/** 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;
}
    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
    }
Example #3
0
 // Note: this now (11/7/2008) considers pointer derefs and array derefs safe,
 // which doesn't preserve invalid memory access behavior
 bool isSimpleInitializer(SgExpression* e) {
     if (isSgVarRefExp(e)) return true;
     if (isSgValueExp(e)) return true;
     if (isSgUnaryOp(e) && isSimpleInitializer(isSgUnaryOp(e)->get_operand())) {
         return isSgBitComplementOp(e) || isSgMinusOp(e) || isSgNotOp(e) || isSgUnaryAddOp(e) || isSgCastExp(e) || isSgPointerDerefExp(e);
     }
     if (isSgBinaryOp(e) && isSimpleInitializer(isSgBinaryOp(e)->get_lhs_operand()) && isSimpleInitializer(isSgBinaryOp(e)->get_rhs_operand())) {
         return isSgAddOp(e) || isSgAndOp(e) || isSgBitAndOp(e) || isSgBitOrOp(e) || isSgBitXorOp(e) || isSgCommaOpExp(e) || isSgDivideOp(e) || isSgEqualityOp(e) || isSgGreaterOrEqualOp(e) || isSgGreaterThanOp(e) || isSgLessOrEqualOp(e) || isSgLessThanOp(e) || isSgLshiftOp(e) || isSgModOp(e) || isSgMultiplyOp(e) || isSgNotEqualOp(e) || isSgOrOp(e) || isSgRshiftOp(e) || isSgSubtractOp(e) || isSgPntrArrRefExp(e);
     }
     if (isSgConditionalExp(e)) {
         SgConditionalExp* c = isSgConditionalExp(e);
         return isSimpleInitializer(c->get_conditional_exp()) && isSimpleInitializer(c->get_true_exp()) && isSimpleInitializer(c->get_false_exp());
     }
     if (isSgFunctionCallExp(e)) {
         SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
         if (!fr) return false;
         SgFunctionDeclaration* decl = fr->get_symbol()->get_declaration();
         if (safe_functions.find(decl) == safe_functions.end()) {
             return false;
         }
         const SgExpressionPtrList& args = isSgFunctionCallExp(e)->get_args()->get_expressions();
         for (size_t i = 0; i < args.size(); ++i) {
             if (!isSimpleInitializer(args[i])) return false;
         }
         return true;
     }
     return false;
 }