void CompassAnalyses::SizeOfPointer::Traversal:: visit(SgNode* node) { int starCount; SgSizeOfOp *szOf = isSgSizeOfOp(node); if(!szOf) return; Rose_STL_Container<SgNode*> pointers = NodeQuery::querySubTree(node,V_SgPointerType); Rose_STL_Container<SgNode*> deRefs = NodeQuery::querySubTree(node,V_SgPointerDerefExp); Rose_STL_Container<SgNode*> varRefs = NodeQuery::querySubTree(node,V_SgVarRefExp); for (Rose_STL_Container<SgNode *>::iterator i = varRefs.begin(); i != varRefs.end(); i++) { SgVarRefExp *vRef = isSgVarRefExp((*i)); if (!vRef) return; SgType *t = vRef->get_type(); std::string typeName = t->unparseToString(); //std::cout << countStars(typeName) << std::endl; starCount = countStars(typeName); if (!starCount or (starCount == pointers.size() and deRefs.size() == (starCount - 1))) { //std::cout << "IT'S OK!" << std::endl; return; } } output->addOutput(new CheckerOutput(node)); } //End of the visit function.
static void run(Compass::Parameters parameters, Compass::OutputObject* output) { // We only care about source code in the user's space, not, // for example, Boost or system files. string target_directory = parameters["general::target_directory"].front(); CompassAnalyses::ByteByByteStructureComparison::source_directory.assign(target_directory); // Use the pre-built ROSE AST SgProject* sageProject = Compass::projectPrerequisite.getProject(); // perform AST matching here AstMatching match_functions; MatchResult result_functions = match_functions.performMatching("$r = SgFunctionCallExp(SgFunctionRefExp,SgExprListExp(_,_,_))", sageProject); BOOST_FOREACH(SingleMatchVarBindings match, result_functions) { SgFunctionCallExp* function_call = (SgFunctionCallExp*)match["$r"]; AstMatching match_vars; MatchResult result_vars; if ("memcmp" == function_call->getAssociatedFunctionDeclaration()->get_name().getString()) result_vars = match_vars.performMatching("$s = SgVarRefExp", function_call); else continue; bool struct_used = false; BOOST_FOREACH(SingleMatchVarBindings var_match, result_vars) { SgVarRefExp* var = (SgVarRefExp*)var_match["$s"]; if (isSgClassType(var->get_type()->findBaseType()) != NULL) struct_used = true; }
CPPOxfordOpConstDefinition::CPPOxfordOpConstDefinition ( SgExprListExp * parameters) { using namespace SageBuilder; using boost::iequals; using boost::lexical_cast; using std::string; SgExpressionPtrList & parameterExpressions = parameters->get_expressions (); dimension = isSgIntVal (parameterExpressions[indexDimension])->get_value (); SgAddressOfOp * addressOfOperator = isSgAddressOfOp ( parameterExpressions[indexData]); if (addressOfOperator != NULL) { SgVarRefExp * operandExpression = isSgVarRefExp ( addressOfOperator->get_operand ()); ROSE_ASSERT (operandExpression != NULL); variableName = operandExpression->get_symbol ()->get_name ().getString (); baseType = operandExpression->get_type (); } else { SgVarRefExp * varRefExpression = isSgVarRefExp ( parameters->get_expressions ()[indexData]); ROSE_ASSERT (varRefExpression != NULL); variableName = varRefExpression->get_symbol ()->get_name ().getString (); baseType = varRefExpression->get_type (); } ROSE_ASSERT (baseType != NULL); ROSE_ASSERT (dimension > 0); ROSE_ASSERT (variableName.empty () == false); Debug::getInstance ()->debugMessage ("Found an OP_CONST declaration: '" + variableName + "' Its dimension is " + lexical_cast <string> (dimension), Debug::FUNCTION_LEVEL, __FILE__, __LINE__); }
FortranOpDatDefinition::FortranOpDatDefinition (SgExprListExp * parameters) { using boost::lexical_cast; using std::string; /* * ====================================================== * Get name of OP_SET * ====================================================== */ SgVarRefExp * opSetVariableReference; if (isSgDotExp (parameters->get_expressions ()[index_OpSetName]) != NULL) { opSetVariableReference = isSgVarRefExp (isSgDotExp ( parameters->get_expressions ()[index_OpSetName])->get_rhs_operand ()); } else { opSetVariableReference = isSgVarRefExp ( parameters->get_expressions ()[index_OpSetName]); } opSetName = opSetVariableReference->get_symbol ()->get_name ().getString (); /* * ====================================================== * Get dimension of OP_DAT * ====================================================== */ dimension = isSgIntVal (parameters->get_expressions ()[index_dimension])->get_value (); /* * ====================================================== * Get type of OP_DAT from the actual data declaration * it wraps * ====================================================== */ SgVarRefExp * actualDataVariableReference; if (isSgDotExp (parameters->get_expressions ()[index_data]) != NULL) { actualDataVariableReference = isSgVarRefExp (isSgDotExp ( parameters->get_expressions ()[index_data])->get_rhs_operand ()); } else { actualDataVariableReference = isSgVarRefExp ( parameters->get_expressions ()[index_data]); } baseType = actualDataVariableReference->get_type (); /* * ====================================================== * Get name of OP_DAT * ====================================================== */ SgVarRefExp * opDatVariableReference; if (isSgDotExp (parameters->get_expressions ()[index_OpDatName]) != NULL) { opDatVariableReference = isSgVarRefExp (isSgDotExp ( parameters->get_expressions ()[index_OpDatName])->get_rhs_operand ()); } else { opDatVariableReference = isSgVarRefExp ( parameters->get_expressions ()[index_OpDatName]); } variableName = opDatVariableReference->get_symbol ()->get_name ().getString (); ROSE_ASSERT (opSetName.empty () == false); ROSE_ASSERT (dimension > 0); ROSE_ASSERT (baseType != NULL); ROSE_ASSERT (variableName.empty () == false); Debug::getInstance ()->debugMessage ("Found an OP_DAT definition: '" + variableName + "'. The data pertains to the set '" + opSetName + "'. Its actual type is " + baseType->class_name () + " and its dimension is " + lexical_cast <string> (dimension), Debug::FUNCTION_LEVEL, __FILE__, __LINE__); }
std::string writeSgBinaryOpZ3(SgBinaryOp* op, SgExpression* lhs, SgExpression* rhs) { std::stringstream ss; std::string opStr; bool compAssign = false; if (isSgCompoundAssignOp(op)) { compAssign = true; opStr = getSgCompoundAssignOp(isSgCompoundAssignOp(op)); } else { opStr = getSgBinaryOp(op); } ROSE_ASSERT(opStr != "unknown"); std::string rhsstring; std::string lhsstring; lhsstring = getSgExpressionString(lhs); SgType* lhstyp; SgType* rhstyp; if (isSgArrayType(lhs->get_type())) { lhstyp = isSgArrayType(lhs->get_type())->get_base_type(); } else { lhstyp = lhs->get_type(); } if (isSgArrayType(rhs->get_type())) { rhstyp = isSgArrayType(rhs->get_type())->get_base_type(); } else { rhstyp = rhs->get_type(); } if (isSgEnumType(lhs->get_type())) { } else { ROSE_ASSERT(lhstyp == rhstyp); } if (isSgValueExp(rhs)) { rhsstring = getSgValueExp(isSgValueExp(rhs)); } else if (isSgUnaryOp(rhs)) { rhsstring = getSgUnaryOp(isSgUnaryOp(rhs)); } else { rhsstring = getSgExpressionString(rhs); } if (opStr == "/" && lhstyp->isIntegerType()) { opStr = "cdiv"; } if (opStr == "assign" || compAssign) { if (isSgVarRefExp(lhs)) { SgVarRefExp* lhsSgVarRefExp = isSgVarRefExp(lhs); int instances = SymbolToInstances[lhsSgVarRefExp->get_symbol()]; std::stringstream instanceName; SymbolToInstances[lhsSgVarRefExp->get_symbol()] = instances + 1; std::string lhsname = SymbolToZ3[lhsSgVarRefExp->get_symbol()]; instanceName << lhsname << "_" << (instances+1); SgType* varType = lhsSgVarRefExp->get_type(); std::string typeZ3; if (varType->isFloatType()) { typeZ3 = "Real"; } else if (varType->isIntegerType()) { typeZ3 = "Int"; } else if (isSgEnumType(varType)) { typeZ3 = isSgEnumType(varType)->get_name().getString(); } else { typeZ3 = "Unknown"; } ss << "(declare-fun " << instanceName.str() << " () " << typeZ3 << ")\n"; if (!compAssign) { ss << "(assert (= " << instanceName.str() << " " << rhsstring << "))"; } else { std::stringstream oldInstanceName; oldInstanceName << lhsname << "_" << instances; ss << "(assert (= " << instanceName.str() << " (" << opStr << " " << oldInstanceName.str() << " " << rhsstring << ")))"; } } else { ROSE_ASSERT(isSgPntrArrRefExp(lhs)); std::string u_type; SgPntrArrRefExp* lhspntr = isSgPntrArrRefExp(lhs); SgVarRefExp* varlhspntr = isSgVarRefExp(lhspntr->get_lhs_operand()); SgArrayType* arrTy = isSgArrayType(varlhspntr->get_type()); if (arrTy->get_base_type()->isIntegerType()) { u_type = "Int"; } else if (arrTy->get_base_type()->isFloatType()) { u_type = "Real"; } else { std::cout << "unknown base type for array" << std::endl; ROSE_ASSERT(false); } std::stringstream oldInstanceName; SgVarRefExp* varexp = isSgVarRefExp((isSgPntrArrRefExp(lhs))->get_lhs_operand()); oldInstanceName << SymbolToZ3[varexp->get_symbol()] << "_" << SymbolToInstances[varexp->get_symbol()]; int instances = SymbolToInstances[varexp->get_symbol()]; std::stringstream instanceName; SymbolToInstances[varexp->get_symbol()] = instances + 1; std::string lhsname = SymbolToZ3[varexp->get_symbol()]; instanceName << lhsname << "_" << instances+1; ss << "(declare-const " << instanceName.str() << " (Array Int " << u_type << "))\n "; std::string indexstring = getSgExpressionString(isSgPntrArrRefExp(lhs)->get_rhs_operand()); ss << "(assert (= (store " << oldInstanceName.str() << " " << indexstring << " " << rhsstring << ") " << instanceName.str() << "))"; } } else if (opStr == "neq") { ss << "(not (= " << lhsstring << " " << rhsstring << "))"; } else if (opStr == "or" || opStr == "and") { std::stringstream val_stream; if (pathNodeTruthValue.find(op) != pathNodeTruthValue.end()) { bool logic_val = pathNodeTruthValue[op]; //std::cout << ";and/or lhsstring " << lhsstring << "\n"; //std::cout << ";and/or rhsstring " << rhsstring << "\n"; if (opStr == "and") { if (logic_val) { std::string p_decl = "(assert (= " + lhsstring + " true))"; declarations.push_back(p_decl); ss << rhsstring; //ss << "(and " << lhsstring << " " << rhsstring << ")"; } else { std::string p_decl = "(assert (= " + lhsstring + " false))"; declarations.push_back(p_decl); ss << "false"; } } else { if (logic_val) { std::string p_decl = "(assert (= " + lhsstring + " true))"; declarations.push_back(p_decl); ss << "true"; } else { std::string p_decl = "(assert (= " + lhsstring + " false))"; declarations.push_back(p_decl); ss << rhsstring; } } } else { ss << ""; } } else { ss << "(" << opStr << " " << lhsstring << " " << rhsstring << ")"; } return ss.str(); }
int main( int argc, char* argv[] ) { // Initialize and check compatibility. See rose::initialize ROSE_INITIALIZE; SgProject* project = frontend(argc,argv); AstTests::runAllTests(project); #if 0 // Output the graph so that we can see the whole AST graph, for debugging. generateAstGraph(project, 4000); #endif #if 1 printf ("Generate the dot output of the SAGE III AST \n"); generateDOT ( *project ); printf ("DONE: Generate the dot output of the SAGE III AST \n"); #endif // There are lots of way to write this, this is one simple approach; get all the function calls. std::vector<SgNode*> functionCalls = NodeQuery::querySubTree (project,V_SgFunctionCallExp); // Find the SgFunctionSymbol for snprintf so that we can reset references to "sprintf" to "snprintf" instead. // SgGlobal* globalScope = (*project)[0]->get_globalScope(); SgSourceFile* sourceFile = isSgSourceFile(project->get_fileList()[0]); ROSE_ASSERT(sourceFile != NULL); SgGlobal* globalScope = sourceFile->get_globalScope(); SgFunctionSymbol* snprintf_functionSymbol = globalScope->lookup_function_symbol("snprintf"); ROSE_ASSERT(snprintf_functionSymbol != NULL); // Iterate over the function calls to find the calls to "sprintf" for (unsigned long i = 0; i < functionCalls.size(); i++) { SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(functionCalls[i]); ROSE_ASSERT(functionCallExp != NULL); SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function()); if (functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); if (functionSymbol != NULL) { SgName functionName = functionSymbol->get_name(); // printf ("Function being called: %s \n",functionName.str()); if (functionName == "sprintf") { // Now we have something to do! functionRefExp->set_symbol(snprintf_functionSymbol); // Now add the "n" argument SgExprListExp* functionArguments = functionCallExp->get_args(); SgExpressionPtrList & functionArgumentList = functionArguments->get_expressions(); // "sprintf" shuld have exactly 2 arguments (I guess the "..." don't count) printf ("functionArgumentList.size() = %zu \n",functionArgumentList.size()); // ROSE_ASSERT(functionArgumentList.size() == 2); SgExpressionPtrList::iterator i = functionArgumentList.begin(); // printf ("(*i) = %p = %s = %s \n",*i,(*i)->class_name().c_str(),SageInterface::get_name(*i).c_str()); SgVarRefExp* variableRefExp = isSgVarRefExp(*i); ROSE_ASSERT(variableRefExp != NULL); // printf ("variableRefExp->get_type() = %p = %s = %s \n",variableRefExp->get_type(),variableRefExp->get_type()->class_name().c_str(),SageInterface::get_name(variableRefExp->get_type()).c_str()); SgType* bufferType = variableRefExp->get_type(); SgExpression* bufferLengthExpression = NULL; switch(bufferType->variantT()) { case V_SgArrayType: { SgArrayType* arrayType = isSgArrayType(bufferType); bufferLengthExpression = arrayType->get_index(); break; } case V_SgPointerType: { // SgPointerType* pointerType = isSgPointerType(bufferType); SgInitializedName* variableDeclaration = variableRefExp->get_symbol()->get_declaration(); ROSE_ASSERT(variableDeclaration != NULL); SgExpression* initializer = variableDeclaration->get_initializer(); if (initializer != NULL) { SgAssignInitializer* assignmentInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignmentInitializer != NULL); // This is the rhs of the initialization of the pointer (likely a malloc through a cast). // This assumes: buffer = (char*) malloc(bufferLengthExpression); SgExpression* initializationExpression = assignmentInitializer->get_operand(); ROSE_ASSERT(initializationExpression != NULL); SgCastExp* castExp = isSgCastExp(initializationExpression); ROSE_ASSERT(castExp != NULL); SgFunctionCallExp* functionCall = isSgFunctionCallExp(castExp->get_operand()); ROSE_ASSERT(functionCall != NULL); SgExprListExp* functionArguments = isSgExprListExp(functionCall->get_args()); bufferLengthExpression = functionArguments->get_expressions()[0]; ROSE_ASSERT(bufferLengthExpression != NULL); } else { printf ("Initializer not found, so no value for n in snprintf can be computed currently \n"); } break; } default: { printf ("Error: default reached in evaluation of buffer type = %p = %s \n",bufferType,bufferType->class_name().c_str()); ROSE_ASSERT(false); } } ROSE_ASSERT(bufferLengthExpression != NULL); // printf ("bufferLengthExpression = %p = %s = %s \n",bufferLengthExpression,bufferLengthExpression->class_name().c_str(),SageInterface::get_name(bufferLengthExpression).c_str()); // Jump over the first argument, the "n" is defined to be the 2nd argument (the rest are shifted one position). i++; // Build a deep copy of the expression used to define the static buffer (could be any complex expression). SgTreeCopy copy_help; SgExpression* bufferLengthExpression_copy = isSgExpression(bufferLengthExpression->copy(copy_help)); // Insert the "n" for the parameter list to work with "snprintf" instead of "sprintf" functionArgumentList.insert(i,bufferLengthExpression_copy); } } } } return backend(project); }