コード例 #1
0
ファイル: SSAGenerator.C プロジェクト: matzke1/rose-develop
//Generates SSA form numbers for the variables contained in *ex and attaches them as AstValueAttributes to the related SgNodes
//Assumption: *ex is located in in the inTrueBranch branch of the if node labeled *condLabel (These two arguments are required to generate the SSA form numbers)  
void SSAGenerator::processSgExpression(SgExpression* ex, Label* condLabel, bool inTrueBranch)
{
	SgIntVal* intVal = dynamic_cast<SgIntVal*>(ex);
	SgMinusOp* minusOp = dynamic_cast<SgMinusOp*>(ex);
	SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(ex);
	SgBinaryOp* binOp = dynamic_cast<SgBinaryOp*>(ex);
	SgFunctionCallExp* funcCall = dynamic_cast<SgFunctionCallExp*>(ex);
	
	if(intVal) //Int value
	{
		//Nothing needs to be done; Case is listed here to have a collection of all expected cases
	}
	else if(minusOp)
	{
		processSgExpression(minusOp->get_operand(), condLabel, inTrueBranch);
	}
	else if(varRef) //Reference to variable that is NOT on the left hand side of an assignment
	{
		//Assign number to variable
		string varName = varRef->get_symbol()->get_name().getString();
		int varNumber = currentNumber(varName, condLabel, inTrueBranch);  
		logger[Sawyer::Message::DEBUG] << "Current number for variable " << varName << ": " << varNumber << endl;
		AstValueAttribute<int>* varNumberAtt = new AstValueAttribute<int>(varNumber);
		varRef->setAttribute("SSA_NUMBER", varNumberAtt);	
	}
	else if(binOp) //Binary operation
	{	
		SgExpression* lhs = binOp->get_lhs_operand();
		SgExpression* rhs = binOp->get_rhs_operand();

		//Process right hand side first
		processSgExpression(rhs, condLabel, inTrueBranch);
		
		//Process left hand side second
		SgAssignOp* assignOp = dynamic_cast<SgAssignOp*>(binOp);	
		if(assignOp) //Assignment to a variable
		{
			//Assign new number to that variable  
			SgVarRefExp* lhsVarRef = dynamic_cast<SgVarRefExp*>(lhs);
			assert(lhsVarRef != NULL);
			processAssignmentTo(lhsVarRef, condLabel, inTrueBranch);
		}
		else //Arithmetic operation or boolean operation (or something unexpected)
		{
			processSgExpression(lhs, condLabel, inTrueBranch);	
		}	
		
	}
	else if(funcCall) //Call to a function
			  //RERS specific; Only two function call types are supported: 
			  //(1) scanf("%d",&...); 
			  //(2) __VERIFIER_error(RERSVerifierErrorNumber); The artificial bool variable RERSErrorOccured has to be updated 
	{
		string funcName = funcCall->getAssociatedFunctionSymbol()->get_name().getString();
		logger[Sawyer::Message::DEBUG] << "Call to function: " << funcName << endl;
		if(funcName == "scanf") //(1)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			SgExpressionPtrList::iterator i = funcArgsPtrs.begin();
			while(i != funcArgsPtrs.end())
			{
				SgAddressOfOp* addrOp = dynamic_cast<SgAddressOfOp*>(*i);
				if(addrOp) 
				{
					SgVarRefExp* varRef = dynamic_cast<SgVarRefExp*>(addrOp->get_operand());
					if(varRef)
					{
						processAssignmentTo(varRef, condLabel, inTrueBranch);
					}
					else logger[Sawyer::Message::DEBUG] << "FOUND NO REFERENCE TO VARIABLE" << endl;
				}
				i++;	
			}	
		}
		else if(funcName == "__VERIFIER_error" && prepareReachabilityAnalysisZ3)
		{
			SgExprListExp* funcArgs = funcCall->get_args();
			SgExpressionPtrList funcArgsPtrs = funcArgs->get_expressions();
			assert(funcArgsPtrs.size() == 1);
			SgExpression* argument = *funcArgsPtrs.begin();
			SgIntVal* intArgument = dynamic_cast<SgIntVal*>(argument);
			assert(intArgument != NULL);
			if(intArgument->get_value() == RERSVerifierErrorNumber) //(2) 
			{
				int RERSErrorOccuredNumber = nextNumber("RERSErrorOccured", condLabel, inTrueBranch); 
				logger[Sawyer::Message::DEBUG] << "Next number for variable RERSErrorOccured: " << RERSErrorOccuredNumber << endl;
				AstValueAttribute<int>* numberAtt = new AstValueAttribute<int>(RERSErrorOccuredNumber);
				funcCall->setAttribute("SSA_NUMBER", numberAtt); 
			}
		}
		else logger[Sawyer::Message::DEBUG] << "Ignoring function call" << endl;
	}
	else //Unexpected
	{
		logger[Sawyer::Message::ERROR] << "ERROR: SgExpression could not be handled: " << ex->class_name() << endl;
		assert(false);
	}
}