bool Parser::parse<SgValueExp *>(SgValueExp * & expr) const { skip_whitespace(); if (!AstFromString::afs_match_constant()) return false; skip_whitespace(); expr = isSgValueExp(AstFromString::c_parsed_node); return expr != NULL; }
std::ostream& operator<<(std::ostream &out, const TypeDescription &typeDescription) { out << typeDescription.get_fortran_type(); if( typeDescription.get_kind() != NULL ){ SgValueExp* kindValue = isSgValueExp(typeDescription.get_kind()); if (kindValue != NULL){ out << "_" << kindValue->get_constant_folded_value_as_string(); } else { out << "_kind"; } } return out; }
// Compares td to this. If we can tell for sure that they are the // same it returns true and false in all other cases. This can // lead to false negatives when the kind is an arbitrary expression bool TypeDescription::operator==(const TypeDescription &td) const { if( &td == this ) return true; if( td.get_fortran_type() == this->get_fortran_type() ){ if( td.get_kind() == NULL && this->get_kind() == NULL ) return true; if( td.get_kind() == NULL || this->get_kind() == NULL ){ // Need the alias information to resolve this // We conservatively, say that they are not equal // because one side had NULL kind and the other non-NULL return false; } SgValueExp* kindValue = isSgValueExp(get_kind()); SgValueExp* tdKindValue = isSgValueExp(td.get_kind()); if (kindValue != NULL && tdKindValue != NULL) { return kindValue->get_constant_folded_value_as_string() == tdKindValue->get_constant_folded_value_as_string(); } } return false; }
Data::Data( PolyGraph * polygraph_, SgExpression * exp, const PolyhedricAnnotation::FunctionPolyhedralProgram & function_program, std::string isl_domain ) : ParseTree(polygraph_), id(0), access(NULL) { if (!isSgValueExp(exp)) { try { SgExpression * last = exp; SgPntrArrRefExp * arr_ref = isSgPntrArrRefExp(last); std::vector<std::string> subscripts; while (arr_ref != NULL) { subscripts.insert(subscripts.begin(), sageExpToIslAff(arr_ref->get_rhs_operand_i())); last = arr_ref->get_lhs_operand_i(); arr_ref = isSgPntrArrRefExp(last); } if (subscripts.size() > 0) { std::ostringstream map; map << "{ " << isl_domain << " -> ["; for (int i = 0; i < subscripts.size(); i++) { map << subscripts[i]; if (i != subscripts.size() - 1) map << ", "; } map << "] }"; access = isl_map_read_from_str(polygraph->context, map.str().c_str()); } RoseVariable * var = PolyhedricAnnotation::translateVarRef(last); id = function_program.getVariableID(*var); std::cerr << var << " -> " << var->getString() << " -> " << id << std::endl; delete var; } catch (Exception::ExceptionBase & e) { e.print(std::cerr); exit(-1); } } }
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 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(); }
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; }