void replaceExps(SgExpression* exp, SgVariableDeclaration* vardecl) { if (isSgVarRefExp(exp)) { return; } else if (isSgUnaryOp(exp)) { if (isSgMinusMinusOp(exp) || isSgPlusPlusOp(exp)) { SgExpression* operand = (isSgUnaryOp(exp))->get_operand(); SgExpression* operand_cpy = SageInterface::copyExpression(operand); std::cout << "operand: " << operand->class_name() << std::endl; SageInterface::replaceExpression(exp,operand_cpy); } return; } else if (isSgBinaryOp(exp)) { replaceExps(isSgBinaryOp(exp)->get_lhs_operand(), vardecl); replaceExps(isSgBinaryOp(exp)->get_rhs_operand(), vardecl); return; } else { return; } return; }
void simplifyExps(SgExpression* exp) { if (isSgVarRefExp(exp)) { return; } else if (isSgBinaryOp(exp)) { SageInterface::splitExpressionIntoBasicBlock(exp); simplifyExps(isSgBinaryOp(exp)->get_lhs_operand()); simplifyExps(isSgBinaryOp(exp)->get_rhs_operand()); return; } else { return; } return; }
void CompassAnalyses::NonAssociativeRelationalOperators::Traversal:: visit(SgNode* node) { SgBinaryOp *relOperator = isSgBinaryOp(node); if( relOperator != NULL && isRelationalOperator(relOperator) ) { SgExpression *lhs = relOperator->get_lhs_operand(); SgExpression *rhs = relOperator->get_rhs_operand(); if( lhs != NULL && rhs != NULL ) { CompassAnalyses::NonAssociativeRelationalOperators::ExpressionTraversal expressionTraversal; if( expressionTraversal.run(lhs->get_parent()) > 1 ) { output->addOutput( new CheckerOutput(relOperator) ); } //if( expressionTraversal.run(lhs->get_parent()) > 1 ) } //if( lhs != NULL && rhs != NULL ) } //if( relOperator != NULL && isRelationalOperator(node) ) return; } //End of the visit function.
void getExps(SgExpression* exp, SgInitializedName* prevPost, std::vector<SgExpression*>& result, int tabcount) { if (isSgVarRefExp(exp)) { return; } else if (isSgUnaryOp(exp)) { if (isSgMinusMinusOp(exp) || isSgPlusPlusOp(exp)) { SgExpression* operand = (isSgUnaryOp(exp))->get_operand(); bool prefix = (isSgUnaryOp(exp)->get_mode() == SgUnaryOp::prefix); if (prefix) { SgExpression* exp_cpy = SageInterface::copyExpression(exp); prefixes.push_back(exp_cpy); } else { SgExpression* exp_cpy = SageInterface::copyExpression(exp); postfixes.push_back(exp_cpy); } } return; } else if (isSgBinaryOp(exp)) { result.push_back(exp); getExps(isSgBinaryOp(exp)->get_lhs_operand(), prevPost, result,tabcount+1); getExps(isSgBinaryOp(exp)->get_rhs_operand(), prevPost, result,tabcount+1); return; } else { result.push_back(exp); return; } return; }
/** * Matches assignment statements (including pointer association) */ void FortranAnalysis::visit(SgExprStatement * expr_stmt) { if (matchRegionAssignment(expr_stmt)) { SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression()); SgVarRefExp * var = isSgVarRefExp(bin_op->get_lhs_operand()); if (var == NULL) return; var->get_symbol()->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR")); printf("FortranAnalysis:: adding halo attr to %s\n", var->get_symbol()->get_name().getString().c_str()); } else if (HaloRefSearch::findHaloRef(expr_stmt)) { expr_stmt->setAttribute("halo_ref", new AstTextAttribute("HAS_HALO_REF")); printf("FortranAnalysis:: adding halo attr to statement\n"); } }
ParseTree * ParseTree::extractParseTree( SgExpression * exp, const PolyhedricAnnotation::FunctionPolyhedralProgram & function_program, PolyGraph * polygraph, std::string isl_domain, unsigned stmt_id ) { SgBinaryOp * bin_op = isSgBinaryOp(exp); SgUnaryOp * una_op = isSgUnaryOp(exp); SgConditionalExp * cond_exp = isSgConditionalExp(exp); SgFunctionCallExp * func_call = isSgFunctionCallExp(exp); ParseTree * c1 = NULL; ParseTree * c2 = NULL; ParseTree * c3 = NULL; unsigned variant = exp->variantT(); if (isSgPntrArrRefExp(exp)) bin_op = NULL; if (bin_op != NULL) { c1 = extractParseTree(bin_op->get_lhs_operand_i(), function_program, polygraph, isl_domain, stmt_id); c2 = extractParseTree(bin_op->get_rhs_operand_i(), function_program, polygraph, isl_domain, stmt_id); } else if (una_op != NULL) { c1 = extractParseTree(una_op->get_operand_i(), function_program, polygraph, isl_domain, stmt_id); } else if (cond_exp != NULL) { c1 = extractParseTree(cond_exp->get_conditional_exp(), function_program, polygraph, isl_domain, stmt_id); c2 = extractParseTree(cond_exp->get_true_exp(), function_program, polygraph, isl_domain, stmt_id); c3 = extractParseTree(cond_exp->get_false_exp(), function_program, polygraph, isl_domain, stmt_id); } else if (func_call != NULL) { std::vector<SgExpression *> args = func_call->get_args()->get_expressions(); ROSE_ASSERT(args.size() == 1); c1 = extractParseTree(args[0], function_program, polygraph, isl_domain, stmt_id); } else { return new Data(polygraph, exp, function_program, isl_domain); } return new Operator(polygraph, variant, c1, c2, c3); }
bool FortranAnalysis::matchRegionAssignment(SgExprStatement * expr_stmt) { SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression()); if (bin_op == NULL) return false; SgFunctionCallExp * fcall = isSgFunctionCallExp(bin_op->get_rhs_operand()); if (fcall == NULL) return false; SgFunctionRefExp * fref = isSgFunctionRefExp(fcall->get_function()); if (fref == NULL) return false; SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin(); std::string name = fref->get_symbol()->get_name().getString(); if (name == "interior" && it != fcall->get_args()->get_expressions().end()) { SgVarRefExp * var = isSgVarRefExp(*it); if (var == NULL) return false; AstTextAttribute * attr = (AstTextAttribute *) var->get_symbol()->getAttribute("dummy_attr"); if (attr == NULL) return false; if (attr->toString() != "DUMMY_ARRAY_ARG") return false; } return true; }
void DataFlow<Annotation, Language, Runtime>::createContextFromLoopTree( const LoopTrees<Annotation> & loop_trees, context_t & context ) const { assert(context.datas.empty()); assert(context.datas_in.empty()); assert(context.datas_out.empty()); assert(context.accesses_map.empty()); typename std::set<Data<Annotation> *>::iterator it_data; const std::vector<Data<Annotation> *> & data_vect = loop_trees.getDatas(); context.datas.insert(data_vect.begin(), data_vect.end()); for (it_data = context.datas.begin(); it_data != context.datas.end(); it_data++) { assert(*it_data != NULL); if ((*it_data)->isFlowIn()) context.datas_in.insert(*it_data); if ((*it_data)->isFlowOut()) context.datas_out.insert(*it_data); } const std::vector<typename LoopTrees<Annotation>::node_t *> & nodes = loop_trees.getNodes(); typename std::vector<typename LoopTrees<Annotation>::node_t *>::const_iterator it_node; for (it_node = nodes.begin(); it_node != nodes.end(); it_node++) { typename LoopTrees<Annotation>::cond_t * cond = dynamic_cast<typename LoopTrees<Annotation>::cond_t *>(*it_node); typename LoopTrees<Annotation>::stmt_t * stmt = dynamic_cast<typename LoopTrees<Annotation>::stmt_t *>(*it_node); if (cond == NULL && stmt == NULL) continue; typename std::map<typename LoopTrees<Annotation>::node_t *, accesses_list_t>::iterator it_access = context.accesses_map.insert(std::pair<typename LoopTrees<Annotation>::node_t *, accesses_list_t>(*it_node, accesses_list_t())).first; std::vector<data_access_t> & read = it_access->second.reads; std::vector<data_access_t> & write = it_access->second.writes; if (cond != NULL) { assert(false); /// \todo } else if (stmt != NULL) { SgExprStatement * expr_stmt = isSgExprStatement(stmt->statement); SgVariableDeclaration * var_decl = isSgVariableDeclaration(stmt->statement); if (expr_stmt != NULL) { SgExpression * exp = expr_stmt->get_expression(); assert(exp != NULL); SgBinaryOp * bin_op = isSgBinaryOp(exp); if (bin_op != NULL) { SgExpression * lhs_exp = bin_op->get_lhs_operand_i(); SgExpression * rhs_exp = bin_op->get_rhs_operand_i(); assert(lhs_exp != NULL && rhs_exp != NULL); SgAssignOp * assign_op = isSgAssignOp(exp); SgCompoundAssignOp * compound_assign_op = isSgCompoundAssignOp(exp); assert((assign_op != NULL) xor (compound_assign_op != NULL)); // FIXME expression statement are not always made of assignement if (assign_op != NULL || compound_assign_op != NULL) { append_access(lhs_exp, write, context); // add access in lhs to write set append_access(rhs_exp, read, context); // add access in rhs to read set } if (compound_assign_op != NULL) { append_access(lhs_exp, read, context); // add access in lhs to read set } } else assert(false); // FIXME expression statement are not always made of binary op } else if (var_decl != NULL) { assert(var_decl->get_variables().size() == 1); SgInitializedName * init_name = isSgInitializedName(var_decl->get_variables()[0]); assert(init_name != NULL); SgInitializer * init = isSgInitializer(init_name->get_initptr()); if (init != NULL) { SgAssignInitializer * assign_init = isSgAssignInitializer(init); if (assign_init != NULL) { SgExpression * exp = assign_init->get_operand_i(); assert(exp != NULL); append_access(exp, read, context); } else assert(false); } } else assert(false); } } }
void CompassAnalyses::VariableNameEqualsDatabaseName::Traversal:: visit(SgNode* node) { if( isSgAssignInitializer(node) != NULL ) assignExp = node; if( isSgAssignOp(node) != NULL ) assignExp = node; SgFunctionCallExp* funcCall = isSgFunctionCallExp(node); // See if we have a dot expression or arrow expression which // accesses the desired member function in the class we are looking for. if ( funcCall != NULL ) { SgExpression* funcExp = funcCall->get_function(); if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) ) { SgBinaryOp* binOp = isSgBinaryOp(funcExp); SgExpression* rhsOp = binOp->get_rhs_operand(); // SgExpression* lhsOp = binOp->get_lhs_operand(); if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp) ) { // std::cout << "c1\n" ; SgMemberFunctionSymbol* funcSymbol = funcRef->get_symbol(); ROSE_ASSERT(funcSymbol->get_declaration() != NULL); // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C) // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL); if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL) { SgMemberFunctionDeclaration* funcDecl = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration()); ROSE_ASSERT( funcDecl != NULL ); SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope()); SgClassDeclaration* clDecl = isSgClassDeclaration(clDef->get_declaration()); // SgClassDeclaration* clDecl = funcDecl->get_associatedClassDeclaration(); ROSE_ASSERT( clDecl != NULL ); std::string className = clDecl->get_name().getString(); ROSE_ASSERT(funcDecl != NULL); std::string functionName = funcDecl->get_name().getString(); // If the class is the class we are looking for see if the member function // access is to the member function we are interested in. // std::cout << "className = " << className << std::endl; // std::cout << "functionName = " << functionName << std::endl; if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) ) { SgExprListExp* actualArgs = funcCall->get_args(); SgExpressionPtrList& actualExpArgs = actualArgs->get_expressions (); ROSE_ASSERT(actualExpArgs.size() == 1); Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal); ROSE_ASSERT( nodeLst.size() > 0); SgStringVal* actualArg = isSgStringVal(*nodeLst.begin()); ROSE_ASSERT(actualArg != NULL); std::string stringArg = actualArg->get_value(); std::cout << "arg:" << stringArg << std::endl; std::string varName; // SgInitializedName* initName = NULL; if ( SgAssignInitializer* assignInit = isSgAssignInitializer(assignExp) ) { SgInitializedName* initName = isSgInitializedName(assignInit->get_parent()); ROSE_ASSERT(initName != NULL); varName = initName->get_name().getString(); } else { if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) ) { SgExpression* lhsOp = assignOp->get_lhs_operand(); SgVarRefExp* varRef = isSgVarRefExp(lhsOp); ROSE_ASSERT(varRef!=NULL); SgVariableSymbol* varSymbol = varRef->get_symbol(); ROSE_ASSERT(varSymbol != NULL); SgInitializedName* initName = varSymbol->get_declaration(); varName = initName->get_name().getString(); } } if (varName != "") { // we are only interested in the part of the argument after the last ":" // Database scopes in ALE3D are separated by ":" size_t posCol = stringArg.find_last_of(':'); if (posCol != std::string::npos) stringArg = stringArg.substr(posCol+1); //Find violations to the rule if ( stringArg != varName) { output->addOutput(new CheckerOutput(assignExp)); std::cout << "violation" << varName << std::endl; } else { std::cout << "non=violation" << varName << std::endl; } } } } } } } } // End of the visit function.
void MarkLhsValues::visit(SgNode* node) { // DQ (1/19/2008): Fixup the get_lvalue() member function which is common on expressions. // printf ("In TestLValueExpressions::visit(): node = %s \n",node->class_name().c_str()); ROSE_ASSERT(node != NULL); #if 0 Sg_File_Info* fileInfo = node->get_file_info(); printf ("In MarkLhsValues::visit(): node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo); if (fileInfo != NULL) { bool isCompilerGenerated = fileInfo->isCompilerGenerated(); std::string filename = fileInfo->get_filenameString(); int line_number = fileInfo->get_line(); int column_number = fileInfo->get_line(); printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str()); } #endif // This function most often sets the SgVarRefExp which appears as an lhs operand in a limited set of binary operators. SgExpression* expression = isSgExpression(node); if (expression != NULL) { #if 0 printf ("MarkLhsValues::visit(): calling expression->get_lvalue() on expression = %p = %s \n",expression,expression->class_name().c_str()); #endif SgBinaryOp* binaryOperator = isSgBinaryOp(expression); if (binaryOperator != NULL) { switch (expression->variantT()) { // IR nodes that have an l-value (required by C/C++/Fortran standard) case V_SgAssignOp: case V_SgAndAssignOp: case V_SgDivAssignOp: case V_SgIorAssignOp: case V_SgLshiftAssignOp: case V_SgMinusAssignOp: case V_SgModAssignOp: case V_SgMultAssignOp: case V_SgPlusAssignOp: case V_SgRshiftAssignOp: case V_SgXorAssignOp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); SgExpression* rhs = binaryOperator->get_rhs_operand(); ROSE_ASSERT(rhs != NULL); // This is violated by the ROSE/tests/nonsmoke/functional/roseTests/astInliningTests/pass16.C test code! // ROSE_ASSERT(lhs->get_lvalue() == true); // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage // sets this properly, but some transformations of the AST do not, so we fix it up here. lhs->set_lvalue(true); rhs->set_lvalue(false); break; } // These cases are less clear so don't explicitly mark it as an l-value! case V_SgDotExp: case V_SgArrowExp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES printf ("L-value test for SgBinaryOp = %s: not clear how to assert value -- lhs->get_lvalue() = %s \n",binaryOperator->class_name().c_str(),lhs->get_lvalue() ? "true" : "false"); #endif // ROSE_ASSERT(lhs->get_lvalue() == true); break; } // DQ (10/9/2008): For the Fortran user defined operator, the lhs is not an L-value. // This represents my understanding, because assignment is explicitly handled separately. case V_SgUserDefinedBinaryOp: { SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); SgExpression* rhs = binaryOperator->get_rhs_operand(); ROSE_ASSERT(rhs != NULL); // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage // sets this properly, but some transformations of the AST do not, so we fix it up here. lhs->set_lvalue(false); rhs->set_lvalue(false); break; } default: { // Make sure that the lhs is not an L-value SgExpression* lhs = binaryOperator->get_lhs_operand(); ROSE_ASSERT(lhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (lhs->get_lvalue() == true) { printf ("Error for lhs = %p = %s = %s in binary expression = %s \n", lhs,lhs->class_name().c_str(),SageInterface::get_name(lhs).c_str(),expression->class_name().c_str()); binaryOperator->get_startOfConstruct()->display("Error for lhs: lhs->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(lhs->get_lvalue() == false); } } //SgExpression* rhs = binaryOperator->get_rhs_operand(); // Liao 3/14/2011. This function is called by builders for binary expressions. // These builders can accept empty right hand operands. // ROSE_ASSERT(rhs != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (rhs != NULL) if (rhs->get_lvalue() == true) { printf ("Error for rhs = %p = %s = %s in binary expression = %s \n", rhs,rhs->class_name().c_str(),SageInterface::get_name(rhs).c_str(),expression->class_name().c_str()); binaryOperator->get_startOfConstruct()->display("Error for rhs: rhs->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(rhs->get_lvalue() == false); } SgUnaryOp* unaryOperator = isSgUnaryOp(expression); if (unaryOperator != NULL) { switch (expression->variantT()) { // IR nodes that should have a valid lvalue // What about SgAddressOfOp? case V_SgAddressOfOp: break; // JJW 1/31/2008 case V_SgMinusMinusOp: case V_SgPlusPlusOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES // if (operand->get_lvalue() == true) if (operand->get_lvalue() == false) { printf ("Error for operand = %p = %s = %s in unary expression (SgMinusMinusOp or SgPlusPlusOp) = %s \n", operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str()); unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(operand->get_lvalue() == false); operand->set_lvalue(true); // ROSE_ASSERT(operand->get_lvalue() == true); break; } case V_SgThrowOp: { #if WARN_ABOUT_ATYPICAL_LVALUES // Note that the gnu " __throw_exception_again;" can cause a SgThrowOp to now have an operand! SgExpression* operand = unaryOperator->get_operand(); if (operand == NULL) { printf ("Warning: operand == NULL in SgUnaryOp = %s (likely caused by __throw_exception_again) \n",expression->class_name().c_str()); // unaryOperator->get_startOfConstruct()->display("Error: operand == NULL in SgUnaryOp: debug"); } #endif // ROSE_ASSERT(operand != NULL); break; } // DQ (10/9/2008): For the Fortran user defined operator, the operand is not an L-value. // This represents my understanding, because assignment is explicitly handled separately. case V_SgUserDefinedUnaryOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); operand->set_lvalue(false); } // Added to address problem on Qing's machine using g++ 4.0.2 case V_SgNotOp: // These are where some error occur. I want to isolate then so that I know the current status of where lvalues are not marked correctly! case V_SgPointerDerefExp: case V_SgCastExp: case V_SgMinusOp: case V_SgBitComplementOp: // case V_SgPlusOp: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES // Most of the time this is false, we only want to know when it is true if (operand->get_lvalue() == true) { printf ("L-value test for SgUnaryOp = %s: not clear how to assert value -- operand->get_lvalue() = %s \n",unaryOperator->class_name().c_str(),operand->get_lvalue() ? "true" : "false"); // unaryOperator->get_startOfConstruct()->display("L-value test for SgUnaryOp: operand->get_lvalue() == true: debug"); } #endif // ROSE_ASSERT(operand->get_lvalue() == false); break; } default: { SgExpression* operand = unaryOperator->get_operand(); ROSE_ASSERT(operand != NULL); #if WARN_ABOUT_ATYPICAL_LVALUES if (operand->get_lvalue() == true) { printf ("Error for operand = %p = %s = %s in unary expression = %s \n", operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str()); unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug"); } #endif // DQ (10/9/2008): What is the date and author for this comment? Is it fixed now? Was it made into a test code? // Note that this fails for line 206 of file: include/g++_HEADERS/hdrs1/ext/mt_allocator.h ROSE_ASSERT(operand->get_lvalue() == false); } } } } }
//! Count floating point operations seen in a subtree void CountFPOperations(SgLocatedNode* input) { Rose_STL_Container<SgNode*> nodeList = NodeQuery::querySubTree(input, V_SgBinaryOp); for (Rose_STL_Container<SgNode *>::iterator i = nodeList.begin(); i != nodeList.end(); i++) { fp_operation_kind_enum op_kind = e_unknown; // bool isFPType = false; // check operation type SgBinaryOp* bop= isSgBinaryOp(*i); switch (bop->variantT()) { case V_SgAddOp: case V_SgPlusAssignOp: op_kind = e_plus; break; case V_SgSubtractOp: case V_SgMinusAssignOp: op_kind = e_minus; break; case V_SgMultiplyOp: case V_SgMultAssignOp: op_kind = e_multiply; break; case V_SgDivideOp: case V_SgDivAssignOp: op_kind = e_divide; break; default: break; } //end switch // skip this expression if unknown operation kind if (op_kind == e_unknown) continue; // Check if the operation is on float point data type if (bop->get_type()->isFloatType()) { // we assume the traverse is inside out, the inner loop will be processed first! // An operation is counted once when its innermost enclosing loop is processed. // Using a map to avoid double counting an operation when it is enclosed in multiple loops if (!FPVisitMAP[bop]) { addFPCount (input, op_kind); FPVisitMAP[bop] = true; } } } // end for //Must update the total counter here FPCounters* fp_counters = getFPCounters (input); fp_counters->updateTotal (); // write results to a report file if (running_mode == e_static_counting) { ofstream reportFile(report_filename.c_str(), ios::app); cout<<"Writing counter results to "<< report_filename <<endl; reportFile<< fp_counters->toString(); } // debugging info if (debug) printFPCount (input); }
// on other nodes lrRecord (lrRecord &parent, SgNode* n) { SgBinaryOp* binOp; SgUnaryOp* unOp; SgFunctionCallExp* funcCall; //SgPntrArrRefExp* arrRef; char typeStr[100]; // if this node is on the read, write or read-write side of an assignment operation, set its access appropriately if(parent.readSubtree == n) access = readAccess; else if(n == parent.writeSubtree) access = writeAccess; else if(n == parent.rwSubtree) access = rwAccess; else access = parent.access; if((binOp = isSgBinaryOp(n))) { // writeSubtree = readSubtree if(isSgAssignOp(binOp)) { writeSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgAssignOp"); } // rwSubtree op= readSubtree else if(isSgCompoundAssignOp(binOp)) { rwSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); writeSubtree = (void*)NULL; strcpy(typeStr, "Sg*AssignOp"); } else if(isSgPntrArrRefExp(binOp)) { // all the references involved in an array reference, whether they are used to compute the array name // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgPntrArrRefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgBinaryNode 0x%x type %s access=%d: %s\n", binOp, typeStr, access, binOp->unparseToString().c_str()); } else if((unOp = isSgUnaryOp(n))) { // unary update operations have only one operand, which is read-write // writeSubtree if(isSgMinusMinusOp(unOp) || isSgPlusPlusOp(unOp)) { writeSubtree = (void*)NULL; readSubtree = (void*)NULL; rwSubtree = unOp->get_operand(); strcpy(typeStr, "Sg**Op"); } // dereference operations have a read-only operand else if(isSgPointerDerefExp(unOp)) { writeSubtree = (void*)NULL; readSubtree = unOp->get_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "isSgPointerDerefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgUnaryNode 0x%x %s access=%d: %s\n", unOp, typeStr, access, unOp->unparseToString().c_str()); } else if((funcCall = isSgFunctionCallExp(n))) { // all the references involved in a function call, whether they are used to compute the function pointer // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; //printf("SgFunctionCall 0x%x access=%d: %s\n", funcCall, access, funcCall->unparseToString().c_str()); } // else, if this is neither a binary, nor unary operation node else { // leave subtree fields of this record as NULL readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; //printf("SgNode 0x%x access=%d: %s\n", n, access, n->unparseToString().c_str()); } }
bool TaintAnalysis::transfer(const Function& func, const DataflowNode& node_, NodeState& state, const std::vector<Lattice*>& dfInfo) { static size_t ncalls = 0; if (debug) { *debug <<"TaintAnalysis::transfer-" <<++ncalls <<"(func=" <<func.get_name() <<",\n" <<" node={" <<StringUtility::makeOneLine(node_.toString()) <<"},\n" <<" state={" <<state.str(this, " ") <<",\n" <<" dfInfo[" <<dfInfo.size() <<"]={...})\n"; } SgNode *node = node_.getNode(); assert(!dfInfo.empty()); FiniteVarsExprsProductLattice *prodLat = dynamic_cast<FiniteVarsExprsProductLattice*>(dfInfo.front()); bool modified = magic_tainted(node, prodLat); // some values are automatically tainted based on their name // Process AST nodes that transfer taintedness. Most of these operations have one or more inputs from which a result // is always calculated the same way. So we just gather up the inputs and do the calculation at the very end of this // function. The other operations are handled individually within their "if" bodies. TaintLattice *result = NULL; // result pointer into the taint lattice std::vector<TaintLattice*> inputs; // input pointers into the taint lattice if (isSgAssignInitializer(node)) { // as in "int a = b" SgAssignInitializer *xop = isSgAssignInitializer(node); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop->get_operand()))); inputs.push_back(in1); } else if (isSgAggregateInitializer(node)) { // as in "int a[1] = {b}" SgAggregateInitializer *xop = isSgAggregateInitializer(node); const SgExpressionPtrList &exprs = xop->get_initializers()->get_expressions(); for (size_t i=0; i<exprs.size(); ++i) { varID in_id = SgExpr2Var(exprs[i]); TaintLattice *in = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in_id)); inputs.push_back(in); } } else if (isSgInitializedName(node)) { SgInitializedName *xop = isSgInitializedName(node); if (xop->get_initializer()) { varID in1_id = SgExpr2Var(xop->get_initializer()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } } else if (isSgValueExp(node)) { // numeric and character constants SgValueExp *xop = isSgValueExp(node); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(SgExpr2Var(xop))); if (result) modified = result->set_vertex(TaintLattice::VERTEX_UNTAINTED); } else if (isSgAddressOfOp(node)) { // as in "&x". The result taintedness has nothing to do with the value in x. /*void*/ } else if (isSgBinaryOp(node)) { // as in "a + b" SgBinaryOp *xop = isSgBinaryOp(node); varID in1_id = SgExpr2Var(isSgExpression(xop->get_lhs_operand())); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); varID in2_id = SgExpr2Var(isSgExpression(xop->get_rhs_operand())); TaintLattice *in2 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in2_id)); inputs.push_back(in2); if (isSgAssignOp(node)) { // copy the rhs lattice to the lhs lattice (as well as the entire '=' expression result) assert(in1 && in2); modified = in1->meetUpdate(in2); } } else if (isSgUnaryOp(node)) { // as in "-a" SgUnaryOp *xop = isSgUnaryOp(node); varID in1_id = SgExpr2Var(xop->get_operand()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } else if (isSgReturnStmt(node)) { // as in "return a". The result will always be dead, so we're just doing this to get some debugging output. Most // of our test inputs are functions, and the test examines the function's returned taintedness. SgReturnStmt *xop = isSgReturnStmt(node); varID in1_id = SgExpr2Var(xop->get_expression()); TaintLattice *in1 = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(in1_id)); inputs.push_back(in1); } // Update the result lattice (unless dead) with the inputs (unless dead) by using the meedUpdate() method. All this // means is that the new result will be the maximum of the old result and all inputs, where "maximum" is defined such // that "tainted" is greater than "untainted" (and both of them are greater than bottom/unknown). for (size_t i=0; i<inputs.size(); ++i) if (debug) *debug <<"TaintAnalysis::transfer: input " <<(i+1) <<" is " <<lattice_info(inputs[i]) <<"\n"; if (!result && varID::isValidVarExp(node)) { varID result_id(node); // NOTE: constructor doesn't handle all SgExpression nodes, thus the next "if" result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (!result && isSgExpression(node)) { varID result_id = SgExpr2Var(isSgExpression(node)); result = dynamic_cast<TaintLattice*>(prodLat->getVarLattice(result_id)); } if (result) { for (size_t i=0; i<inputs.size(); ++i) { if (inputs[i]) modified = result->meetUpdate(inputs[i]) || modified; } } if (debug) *debug <<"TaintAnalysis::transfer: result is " <<lattice_info(result) <<(modified?" (modified)":" (not modified)") <<"\n"; return modified; }
std::string getSgExpressionString(SgExpression* expNode) { //bool returnString = false; std::string expString; bool set_to_expression_val = false; VariantT var = expNode->variantT(); if (isSgBinaryOp(expNode)) { SgBinaryOp* binOp = isSgBinaryOp(expNode); SgExpression* lhs_exp = binOp->get_lhs_operand(); SgExpression* rhs_exp = binOp->get_rhs_operand(); expString = writeSgBinaryOpZ3(binOp, lhs_exp, rhs_exp); if (isSgAssignOp(binOp) || isSgCompoundAssignOp(binOp)) { declarations.push_back(expString); expString = ""; } else if (isSgEqualityOp(binOp) || isSgGreaterThanOp(binOp) || isSgGreaterOrEqualOp(binOp) || isSgLessThanOp(binOp) || isSgLessOrEqualOp(binOp) || isSgNotEqualOp(binOp) || isSgAndOp(binOp) || isSgOrOp(binOp)) { //set_to_expression_val = true; } } else if (isSgUnaryOp(expNode)) { expString = getSgUnaryOp(isSgUnaryOp(expNode)); } else if (isSgValueExp(expNode)) { expString = getSgValueExp(isSgValueExp(expNode)); } else { switch (var) { case V_SgCallExpression: std::cout << "SgCallExpression not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgClassNameRefExp: std::cout << "SgClassNameRefExp not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgConditionalExp: std::cout << "SgConditionalExp (trinary A ? B : C) not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgExprListExp: std::cout << "SgExprListExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgFunctionRefExp: std::cout << "SgFunctionRefExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgDeleteExp: std::cout << "SgDeleteExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgInitializer: std::cout << "SgInitializer is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNaryOp: std::cout << "SgNaryOp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNewExp: std::cout << "SgNewExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgNullExpression: expString = "; null expression"; break; case V_SgRefExp: std::cout << "SgRefExp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgSizeOfOp: std::cout << "SgSizeOfOp is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgStatementExpression: std::cout << "SgStatementExpression is not yet implemented" << std::endl; expString = ""; ROSE_ASSERT(false); break; case V_SgValueExp: std::cout << "V_SgValueExp should never be encountered" << std::endl; ROSE_ASSERT(false); expString = ""; break; case V_SgVarRefExp: expString = getSgVarRefExp(isSgVarRefExp(expNode)); break; default: std::cout << expNode->class_name() << " is not being considered for implementation"; expString = ""; #ifndef VERBOSE_COMPLETE ROSE_ASSERT(false); #endif } } /*if (set_to_expression_val) { std::stringstream exp_var; exp_var << "e_" << expression_count; expression_count++; std::string exp_var_decl = "(declare-const " + exp_var.str() + " Bool)"; variables.push_back(exp_var_decl); std::string exp_var_val = "(assert (= " + exp_var.str() + " " + expString + "))"; expressions.push_back(exp_var_val); return exp_var.str(); } else { return expString; }*/ return expString; }