void ProBoundsPointerArithmeticCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
  Finder->addMatcher(
      binaryOperator(
          anyOf(hasOperatorName("+"), hasOperatorName("-"),
                hasOperatorName("+="), hasOperatorName("-=")),
          hasType(pointerType()),
          unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))))))
          .bind("expr"),
      this);

  Finder->addMatcher(
      unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
                    hasType(pointerType()))
          .bind("expr"),
      this);

  // Array subscript on a pointer (not an array) is also pointer arithmetic
  Finder->addMatcher(
      arraySubscriptExpr(
          hasBase(ignoringImpCasts(
              anyOf(hasType(pointerType()),
                    hasType(decayedType(hasDecayedType(pointerType())))))))
          .bind("expr"),
      this);
}
void RedundantVoidArgCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(functionDecl(parameterCountIs(0), unless(isImplicit()),
                                  unless(isExternC()))
                         .bind(FunctionId),
                     this);
  Finder->addMatcher(typedefNameDecl().bind(TypedefId), this);
  auto ParenFunctionType = parenType(innerType(functionType()));
  auto PointerToFunctionType = pointee(ParenFunctionType);
  auto FunctionOrMemberPointer =
      anyOf(hasType(pointerType(PointerToFunctionType)),
            hasType(memberPointerType(PointerToFunctionType)));
  Finder->addMatcher(fieldDecl(FunctionOrMemberPointer).bind(FieldId), this);
  Finder->addMatcher(varDecl(FunctionOrMemberPointer).bind(VarId), this);
  auto CastDestinationIsFunction =
      hasDestinationType(pointsTo(ParenFunctionType));
  Finder->addMatcher(
      cStyleCastExpr(CastDestinationIsFunction).bind(CStyleCastId), this);
  Finder->addMatcher(
      cxxStaticCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(
      cxxReinterpretCastExpr(CastDestinationIsFunction).bind(NamedCastId),
      this);
  Finder->addMatcher(
      cxxConstCastExpr(CastDestinationIsFunction).bind(NamedCastId), this);
  Finder->addMatcher(lambdaExpr().bind(LambdaId), this);
}
Esempio n. 3
0
Type Value::typeFor(Opcode opcode, Value* firstChild)
{
    switch (opcode) {
    case Identity:
    case Add:
    case Sub:
    case Mul:
    case Div:
    case ChillDiv:
    case Mod:
    case BitAnd:
    case BitOr:
    case BitXor:
    case Shl:
    case SShr:
    case ZShr:
    case CheckAdd:
    case CheckSub:
    case CheckMul:
        return firstChild->type();
    case FramePointer:
        return pointerType();
    case SExt8:
    case SExt16:
    case Trunc:
    case DToI32:
    case Equal:
    case NotEqual:
    case LessThan:
    case GreaterThan:
    case LessEqual:
    case GreaterEqual:
    case Above:
    case Below:
    case AboveEqual:
    case BelowEqual:
        return Int32;
    case SExt32:
    case ZExt32:
        return Int64;
    case FRound:
    case IToD:
        return Double;
    case BitwiseCast:
        if (firstChild->type() == Int64)
            return Double;
        if (firstChild->type() == Double)
            return Int64;
        ASSERT_NOT_REACHED();
        return Void;
    case Nop:
        return Void;
    default:
        RELEASE_ASSERT_NOT_REACHED();
    }
}
void PointerAndIntegralOperationCheck::registerMatchers(MatchFinder *Finder) {
  const auto PointerExpr = expr(hasType(pointerType()));
  const auto BoolExpr = ignoringParenImpCasts(hasType(booleanType()));
  const auto CharExpr = ignoringParenImpCasts(hasType(isAnyCharacter()));

  const auto BinOpWithPointerExpr =
      binaryOperator(unless(anyOf(hasOperatorName(","), hasOperatorName("="))),
                     hasEitherOperand(PointerExpr));

  const auto AssignToPointerExpr =
      binaryOperator(hasOperatorName("="), hasLHS(PointerExpr));

  const auto CompareToPointerExpr =
      binaryOperator(matchers::isRelationalOperator(),
                     hasEitherOperand(PointerExpr));

  // Detect expression like: ptr = (x != y);
  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(BoolExpr))
                         .bind("assign-bool-to-pointer"),
                     this);

  // Detect expression like: ptr = A[i]; where A is char*.
  Finder->addMatcher(binaryOperator(AssignToPointerExpr, hasRHS(CharExpr))
                         .bind("assign-char-to-pointer"),
                     this);

  // Detect expression like: ptr < false;
  Finder->addMatcher(
      binaryOperator(BinOpWithPointerExpr,
                     hasEitherOperand(ignoringParenImpCasts(cxxBoolLiteral())))
          .bind("pointer-and-bool-literal"),
      this);

  // Detect expression like: ptr < 'a';
  Finder->addMatcher(binaryOperator(BinOpWithPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        characterLiteral())))
                         .bind("pointer-and-char-literal"),
                     this);

  // Detect expression like: ptr < 0;
  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        integerLiteral(equals(0)))))
                         .bind("compare-pointer-to-zero"),
                     this);

  // Detect expression like: ptr < nullptr;
  Finder->addMatcher(binaryOperator(CompareToPointerExpr,
                                    hasEitherOperand(ignoringParenImpCasts(
                                        cxxNullPtrLiteralExpr())))
                         .bind("compare-pointer-to-null"),
                     this);
}
Esempio n. 5
0
// Generate the code for a method call (save base and return label and call
// method).
void genMethodCall( FILE* yyout, Method* method, int reg )
{
	int newLabel_ = newLabel();
	int totalSize = method->argumentsSize;
	int freg = -1;
	
	// Save base
	fprintf( yyout, "\tP(R7+4) = R6;\t// Save base\n" );

	// Save return label
	fprintf( yyout, "\tP(R7) = %i;\t// Save return label\n", newLabel_ );

	
	// Call method
	fprintf( yyout, "\tGT(%i);\t// Call method\n", method->label );

	// Set return label
	fprintf( yyout, "L %i:\n", newLabel_ );
	
	if(method->returnType){
		if(!isFloat(method->returnType)){
		// Save return value
		fprintf( yyout, "\tR%d = %c(R7+%d); // Get return value\n", reg, 
			pointerType(method->returnType), totalSize);		
		}else{
		// Save return value
		fprintf( yyout, "\tRR%d = %c(R7+%d); // Get return value\n", reg, 
			pointerType(method->returnType), totalSize);		
			freg = reg;
			reg = -1;				
		}	
		totalSize += ((Type*)(method->returnType->info))->size;
	}
	// Free arguments memory
	fprintf( yyout,"\tR7 = R7 + %d;\t// Free memory for arguments and return value\n", totalSize );

	// Load the used registers from the stack
	loadRegisters(yyout, reg, freg);	
	// Print a comment to indicate the method call's end.
	fprintf( yyout, "\t/* Call to procedure - end */\n\n" );
}
Esempio n. 6
0
SymbolInfo* genArrayContent( FILE* yyout, SymbolInfo* leftSide, Symbol* literalInfo,
	SymbolInfo* arrayInfo )
{
	Symbol* varSymbol = leftSide->varSymbol;
	int position = arrayInfo->info;
	int address = ((Variable*)(varSymbol->info))->address;
	int nRegister = ((ExtraInfo*)(literalInfo->info))->nRegister;
	int	elementSize = ((Type*)(((Type*)(((Variable*)(varSymbol->info))->type->info))->arrayInfo->type->info))->size;

	int isFloat_ = isFloat(leftSide->varSymbol);
	cstr regStr = getRegStr( isFloat_ );

	switch(varSymbol->symType)
	{
	case SYM_GLOBAL:
		fprintf(yyout,"\t%c(0x%x + %d) = %s%d; //Initializing %s array\n",pointerType(varSymbol),
			address, elementSize*position, regStr, nRegister, varSymbol->name);				
		break;
	case SYM_VARIABLE:
		if(((Variable*)(varSymbol->info))->symSubtype == SYM_LOCAL){
			fprintf(yyout,"\t%c(R6 + %d) = %s%d; //Initializing %s array\n",pointerType(varSymbol),
				elementSize*position - address, regStr, nRegister, varSymbol->name);	
		}else{
			fprintf(yyout,"\t%c(R6 - %d) = %s%d; //Initializing %s array\n",pointerType(varSymbol),
				elementSize*position + address, regStr, nRegister, varSymbol->name);		
		}		
		break;
	case SYM_CONSTANT:
		break;
	default:
		//Error
		printf("Error in array content\n");
		break;				
	}
	arrayInfo->info++;
	freeRegister( ((ExtraInfo*)(literalInfo->info))->nRegister, isFloat_ );	
	freeSymbol(literalInfo);		
	return arrayInfo;
}
Esempio n. 7
0
// Generate the code for a parameter pass. Arguments:
// - iRegister - index of register with the argument's value.
// - method - called method symbol.
// - iArgument - argument index.
void genArgumentPass( FILE* yyout, Symbol* argumentSymbol, Symbol* method, int iArgument )
{
	Symbol* argument = getMethodArgument( method, iArgument );
	int iRegister = ((ExtraInfo*)(argumentSymbol->info))->nRegister;
	int address = ((Variable*)( argument->info ) )->address;

	int isFloat_ = isFloat( argumentSymbol );
	cstr regStr = getRegStr( isFloat_ );

	// Get parameter.
	fprintf( yyout,"\t%c(R7+%d) = %s%d;\t// %iº Argument\n", pointerType( argument ), address, regStr, iRegister, iArgument+1 );
	freeRegister( iRegister, isFloat_ );
	freeSymbol(argumentSymbol);
}
Esempio n. 8
0
Output::Output(CompilerState& state)
    : m_state(state)
    , m_repo(state.m_context, state.m_module)
    , m_builder(nullptr)
    , m_stackMapsId(1)
    , m_currentBlockTerminated(false)
{
    m_argType = pointerType(arrayType(repo().intPtr, state.m_platformDesc.m_contextSize / sizeof(intptr_t)));
    state.m_function = addFunction(
        state.m_module, "main", functionType(repo().voidType, m_argType));
    llvmAPI->SetFunctionCallConv(state.m_function, LLVMFastCallConv);
    m_builder = llvmAPI->CreateBuilderInContext(state.m_context);

    m_prologue = appendBasicBlock("Prologue");
    positionToBBEnd(m_prologue);
    buildGetArg();
}
void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
  // Only register the matchers for C++11; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus11)
    return;

  Finder->addMatcher(
      cxxConstructorDecl(
          unless(isImplicit()),
          allOf(isMoveConstructor(),
                hasAnyConstructorInitializer(
                    cxxCtorInitializer(
                        withInitializer(cxxConstructExpr(hasDeclaration(
                            cxxConstructorDecl(isCopyConstructor())
                                .bind("ctor")))))
                        .bind("move-init")))),
      this);

  auto NonConstValueMovableAndExpensiveToCopy =
      qualType(allOf(unless(pointerType()), unless(isConstQualified()),
                     hasDeclaration(cxxRecordDecl(hasMethod(cxxConstructorDecl(
                         isMoveConstructor(), unless(isDeleted()))))),
                     matchers::isExpensiveToCopy()));

  // This checker is also used to implement cert-oop11-cpp, but when using that
  // form of the checker, we do not want to diagnose movable parameters.
  if (!UseCERTSemantics) {
    Finder->addMatcher(
        cxxConstructorDecl(
            allOf(
                unless(isMoveConstructor()),
                hasAnyConstructorInitializer(withInitializer(cxxConstructExpr(
                    hasDeclaration(cxxConstructorDecl(isCopyConstructor())),
                    hasArgument(
                        0,
                        declRefExpr(
                            to(parmVarDecl(
                                   hasType(
                                       NonConstValueMovableAndExpensiveToCopy))
                                   .bind("movable-param")))
                            .bind("init-arg")))))))
            .bind("ctor-decl"),
        this);
  }
}
Esempio n. 10
0
    DataType TypeParser::applyTypePostfixes(const DataType& originalType, bool genericParam) {
        DataType type(originalType);

        if (_helper->nextIf(Token::Type::OperatorNot)) {
            type.setAccess(DataType::Access::ReadWrite);
        }

        if (_helper->nextIf(Token::Type::OperatorQuestionMark)) {
            DataType::Kind kind = genericParam ? DataType::Kind::GenericNullablePointer : DataType::Kind::NullablePointer;
            DataType pointerType(kind);

            pointerType.addSubtype(type);

            type = pointerType;
        }

        return type;
    }
Esempio n. 11
0
CommonValues::CommonValues(LContext context)
    : voidType(FTL::voidType(context))
    , boolean(int1Type(context))
    , int8(int8Type(context))
    , int16(int16Type(context))
    , int32(int32Type(context))
    , int64(int64Type(context))
    , intPtr(intPtrType(context))
    , floatType(FTL::floatType(context))
    , doubleType(FTL::doubleType(context))
    , ref8(pointerType(int8))
    , ref16(pointerType(int16))
    , ref32(pointerType(int32))
    , ref64(pointerType(int64))
    , refPtr(pointerType(intPtr))
    , refFloat(pointerType(floatType))
    , refDouble(pointerType(doubleType))
    , booleanTrue(constInt(boolean, true, ZeroExtend))
    , booleanFalse(constInt(boolean, false, ZeroExtend))
    , int8Zero(constInt(int8, 0, SignExtend))
    , int32Zero(constInt(int32, 0, SignExtend))
    , int32One(constInt(int32, 1, SignExtend))
    , int64Zero(constInt(int64, 0, SignExtend))
    , intPtrZero(constInt(intPtr, 0, SignExtend))
    , intPtrOne(constInt(intPtr, 1, SignExtend))
    , intPtrTwo(constInt(intPtr, 2, SignExtend))
    , intPtrThree(constInt(intPtr, 3, SignExtend))
    , intPtrFour(constInt(intPtr, 4, SignExtend))
    , intPtrEight(constInt(intPtr, 8, SignExtend))
    , intPtrPtr(constInt(intPtr, sizeof(void*), SignExtend))
    , doubleZero(constReal(doubleType, 0))
    , rangeKind(mdKindID(context, "range"))
    , profKind(mdKindID(context, "prof"))
    , branchWeights(mdString(context, "branch_weights"))
    , nonNegativeInt32(constInt(int32, 0, SignExtend), constInt(int32, 1ll << 31, SignExtend))
    , m_context(context)
    , m_module(0)
{
}
Esempio n. 12
0
void TabletWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    QStringList eventInfo;

    QString typeString("Event type: ");
    switch (mType) {
    case QEvent::TabletEnterProximity:
        typeString += "QEvent::TabletEnterProximity";
        break;
    case QEvent::TabletLeaveProximity:
        typeString += "QEvent::TabletLeaveProximity";
        break;
    case QEvent::TabletMove:
        typeString += "QEvent::TabletMove";
        break;
    case QEvent::TabletPress:
        typeString += "QEvent::TabletPress";
        break;
    case QEvent::TabletRelease:
        typeString += "QEvent::TabletRelease";
        break;
    case QEvent::MouseMove:
        typeString += "QEvent::MouseMove";
        break;
    }
    eventInfo << typeString;

    eventInfo << QString("Global position: %1 %2").arg(QString::number(mGPos.x()), QString::number(mGPos.y()));
    eventInfo << QString("Local position: %1 %2").arg(QString::number(mPos.x()), QString::number(mPos.y()));
    if (mType == QEvent::TabletEnterProximity || mType == QEvent::TabletLeaveProximity
        || mType == QEvent::TabletMove || mType == QEvent::TabletPress
        || mType == QEvent::TabletRelease) {

        eventInfo << QString("High res global position: %1 %2").arg(QString::number(mHiResGlobalPos.x()), QString::number(mHiResGlobalPos.y()));

        QString pointerType("Pointer type: ");
        switch (mPointerType) {
        case QTabletEvent::UnknownPointer:
            pointerType += "QTabletEvent::UnknownPointer";
            break;
        case QTabletEvent::Pen:
            pointerType += "QTabletEvent::Pen";
            break;
        case QTabletEvent::Cursor:
            pointerType += "QTabletEvent::Cursor";
            break;
        case QTabletEvent::Eraser:
            pointerType += "QTabletEvent::Eraser";
            break;
        }
        eventInfo << pointerType;

        QString deviceString = "Device type: ";
        switch (mDev) {
        case QTabletEvent::NoDevice:
            deviceString += "QTabletEvent::NoDevice";
            break;
        case QTabletEvent::Puck:
            deviceString += "QTabletEvent::Puck";
            break;
        case QTabletEvent::Stylus:
            deviceString += "QTabletEvent::Stylus";
            break;
        case QTabletEvent::Airbrush:
            deviceString += "QTabletEvent::Airbrush";
            break;
        case QTabletEvent::FourDMouse:
            deviceString += "QTabletEvent::FourDMouse";
            break;
        case QTabletEvent::RotationStylus:
            deviceString += "QTabletEvent::RotationStylus";
            break;
        }
        eventInfo << deviceString;

        eventInfo << QString("Button: %1 (0x%2)").arg(buttonToString(mButton)).arg(mButton, 0, 16);
        eventInfo << QString("Buttons currently pressed: %1 (0x%2)").arg(buttonsToString(mButtons)).arg(mButtons, 0, 16);
        eventInfo << QString("Pressure: %1").arg(QString::number(mPress));
        eventInfo << QString("Tangential pressure: %1").arg(QString::number(mTangential));
        eventInfo << QString("Rotation: %1").arg(QString::number(mRot));
        eventInfo << QString("xTilt: %1").arg(QString::number(mXT));
        eventInfo << QString("yTilt: %1").arg(QString::number(mYT));
        eventInfo << QString("z: %1").arg(QString::number(mZ));

        eventInfo << QString("Unique Id: %1").arg(QString::number(mUnique));
    }

    QString text = eventInfo.join("\n");
    painter.drawText(rect(), text);
}
Esempio n. 13
0
static const llvm::Type *makeLLVMType(TypePtr t) {
    switch (t->typeKind) {
    case BOOL_TYPE : return llvmIntType(8);
    case INTEGER_TYPE : {
        IntegerType *x = (IntegerType *)t.ptr();
        return llvmIntType(x->bits);
    }
    case FLOAT_TYPE : {
        FloatType *x = (FloatType *)t.ptr();
        return llvmFloatType(x->bits);
    }
    case POINTER_TYPE : {
        PointerType *x = (PointerType *)t.ptr();
        return llvmPointerType(x->pointeeType);
    }
    case CODE_POINTER_TYPE : {
        CodePointerType *x = (CodePointerType *)t.ptr();
        vector<const llvm::Type *> llArgTypes;
        for (unsigned i = 0; i < x->argTypes.size(); ++i)
            llArgTypes.push_back(llvmPointerType(x->argTypes[i]));
        for (unsigned i = 0; i < x->returnTypes.size(); ++i) {
            TypePtr t = x->returnTypes[i];
            if (x->returnIsRef[i])
                llArgTypes.push_back(llvmPointerType(pointerType(t)));
            else
                llArgTypes.push_back(llvmPointerType(t));
        }
        llvm::FunctionType *llFuncType =
            llvm::FunctionType::get(llvmIntType(32), llArgTypes, false);
        return llvm::PointerType::getUnqual(llFuncType);
    }
    case CCODE_POINTER_TYPE : {
        CCodePointerType *x = (CCodePointerType *)t.ptr();
        vector<const llvm::Type *> llArgTypes;
        for (unsigned i = 0; i < x->argTypes.size(); ++i)
            llArgTypes.push_back(llvmType(x->argTypes[i]));
        const llvm::Type *llReturnType =
            x->returnType.ptr() ? llvmType(x->returnType) : llvmVoidType();
        llvm::FunctionType *llFuncType =
            llvm::FunctionType::get(llReturnType, llArgTypes, x->hasVarArgs);
        return llvm::PointerType::getUnqual(llFuncType);
    }
    case ARRAY_TYPE : {
        ArrayType *x = (ArrayType *)t.ptr();
        return llvmArrayType(x->elementType, x->size);
    }
    case VEC_TYPE : {
        VecType *x = (VecType *)t.ptr();
        return llvm::VectorType::get(llvmType(x->elementType), x->size);
    }
    case TUPLE_TYPE : {
        TupleType *x = (TupleType *)t.ptr();
        vector<const llvm::Type *> llTypes;
        vector<TypePtr>::iterator i, end;
        for (i = x->elementTypes.begin(), end = x->elementTypes.end();
             i != end; ++i)
            llTypes.push_back(llvmType(*i));
        if (x->elementTypes.empty())
            llTypes.push_back(llvmIntType(8));
        return llvm::StructType::get(llvm::getGlobalContext(), llTypes);
    }
    case UNION_TYPE : {
        UnionType *x = (UnionType *)t.ptr();
        const llvm::Type *maxAlignType = NULL;
        size_t maxAlign = 0;
        size_t maxAlignSize = 0;
        size_t maxSize = 0;
        for (unsigned i = 0; i < x->memberTypes.size(); ++i) {
            const llvm::Type *llt =
                makeLLVMApproximateType(x->memberTypes[i]);
            size_t align = llvmTargetData->getABITypeAlignment(llt);
            size_t size = llvmTargetData->getTypeAllocSize(llt);
            if (align > maxAlign) {
                maxAlign = align;
                maxAlignType = llt;
                maxAlignSize = size;
            }
            if (size > maxSize)
                maxSize = size;
        }
        if (!maxAlignType) {
            maxAlignType = llvmIntType(8);
            maxAlign = 1;
        }
        vector<const llvm::Type *> llTypes;
        llTypes.push_back(maxAlignType);
        if (maxSize > maxAlignSize) {
            const llvm::Type *padding =
                llvm::ArrayType::get(llvmIntType(8), maxSize-maxAlignSize);
            llTypes.push_back(padding);
        }
        return llvm::StructType::get(llvm::getGlobalContext(), llTypes);
    }
    case RECORD_TYPE : {
        RecordType *x = (RecordType *)t.ptr();
        const vector<TypePtr> &fieldTypes = recordFieldTypes(x);
        vector<const llvm::Type *> llTypes;
        vector<TypePtr>::const_iterator i, end;
        for (i = fieldTypes.begin(), end = fieldTypes.end(); i != end; ++i)
            llTypes.push_back(llvmType(*i));
        if (fieldTypes.empty())
            llTypes.push_back(llvmIntType(8));
        return llvm::StructType::get(llvm::getGlobalContext(), llTypes);
    }
    case VARIANT_TYPE : {
        VariantType *x = (VariantType *)t.ptr();
        return llvmType(variantReprType(x));
    }
    case STATIC_TYPE : {
        vector<const llvm::Type *> llTypes;
        llTypes.push_back(llvmIntType(8));
        return llvm::StructType::get(llvm::getGlobalContext(), llTypes);
    }
    case ENUM_TYPE : {
        return llvmType(cIntType);
    }
    default :
        assert(false);
        return NULL;
    }
}
#include "ASTUtility.h"

StatementMatcher FuncStmtMatcher = compoundStmt(
				hasParent(functionDecl(returns(pointerType())).bind("functiondecl")),
                hasDescendant(returnStmt(
                        hasDescendant(declRefExpr().bind("decl"))))
                ).bind("funcstmt");

class ReturnChecker : public MatchFinder::MatchCallback {
public:
	virtual void run(const MatchFinder::MatchResult &Result)
    {
		clang::ASTContext *Context = Result.Context;
		const clang::CompoundStmt *cs = Result.Nodes.getNodeAs<clang::CompoundStmt>("funcstmt");
		const clang::FunctionDecl *fd = Result.Nodes.getNodeAs<clang::FunctionDecl>("functiondecl");
        const clang::DeclRefExpr *decl = Result.Nodes.getNodeAs<clang::DeclRefExpr>("decl");

		if(!cs || !fd || !decl || ASTUtility::IsStmtInSTDFile(cs, Context)) return;

        if (!clang::VarDecl::classof(decl -> getDecl())) return; 
        
        const clang::VarDecl *var = static_cast<const clang::VarDecl*>(decl -> getDecl());


        if (var -> hasLocalStorage()) 
            ASTUtility::Print(decl, Context, "Rule65");
	}
};

//@TestNeed
static llvm::cl::OptionCategory MyToolCategory("options");
#include "ASTUtility.h" 

// int *x = NULL or int *x = 0
DeclarationMatcher nullPointerMatcher = varDecl(hasType(pointerType()),
        hasInitializer(implicitCastExpr().bind("cast"))).bind("var");

// x == NULL  or x == 0
StatementMatcher biOpMatcher1 = binaryOperator(hasRHS(implicitCastExpr().bind("castR1")),
        hasOperatorName("==")).bind("bo1");

// x != NULL or x != 0
StatementMatcher biOpMatcher2 = binaryOperator(hasRHS(implicitCastExpr().bind("castR2")),
        hasOperatorName("!=")).bind("bo2");

// x != NULL or x != 0
StatementMatcher biOpMatcher3 = binaryOperator(hasRHS(implicitCastExpr().bind("castR3")),
        hasOperatorName("=")).bind("bo3");

class NullPointerPrinter : public MatchFinder::MatchCallback {
public:
    virtual void run(const MatchFinder::MatchResult &Result) 
    {
        //get the node
        clang::ASTContext *Context = Result.Context;
        const clang::ImplicitCastExpr *cast = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("cast");
        const clang::ImplicitCastExpr *castR1 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR1");
        const clang::ImplicitCastExpr *castR2 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR2");
        const clang::ImplicitCastExpr *castR3 = Result.Nodes.getNodeAs<clang::ImplicitCastExpr>("castR3");
        const clang::BinaryOperator *bo1 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo1");
        const clang::BinaryOperator *bo2 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo2");
        const clang::BinaryOperator *bo3 = Result.Nodes.getNodeAs<clang::BinaryOperator>("bo3");
Esempio n. 16
0
void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
  auto InvalidArg =
      // We want to find any expression,
      ignoreTrivials(expr(
          // which has a refcounted pointer type,
          hasType(pointerType(
              pointee(hasDeclaration(cxxRecordDecl(isRefCounted()))))),
          // and which is not this,
          unless(cxxThisExpr()),
          // and which is not a method call on a smart ptr,
          unless(cxxMemberCallExpr(on(hasType(isSmartPtrToRefCounted())))),
          // and which is not a parameter of the parent function,
          unless(declRefExpr(to(parmVarDecl()))),
          // and which is not a MOZ_KnownLive wrapped value.
          unless(callExpr(callee(functionDecl(hasName("MOZ_KnownLive"))))),
          expr().bind("invalidArg")));

  auto OptionalInvalidExplicitArg = anyOf(
      // We want to find any argument which is invalid.
      hasAnyArgument(InvalidArg),

      // This makes this matcher optional.
      anything());

  // Please not that the hasCanRunScriptAnnotation() matchers are not present
  // directly in the cxxMemberCallExpr, callExpr and constructExpr matchers
  // because we check that the corresponding functions can run script later in
  // the checker code.
  AstMatcher->addMatcher(
      expr(
          anyOf(
              // We want to match a method call expression,
              cxxMemberCallExpr(
                  // which optionally has an invalid arg,
                  OptionalInvalidExplicitArg,
                  // or which optionally has an invalid implicit this argument,
                  anyOf(
                      // which derefs into an invalid arg,
                      on(cxxOperatorCallExpr(
                          anyOf(hasAnyArgument(InvalidArg), anything()))),
                      // or is an invalid arg.
                      on(InvalidArg),

                      anything()),
                  expr().bind("callExpr")),
              // or a regular call expression,
              callExpr(
                  // which optionally has an invalid arg.
                  OptionalInvalidExplicitArg, expr().bind("callExpr")),
              // or a construct expression,
              cxxConstructExpr(
                  // which optionally has an invalid arg.
                  OptionalInvalidExplicitArg, expr().bind("constructExpr"))),

          anyOf(
              // We want to match the parent function.
              forFunction(functionDecl().bind("nonCanRunScriptParentFunction")),

              // ... optionally.
              anything())),
      this);
}
void DanglingOnTemporaryChecker::registerMatchers(MatchFinder *AstMatcher) {
  ////////////////////////////////////////
  // Quick annotation conflict checkers //
  ////////////////////////////////////////

  AstMatcher->addMatcher(
      // This is a matcher on a method declaration,
      cxxMethodDecl(
          // which is marked as no dangling on temporaries,
          noDanglingOnTemporaries(),

          // and which is && ref-qualified.
          isRValueRefQualified(),

          decl().bind("invalidMethodRefQualified")),
      this);

  AstMatcher->addMatcher(
      // This is a matcher on a method declaration,
      cxxMethodDecl(
          // which is marked as no dangling on temporaries,
          noDanglingOnTemporaries(),

          // which returns a primitive type,
          returns(builtinType()),

          // and which doesn't return a pointer.
          unless(returns(pointerType())),

          decl().bind("invalidMethodPointer")),
      this);

  //////////////////
  // Main checker //
  //////////////////

  auto hasParentCall =
      hasParent(expr(anyOf(
          cxxOperatorCallExpr(
              // If we're in a lamda, we may have an operator call expression
              // ancestor in the AST, but the temporary we're matching
              // against is not going to have the same lifetime as the
              // constructor call.
              unless(has(expr(ignoreTrivials(lambdaExpr())))),
              expr().bind("parentOperatorCallExpr")),
          callExpr(
              // If we're in a lamda, we may have a call expression
              // ancestor in the AST, but the temporary we're matching
              // against is not going to have the same lifetime as the
              // function call.
              unless(has(expr(ignoreTrivials(lambdaExpr())))),
              expr().bind("parentCallExpr")),
          objcMessageExpr(
              // If we're in a lamda, we may have an objc message expression
              // ancestor in the AST, but the temporary we're matching
              // against is not going to have the same lifetime as the
              // function call.
              unless(has(expr(ignoreTrivials(lambdaExpr())))),
              expr().bind("parentObjCMessageExpr")),
          cxxConstructExpr(
              // If we're in a lamda, we may have a construct expression
              // ancestor in the AST, but the temporary we're matching
              // against is not going to have the same lifetime as the
              // constructor call.
              unless(has(expr(ignoreTrivials(lambdaExpr())))),
              expr().bind("parentConstructExpr")))));

  AstMatcher->addMatcher(
      // This is a matcher on a method call,
      cxxMemberCallExpr(
          // which is in first party code,
          isFirstParty(),

          // and which is performed on a temporary,
          on(allOf(
              unless(hasType(pointerType())),
              isTemporary(),
              // but which is not `this`.
              unless(cxxThisExpr()))),

          // and which is marked as no dangling on temporaries.
          callee(cxxMethodDecl(noDanglingOnTemporaries())),

          expr().bind("memberCallExpr"),

          // We optionally match a parent call expression or a parent construct
          // expression because using a temporary inside a call is fine as long
          // as the pointer doesn't escape the function call.
          anyOf(
              // This is the case where the call is the direct parent, so we
              // know that the member call expression is the argument.
              allOf(hasParentCall, expr().bind("parentCallArg")),

              // This is the case where the call is not the direct parent, so we
              // get its child to know in which argument tree we are.
              hasAncestor(expr(
                  hasParentCall,
                  expr().bind("parentCallArg"))),
              // To make it optional.
              anything())),
      this);
}
Esempio n. 18
0
Symbol* genAccessVariable(FILE* yyout,cstr name, int symType, SymbolInfo* atribute)
{	
	Symbol* variable = searchVariable(symType, name);
	int isFloat_ = isFloat( variable );
	int reg;
	int height = returnVariableHeight( symType, name );
	
	//When trying to access an array variable outside a block
	//we can use expression register so we do not have to assign a new one
	if( atribute->info == TYPE_ARRAY && !isFloat_ && height == 0 ){
		reg = ((ExtraInfo*)(atribute->exprSymbol->info))->nRegister;
	}else{
		reg = assignRegisters( isFloat_ );
	}
	
	cstr regStr = getRegStr( isFloat_ );

	int elementSize = 0;	
	if (isFloat_ == 0) reg = checkOverflow(yyout, reg, TYPE_INTEGER);
	else reg = checkOverflow(yyout, reg, TYPE_FLOAT);
	
	Symbol* returnSymbol = createExtraInfoSymbol(reg, isFloat_);	
	ExtraInfo* aux = (ExtraInfo*)(returnSymbol->info); 	
	aux->nRegister = reg;
	aux->variable = variable;

	
		
	if(atribute->info == SYM_CLASS_VARIABLE){
		//varSymbol gets the Symbol of the variable
		aux->variable = getClassVar(aux->variable,atribute->name);
	}			

	if( atribute->info == TYPE_ARRAY ){
		elementSize = ((Type*)(((Type*)(((Variable*)(aux->variable->info))->type->info))->arrayInfo->type->info))->size;
	}	
	if( symType == SYM_VARIABLE )
	{
		int accessRegister = genFrameAccess( yyout, height, reg, isFloat_ );
		if(((Variable*)(aux->variable->info))->symSubtype == SYM_LOCAL){
			if( atribute->info == TYPE_ARRAY ){
				int expReg = ((ExtraInfo*)(atribute->exprSymbol->info))->nRegister;
				fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",expReg, expReg,
					elementSize, aux->variable->name);
				fprintf(yyout, "\tR%d = R%d - %d; //Calculate local %s position\n",expReg, expReg,
					returnAddress(symType,aux->variable->name), aux->variable->name);						
				fprintf(yyout,"\t%s%d = %c(R%d + R%d); //%s[expr] = expr\n",regStr, reg, 
					pointerType(aux->variable), accessRegister, expReg, aux->variable->name);	
					
				if( !(atribute->info == TYPE_ARRAY && !isFloat_ && height == 0) ){	
					freeRegister( expReg, 0 );	
				}	
				freeSymbol(atribute->exprSymbol);	
			}else{
					fprintf(yyout,"\t%s%d = %c(R%d - %d); //Loading value of var %s\n",regStr, reg, 
						pointerType(aux->variable), accessRegister, returnAddress(symType,aux->variable->name),
						aux->variable->name);
			}	
		}else{
			if( atribute->info == TYPE_ARRAY ){
				int expReg = ((ExtraInfo*)(atribute->exprSymbol->info))->nRegister;
				fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",expReg, expReg,
					elementSize, aux->variable->name);
				fprintf(yyout, "\tR%d = R%d + %d; //Calculate local %s position\n",expReg, expReg,
					returnAddress(symType,aux->variable->name), aux->variable->name);						
				fprintf(yyout,"\t%s%d = %c(R%d + R%d); //%s[expr] = expr\n",regStr, reg, 
					pointerType(aux->variable), accessRegister, expReg, aux->variable->name);
				if( !(atribute->info == TYPE_ARRAY && !isFloat_ && height == 0) ){	
					freeRegister( expReg, 0 );	
				}		
				freeSymbol(atribute->exprSymbol);
			}else{
				fprintf(yyout,"\t%s%d = %c(R%d + %d); //Loading value of var %s\n",regStr,reg, 
					pointerType(aux->variable), accessRegister, 
					returnAddress(symType,aux->variable->name),	aux->variable->name);
			}			
		}
		
		if( accessRegister != 6 ){
			freeRegister( accessRegister, 0 );
		}	
		
	}else{
		if( symType == SYM_GLOBAL )
		{
			if( atribute->info == TYPE_ARRAY ){
				int expReg = ((ExtraInfo*)(atribute->exprSymbol->info))->nRegister;
				fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",expReg, expReg,
					elementSize, aux->variable->name);
				fprintf(yyout,"\t%s%d = %c(0x%x + R%d); //Loading value of var %s[expr]\n",regStr, reg, pointerType(aux->variable),
					returnAddress(symType,aux->variable->name), expReg, aux->variable->name);
				if( !(atribute->info == TYPE_ARRAY && !isFloat_ && height == 0) ){	
					freeRegister( expReg, 0 );	
				}	
				freeSymbol(atribute->exprSymbol);
			}else{			
			fprintf(yyout,"\t%s%d = %c(0x%x); //Loading value of var %s\n", regStr, reg, pointerType(aux->variable), 
				returnAddress(symType,aux->variable->name), aux->variable->name);	
			}
		//FIXME Las constantes van aqui			
		}else{
		}
	}	
	freeSymbolInfo(atribute);
	return returnSymbol;
}
//StatementMatcher callExprMatcher = callExpr().bind("callexpr");
StatementMatcher mallocMatcher = callExpr(callee(functionDecl(hasName("malloc")).bind("m"))).bind("mallocCall");
StatementMatcher freeMatcher = callExpr(callee(functionDecl(hasName("free")).bind("f"))).bind("freeCall");
StatementMatcher reallocMatcher = callExpr(callee(functionDecl(hasName("realloc")).bind("r"))).bind("reallocCall");

//memcpy arrayType non-builtin = pointer or user-defined
StatementMatcher memcpyAryMatcher = callExpr(
        callee(functionDecl(hasName("memcpy")).bind("cpy")),
        hasAnyArgument(ignoringImpCasts(declRefExpr(
                    to(declaratorDecl(hasType(arrayType(
                                    unless(hasElementType(builtinType()))).bind("cpyParm")))))))
        ).bind("memcpyCall");
StatementMatcher memcpyPtrMatcher = callExpr(
        callee(functionDecl(hasName("memcpy")).bind("cpy")),
        hasAnyArgument(ignoringImpCasts(declRefExpr(
                    to(declaratorDecl(hasType(pointerType(
                                    pointee(unless(builtinType()))).bind("cpyParmPtr")))))))
        ).bind("memcpyCall");


StatementMatcher memcmpAryMatcher = callExpr(
        callee(functionDecl(hasName("memcmp")).bind("cmp")),
        hasAnyArgument(ignoringImpCasts(declRefExpr(
                    to(declaratorDecl(hasType(arrayType(
                                    unless(hasElementType(builtinType()))).bind("cmpParm")))))))
        ).bind("memcmpCall");
StatementMatcher memcmpPtrMatcher = callExpr(
        callee(functionDecl(hasName("memcmp")).bind("cmp")),
        hasAnyArgument(ignoringImpCasts(declRefExpr(
                    to(declaratorDecl(hasType(pointerType(
                                    pointee(unless(builtinType()))).bind("cmpParmPtr")))))))
        ).bind("memcmpCall");
Esempio n. 20
0
Type Value::typeFor(Opcode opcode, Value* firstChild, Value* secondChild)
{
    switch (opcode) {
    case Identity:
    case Add:
    case Sub:
    case Mul:
    case Div:
    case Mod:
    case Neg:
    case ChillDiv:
    case ChillMod:
    case BitAnd:
    case BitOr:
    case BitXor:
    case Shl:
    case SShr:
    case ZShr:
    case Clz:
    case Abs:
    case Ceil:
    case Sqrt:
    case CheckAdd:
    case CheckSub:
    case CheckMul:
        return firstChild->type();
    case FramePointer:
        return pointerType();
    case SExt8:
    case SExt16:
    case Trunc:
    case Equal:
    case NotEqual:
    case LessThan:
    case GreaterThan:
    case LessEqual:
    case GreaterEqual:
    case Above:
    case Below:
    case AboveEqual:
    case BelowEqual:
    case EqualOrUnordered:
        return Int32;
    case SExt32:
    case ZExt32:
        return Int64;
    case FloatToDouble:
    case IToD:
        return Double;
    case DoubleToFloat:
        return Float;
    case BitwiseCast:
        switch (firstChild->type()) {
        case Int64:
            return Double;
        case Double:
            return Int64;
        case Int32:
            return Float;
        case Float:
            return Int32;
        case Void:
            ASSERT_NOT_REACHED();
        }
        return Void;
    case Nop:
        return Void;
    case Select:
        ASSERT(secondChild);
        return secondChild->type();
    default:
        RELEASE_ASSERT_NOT_REACHED();
    }
}
Esempio n. 21
0
static void initializeLambdaWithFreeVars(LambdaPtr x, EnvPtr env,
    string const &closureDataName, string const &lname)
{
    RecordPtr r = new Record(PRIVATE);
    r->location = x->location;
    r->name = new Identifier(lname);
    r->env = env;
    x->lambdaRecord = r;
    r->lambda = x;
    vector<RecordFieldPtr> fields;

    CallPtr converted = new Call(NULL, new ExprList());
    for (unsigned i = 0; i < x->freeVars.size(); ++i) {
        IdentifierPtr ident = new Identifier(x->freeVars[i]);
        NameRefPtr nameRef = new NameRef(ident);

        TypePtr type;
        ObjectPtr obj = safeLookupEnv(env, ident);
        switch (obj->objKind) {
        case PVALUE :
        case CVALUE : {
            type = typeOfValue(obj);
            if (x->captureByRef) {
                type = pointerType(type);
                vector<int> ops;
                ops.push_back(ADDRESS_OF);
                ExprPtr addr = new VariadicOp(ops, new ExprList(nameRef.ptr()));
                converted->parenArgs->add(addr);
            }
            else {
                converted->parenArgs->add(nameRef.ptr());
            }
            break;
        }
        case MULTI_PVALUE :
        case MULTI_CVALUE : {
            vector<TypePtr> types = typesOfValues(obj);
            vector<TypePtr> elementTypes;
            for (unsigned j = 0; j < types.size(); ++j) {
                TypePtr t = types[j];
                if (x->captureByRef)
                    t = pointerType(t);
                elementTypes.push_back(t);
            }
            type = tupleType(elementTypes);
            if (x->captureByRef) {
                ExprPtr e = operator_expr_packMultiValuedFreeVarByRef();
                CallPtr call = new Call(e, new ExprList());
                call->parenArgs->add(new Unpack(nameRef.ptr()));
                converted->parenArgs->add(call.ptr());
            }
            else {
                ExprPtr e = operator_expr_packMultiValuedFreeVar();
                CallPtr call = new Call(e, new ExprList());
                call->parenArgs->add(new Unpack(nameRef.ptr()));
                converted->parenArgs->add(call.ptr());
            }
            break;
        }
        default :
            assert(false);
        }

        ExprPtr fieldType = new ObjectExpr(type.ptr());
        RecordFieldPtr field = new RecordField(ident, fieldType);
        fields.push_back(field);
    }
    r->body = new RecordBody(fields);

    TypePtr t = recordType(r, vector<ObjectPtr>());
    x->lambdaType = t;
    ExprPtr typeExpr = new ObjectExpr(t.ptr());
    converted->expr = typeExpr;
    x->converted = converted.ptr();

    CodePtr code = new Code();
    code->location = x->location;
    IdentifierPtr closureDataIdent = new Identifier(closureDataName);
    FormalArgPtr closureDataArg = new FormalArg(closureDataIdent, typeExpr);
    code->formalArgs.push_back(closureDataArg.ptr());
    for (unsigned i = 0; i < x->formalArgs.size(); ++i) {
        code->formalArgs.push_back(x->formalArgs[i]);
    }
    if (x->formalVarArg.ptr()) {
        code->formalVarArg = x->formalVarArg;
    }
    code->body = x->body;

    OverloadPtr overload = new Overload(
        operator_expr_call(), code, false, false
    );
    overload->env = env;
    overload->location = x->location;
    ObjectPtr obj = operator_call();
    if (obj->objKind != PROCEDURE)
        error("'call' operator not found!");
    Procedure *callObj = (Procedure *)obj.ptr();
    callObj->overloads.insert(callObj->overloads.begin(), overload);
}
Esempio n. 22
0
Symbol* genAssignement(FILE* yyout, SymbolInfo* leftSide, Symbol* rightSide, int insideIfLoop)
{
	ExtraInfo* rightInfo = (ExtraInfo*)(rightSide->info);
	Variable* leftInfo = (Variable*)(leftSide->varSymbol->info);
	int i, arraySize, elementSize;

	if( rightInfo->assignmentType == TYPE_ARRAY || leftSide->info == TYPE_ARRAY ){
		arraySize = ((Type*)(leftInfo->type->info))->arrayInfo->nElements;
		elementSize = ((Type*)(((Type*)(leftInfo->type->info))->arrayInfo->type->info))->size;
	}		

	int isFloat_ = isFloat(leftSide->varSymbol);
	cstr regStr = getRegStr( isFloat_ );

	int height = returnVariableHeight( leftSide->varSymbol->symType, leftSide->varSymbol->name );
			
	//Left side is a global variable
	if (leftSide->varSymbol->symType == SYM_GLOBAL){					
		//Aquí no afecta el derramado porque la asignacion se hace directamente a memoria.	
		//var = Array / Class
		if( rightInfo->assignmentType == LOAD_ADDRESS ){
			//FIXME Aqui deberiamos cargar la direccion de la variable, para arrays y clases
		}else{
			//Right side is Array.new
			if( rightInfo->assignmentType == TYPE_ARRAY ){
				for( i = 0; i < arraySize; i++ ){
					fprintf(yyout,"\t%c(0x%x + %d) = %s%d; //Initializing %s array",pointerType(leftSide->varSymbol),
						leftInfo->address, elementSize*i, regStr, rightInfo->nRegister, leftSide->varSymbol->name);				
				}
			}else{		
				//Assignement $var[expression] = expression
				if( leftSide->info == TYPE_ARRAY ){
					int reg = ((ExtraInfo*)(leftSide->exprSymbol->info))->nRegister;
					fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",reg, reg,
						elementSize, leftSide->varSymbol->name);
					fprintf(yyout,"\t%c(0x%x + R%d) = %s%d; //%s[expr] = expr\n",pointerType(leftSide->varSymbol),
						leftInfo->address, reg, regStr, rightInfo->nRegister, leftSide->varSymbol->name );
					freeRegister( reg, 0 );	
					freeSymbol(leftSide->exprSymbol);
				//Assignement $var = expression
				}else{
					fprintf(yyout,"\t%c(0x%x) = %s%d; //%s = expr\n",pointerType(leftSide->varSymbol),
						leftInfo->address, regStr, rightInfo->nRegister, leftSide->varSymbol->name, isFloat_);			
				}		
			}
		}			
	//Left side not a global varialbe
	}else if (leftSide->varSymbol->symType == SYM_VARIABLE){
		//Obtenemos la direccion con el desplazamiento y almacenamos
		if( rightInfo->assignmentType == LOAD_ADDRESS ){
			//FIXME Aqui deberiamos cargar la direccion de la variable, para arrays y clases
		}else{	
			int accessRegister = genFrameAccess( yyout, height, -1, 1 );
			//Left side is a local variable
			if(((Variable*)(leftSide->varSymbol->info))->symSubtype == SYM_LOCAL){
				//Right side is Array.new or [e,e,..,e]
				if( rightInfo->assignmentType == TYPE_ARRAY ){
					for( i = 0; i < arraySize; i++ ){	
						fprintf(yyout,"\t%c(R%d - %d) = %s%d; //Initializing %s array\n",pointerType(leftSide->varSymbol),
							accessRegister,leftInfo->address - elementSize*i, 
							regStr, rightInfo->nRegister, leftSide->varSymbol->name);				
					}	
				}else{	
					//Assignement var[expression] = expression
					if( leftSide->info == TYPE_ARRAY ){
						int reg = ((ExtraInfo*)(leftSide->exprSymbol->info))->nRegister;
						fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",reg, reg,
							elementSize, leftSide->varSymbol->name);
						fprintf(yyout, "\tR%d = R%d - %d; //Calculate local %s position\n",reg, reg,
							leftInfo->address, leftSide->varSymbol->name);				
						fprintf(yyout,"\t%c(R%d + R%d) = %s%d; //%s[expr] = expr (2)\n",pointerType(leftSide->varSymbol),
							accessRegister, reg, regStr, rightInfo->nRegister, leftSide->varSymbol->name);
							freeRegister( reg, 0 );		
						freeSymbol(leftSide->exprSymbol);
					//Assignement var = expression
					}else{	
						fprintf(yyout,"\t%c(R%d - %d) = %s%d; //%s = expr\n",pointerType(leftSide->varSymbol),
							accessRegister, leftInfo->address, regStr, rightInfo->nRegister, leftSide->varSymbol->name);
					}		
				}	
			}
			//Left side is an argument variable
			else{
				//Right side is Array.new or [e,e,..,e]
				if( rightInfo->assignmentType == TYPE_ARRAY ){
					for( i = 0; i < arraySize; i++ ){	
						fprintf(yyout,"\t%c(R%d + %d) = %s%d; //Initializing %s array\n",pointerType(leftSide->varSymbol),
							accessRegister, leftInfo->address + elementSize*i, 
							regStr, rightInfo->nRegister, leftSide->varSymbol->name);				
					}	
				}else{				
					//Assignement var[expression] = expression
					if( leftSide->info == TYPE_ARRAY ){
						int reg = ((ExtraInfo*)(leftSide->exprSymbol->info))->nRegister;
						fprintf(yyout, "\tR%d = R%d * %d; //Calculate array %s position\n",reg, reg,
							elementSize, leftSide->varSymbol->name);
						fprintf(yyout, "\tR%d = R%d - %d; //Calculate local %s position\n",reg, reg,
							leftInfo->address, leftSide->varSymbol->name);						
						fprintf(yyout,"\t%c(R%d - R%d) = %s%d; //%s[expr] = expr\n",pointerType(leftSide->varSymbol),
							accessRegister, reg, regStr, rightInfo->nRegister, leftSide->varSymbol->name);
						freeRegister( reg, 0 );	
						freeSymbol(leftSide->exprSymbol);
					//Assignement var = expression
					}else{			
						fprintf(yyout,"\t%c(R%d + %d) = %s%d; //%s = expr\n",pointerType(leftSide->varSymbol),
							accessRegister, leftInfo->address, regStr, rightInfo->nRegister, leftSide->varSymbol->name);
					}			
				}
			}
			if( accessRegister != 6 ){
				freeRegister( accessRegister, 0 );
			}	
		}
	}

	if(!insideIfLoop){
		int reg = rightInfo->nRegister;
		Method* method = getCurrentScope();
	
		if(method->returnType){	
			int size = method->argumentsSize;	
			if(!isFloat(method->returnType) && !isFloat_){												
				fprintf(yyout,"\t%c(R6 + %d) = R%d; //Store return value\n",
					pointerType(method->returnType), size, reg);
			}else{
				if(isFloat(method->returnType) && isFloat_){
					fprintf(yyout,"\t%c(R6 + %d) = RR%d; //Store return value\n",
						pointerType(method->returnType), size, reg);				
				}
			}		
		}
	}

	freeRegister( rightInfo->nRegister, isFloat_ );
	freeSymbolInfo(leftSide);

	return rightSide;
}