void CompassAnalyses::DiscardAssignment::Traversal:: visit(SgNode* node) { if (isSgAssignOp(node)) { // simple case: the parent of a "real" assignment op must be an // expression statement if (!isSgExprStatement(node->get_parent())) { output->addOutput(new CheckerOutput(node)); } else { // not so simple case: the parent is an expression statement, but if // that statement is an if/loop condition, we still want to complain SgNode *assignment = node->get_parent(); SgNode *p = assignment->get_parent(); SgDoWhileStmt *dws; SgForStatement *fs; SgIfStmt *is; SgSwitchStatement *ss; SgWhileStmt *ws; if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } } } else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node)) { // not so simple case: call to operator= member function that is not an // expression statement by itself SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent()); if (call && !isSgExprStatement(call->get_parent()) && mf->get_parent() == call->get_function() && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0) { output->addOutput(new CheckerOutput(call)); } } } //End of the visit function.
InheritedAttribute BugSeeding::evaluateInheritedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute ) { // Use this if we only want to seed bugs in loops bool isLoop = inheritedAttribute.isLoop || (isSgForStatement(astNode) != NULL) || (isSgWhileStmt(astNode) != NULL) || (isSgDoWhileStmt(astNode) != NULL); // Add Fortran support isLoop = isLoop || (isSgFortranDo(astNode) != NULL); // Mark future noes in this subtree as being part of a loop inheritedAttribute.isLoop = isLoop; // To test this on simple codes, optionally allow it to be applied everywhere bool applyEveryWhere = true; if (isLoop == true || applyEveryWhere == true) { // The inherited attribute is true iff we are inside a loop and this is a SgPntrArrRefExp. SgPntrArrRefExp *arrayReference = isSgPntrArrRefExp(astNode); if (arrayReference != NULL) { // Mark as a vulnerability inheritedAttribute.isVulnerability = true; // Now change the array index (to seed the buffer overflow bug) SgVarRefExp* arrayVarRef = isSgVarRefExp(arrayReference->get_lhs_operand()); ROSE_ASSERT(arrayVarRef != NULL); ROSE_ASSERT(arrayVarRef->get_symbol() != NULL); SgInitializedName* arrayName = isSgInitializedName(arrayVarRef->get_symbol()->get_declaration()); ROSE_ASSERT(arrayName != NULL); SgArrayType* arrayType = isSgArrayType(arrayName->get_type()); ROSE_ASSERT(arrayType != NULL); SgExpression* arraySize = arrayType->get_index(); SgTreeCopy copyHelp; // Make a copy of the expression used to hold the array size in the array declaration. SgExpression* arraySizeCopy = isSgExpression(arraySize->copy(copyHelp)); ROSE_ASSERT(arraySizeCopy != NULL); // This is the existing index expression SgExpression* indexExpression = arrayReference->get_rhs_operand(); ROSE_ASSERT(indexExpression != NULL); // Build a new expression: "array[n]" --> "array[n+arraySizeCopy]", where the arraySizeCopy is a size of "array" SgExpression* newIndexExpression = buildAddOp(indexExpression,arraySizeCopy); // Substitute the new expression for the old expression arrayReference->set_rhs_operand(newIndexExpression); } } return inheritedAttribute; }
void CompassAnalyses::ExplicitTestForNonBooleanValue::Traversal:: visit(SgNode* node) { // Implement your traversal here. // 1. conditional expression if(NULL != isSgBasicBlock(node)) { Rose_STL_Container<SgNode*> conditionalExpList = NodeQuery::querySubTree(node, V_SgConditionalExp); for(Rose_STL_Container<SgNode*>::iterator i=conditionalExpList.begin(); i != conditionalExpList.end(); i++) { SgConditionalExp* conditionalExp = isSgConditionalExp(*i); //ROSE_ASSERT(conditionalExp != NULL); if(NULL != conditionalExp && NULL != isSgCastExp(conditionalExp->get_conditional_exp())) { output->addOutput(new CheckerOutput(conditionalExp)); } } } else { SgExprStatement* exprStatement = NULL; // 2. test statement in a if statement SgIfStmt* ifStmt = isSgIfStmt(node); if(NULL != ifStmt) exprStatement = isSgExprStatement(ifStmt->get_conditional()); // 3. test statement in a while statement SgWhileStmt* whileStmt = isSgWhileStmt(node); if(NULL != whileStmt) exprStatement = isSgExprStatement(whileStmt->get_condition()); // 4. test statement in a do-while statement SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node); if(NULL != doWhileStmt) exprStatement = isSgExprStatement(doWhileStmt->get_condition()); // 5. test statement in a for statement SgForStatement* forStatement = isSgForStatement(node); if(NULL != forStatement) exprStatement = isSgExprStatement(forStatement->get_test()); if(NULL != exprStatement && NULL != isSgCastExp(exprStatement->get_expression())) { output->addOutput(new CheckerOutput(node)); } } } //End of the visit function.
void CompassAnalyses::FloatingPointExactComparison::Traversal:: visit(SgNode* node) { // Implement your traversal here. SgExprStatement* exprStatement = NULL; SgIfStmt* ifStmt = isSgIfStmt(node); if(NULL != ifStmt) exprStatement = isSgExprStatement(ifStmt->get_conditional()); SgWhileStmt* whileStmt = isSgWhileStmt(node); if(NULL != whileStmt) exprStatement = isSgExprStatement(whileStmt->get_condition()); SgDoWhileStmt* doWhileStmt = isSgDoWhileStmt(node); if(NULL != doWhileStmt) exprStatement = isSgExprStatement(doWhileStmt->get_condition()); SgForStatement* forStatement = isSgForStatement(node); if(NULL != forStatement) exprStatement = isSgExprStatement(forStatement->get_test()); if(NULL != exprStatement && NULL != isSgNotEqualOp(exprStatement->get_expression())) { SgNotEqualOp* comparison = isSgNotEqualOp(exprStatement->get_expression()); if((comparison->get_lhs_operand_i() != NULL && isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) || (comparison->get_rhs_operand_i() != NULL && isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL)) { output->addOutput(new CheckerOutput(comparison)); } } if(NULL != exprStatement && NULL != isSgEqualityOp(exprStatement->get_expression())) { SgEqualityOp* comparison = isSgEqualityOp(exprStatement->get_expression()); if((comparison->get_lhs_operand_i() != NULL && isSgDoubleVal(comparison->get_lhs_operand_i()) != NULL) || (comparison->get_rhs_operand_i() != NULL && isSgDoubleVal(comparison->get_rhs_operand_i()) != NULL)) { output->addOutput(new CheckerOutput(comparison)); } } } //End of the visit function.
void SgWhileStmt::fixupCopy_symbols(SgNode* copy, SgCopyHelp & help) const { #if DEBUG_FIXUP_COPY printf ("Inside of SgWhileStmt::fixupCopy_symbols() this = %p = %s copy = %p \n",this,this->class_name().c_str(),copy); #endif SgScopeStatement::fixupCopy_symbols(copy,help); SgWhileStmt* whileStatement_copy = isSgWhileStmt(copy); ROSE_ASSERT(whileStatement_copy != NULL); ROSE_ASSERT(this->get_condition() != NULL); this->get_condition()->fixupCopy_symbols(whileStatement_copy->get_condition(),help); ROSE_ASSERT(this->get_body() != NULL); this->get_body()->fixupCopy_symbols(whileStatement_copy->get_body(),help); }
EdgeConditionKind CFGEdge::condition() const { #if 0 SgAsmNode* srcNode = src.getNode(); unsigned int srcIndex = src.getIndex(); SgAsmNode* tgtNode = tgt.getNode(); unsigned int tgtIndex = tgt.getIndex(); if (isSgAsmMov(srcNode) ) { SgAsmMov* ifs = isSgAsmMov(srcNode); #if 0 if (ifs->get_true_body() == tgtNode) { return eckTrue; } else if (ifs->get_false_body() == tgtNode) { return eckFalse; } else ROSE_ASSERT (!"Bad successor in if statement"); #endif } #if 0 else if (isSgWhileStmt(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // False case for while test return eckFalse; } else { return eckTrue; } } else if (isSgDoWhileStmt(srcNode) && srcIndex == 2) { // tgtIndex values are 0 for true branch and 3 for false branch if (tgtIndex == 0) { return eckTrue; } else { return eckFalse; } } else if (isSgForStatement(srcNode) && srcIndex == 2) { if (srcNode == tgtNode) { // False case for test return eckFalse; } else { return eckTrue; } } else if (isSgSwitchStatement(srcNode) && isSgCaseOptionStmt(tgtNode)) { return eckCaseLabel; } else if (isSgSwitchStatement(srcNode) && isSgDefaultOptionStmt(tgtNode)){ return eckDefault; } else if (isSgConditionalExp(srcNode) && srcIndex == 1) { SgConditionalExp* ce = isSgConditionalExp(srcNode); if (ce->get_true_exp() == tgtNode) { return eckTrue; } else if (ce->get_false_exp() == tgtNode) { return eckFalse; } else ROSE_ASSERT (!"Bad successor in conditional expression"); } else if (isSgAndOp(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // Short-circuited false case return eckFalse; } else { return eckTrue; } } else if (isSgOrOp(srcNode) && srcIndex == 1) { if (srcNode == tgtNode) { // Short-circuited true case return eckTrue; } else { return eckFalse; } } #endif else { // No key return eckUnconditional; } #else // DQ (11/28/2009): This function was already commented out, but must return a value for use in MSVC. return eckFalse; #endif }
/** Visits AST nodes in pre-order */ FunctionCallInheritedAttribute FunctionEvaluationOrderTraversal::evaluateInheritedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute) { FunctionCallInheritedAttribute result = parentAttribute; SgForStatement* parentForLoop = isSgForStatement(parentAttribute.currentScope); SgWhileStmt* parentWhileLoop = isSgWhileStmt(parentAttribute.currentScope); SgDoWhileStmt* parentDoWhileLoop = isSgDoWhileStmt(parentAttribute.currentScope); SgConditionalExp* parentSgConditionalExp = astNode->get_parent() ? isSgConditionalExp(astNode->get_parent()) : NULL; SgAndOp* parentAndOp = astNode->get_parent() ?isSgAndOp(astNode->get_parent()) : NULL; SgOrOp* parentOrOp = astNode->get_parent() ? isSgOrOp(astNode->get_parent()) : NULL; if (isSgForStatement(astNode)) result.currentScope = isSgForStatement(astNode); else if (isSgWhileStmt(astNode)) result.currentScope = isSgWhileStmt(astNode); else if (isSgDoWhileStmt(astNode)) result.currentScope = isSgDoWhileStmt(astNode); //else if (isSgConditionalExp(astNode)) // result.currentScope = isSgConditionalExp(astNode); //else if (isSgAndOp(astNode)) // result.currentScope = isSgAndOp(astNode); //else if (isSgOrOp(astNode)) // result.currentScope = isSgOrOp(astNode); else if (isSgForInitStatement(astNode)) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INIT; ROSE_ASSERT(isSgForStatement(result.currentScope)); } else if (parentForLoop != NULL && parentForLoop->get_test() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_TEST; } else if (parentForLoop != NULL && parentForLoop->get_increment() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT; } else if (parentWhileLoop != NULL && parentWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION; } else if (parentDoWhileLoop != NULL && parentDoWhileLoop->get_condition() == astNode) { ROSE_ASSERT(result.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE); result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION; } else if( parentSgConditionalExp != NULL && parentSgConditionalExp->get_true_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM; } else if(parentSgConditionalExp != NULL && parentSgConditionalExp->get_false_exp() == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM; } else if( parentOrOp != NULL && parentOrOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } else if( parentAndOp != NULL && parentAndOp->get_rhs_operand () == astNode) { // if the scope status was safe, turn it into unsafe if (IsStatusSafe(result.scopeStatus)) result.scopeStatus = FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS; } //We can't insert variables before an expression statement that appears inside if(), switch, throw, etc. if (isSgExprStatement(astNode) && !isSgBasicBlock(astNode->get_parent())) { //We can't insert a variable declaration at these locations. Use the parent statement } else if (isSgStatement(astNode)) { result.lastStatement = isSgStatement(astNode); } return result; }
int main(int argc,char** argv) { SgProject* proj = frontend(argc,argv); fixAllPrefixPostfix(proj); initializeScopeInformation(proj); SgFunctionDeclaration* mainDecl = SageInterface::findMain(proj); SgFunctionDefinition* mainDef = mainDecl->get_definition(); //SageInterface::rebuildSymbolTable(mainDef); StaticCFG::CFG cfg(mainDef); SgIncidenceDirectedGraph *g = cfg.getGraph(); PathCollector* pathCollector = new PathCollector(g,&cfg); std::vector<SgNode*> scopeNodes = NodeQuery::querySubTree(mainDef,V_SgScopeStatement); std::vector<SgGraphNode*> visited; std::vector<SgNode*> nodes = NodeQuery::querySubTree(mainDef,V_SgWhileStmt); std::vector<SgNode*>::iterator node = nodes.begin(); for (; node != nodes.end(); node++) { SgScopeStatement* scopeOfWhile = SageInterface::getEnclosingScope(*node); SgStatementPtrList statementsInScope = scopeOfWhile->getStatementList(); SgStatementPtrList::iterator statPtr = statementsInScope.begin(); std::set<SgPragmaDeclaration*> prdecls; for (; statPtr!=statementsInScope.end();statPtr++) { if (isSgPragmaDeclaration(*statPtr)) { prdecls.insert(isSgPragmaDeclaration(*statPtr)); } } //SgExprStatement* boundingConditionStatement = isSgExprStatement(isSgWhileStmt(*node)->get_condition()); //SgExpression* boundingCondition = boundingConditionStatement->get_expression(); SgStatement* body = (isSgWhileStmt(*node)->get_body()); std::vector<std::vector<SgGraphNode*> > paths = pathCollector->getPaths(); std::cout << getPrelude() << std::endl; SgGraphNode* whileStart = cfg.cfgForBeginning(isSgWhileStmt(*node)); SgGraphNode* whileEnd = cfg.cfgForEnd(isSgWhileStmt(*node)); collectPaths(whileStart,whileEnd, pathCollector); SgGraphNode* whileOut = getWhileEndNode(isSgWhileStmt(*node),pathCollector); SgGraphNode* bodyStart = cfg.cfgForBeginning(isSgWhileStmt(*node)->get_body()); SgGraphNode* bodyEnd = cfg.cfgForEnd(isSgWhileStmt(*node)->get_body()); pathCollector->clearPaths(); collectPaths(bodyStart,whileOut,pathCollector); paths.clear(); paths = pathCollector->getPaths(); std::vector<std::vector<SgGraphNode*> >::iterator i = paths.begin(); std::set<SgVariableSymbol*> vars = getVars(pathCollector); std::string vardecls; std::string initrule; std::vector<std::string> rules= getRules(*node,pathCollector, vars, vardecls,initrule); std::cout << vardecls << std::endl; for (int i = 0; i < rules.size(); i++) { std::cout << rules[i] << std::endl; } std::set<SgPragmaDeclaration*>::iterator pr = prdecls.begin(); for (; pr != prdecls.end(); pr++) { std::set<std::string> variables; std::vector<std::string> s_expressions; std::string prag_str = get_pragma_string(*pr); bool initPrag; /*std::string rhs =*/ translateToS_Expr(prag_str,variables,s_expressions,initPrag); if (s_expressions.size() > 0) { std::string queryResult; if (initPrag) { queryResult = assumptionPragma(s_expressions,initrule); } else { queryResult = queryPragma(s_expressions,initrule); } std::cout << queryResult << std::endl; } } } backend(proj); return 0; }