Checking For The Overflow Of An Expr In A ASTMatcher

Hi,
I have two questions.
I wan to check for overflows in an ASTMatcher.
I only need to check for Exprs that are of type Int, so I figured I
could use Expr::EvaluateAsInt.
I have the following code:

#define START 0x80000000
#define END 0xFFFFFFFF
#define LEN 0x80000000

if ((START + LEN) > END)
{
   /*does something*/
}

Int size on my target(x86-64) is 32-bits so obviously START + LEN
should overflow.
when i call the APSInt.getExtValue() I get 4294967295 which has
overflowed and saturated. The type of the Expr is Int so the result is
saturated and then when i extend it with getExtValue its not going to
give me 4294967296 obviously.
My question is, is there a way to cast the result of the evaluation to
a wider type before it gets truncated?

I also thought i could use Expr::EvaluateForOverflow( const
ASTContext) but i cant figure out how it works. My question is How
does it return a value I can check for?
The return type is void so i figured maybe its setting a flag
somewhere but I couldnt find it. I looked at Expr's attributes but no
luck. I thought maybe ASTContext holds the result but I couldn't find
anything there either.

Hello!

It sounds strange that you get a saturated value.

try this code:

    B->dump();

    llvm::APSInt Result;
    B->EvaluateAsInt(Result, AC->getASTContext());
    Result.dump();

My output is:

    BinaryOperator 0x651b98 'unsigned int' '+'
    >-IntegerLiteral 0x651b58 'unsigned int' 2147483648
    `-IntegerLiteral 0x651b78 'unsigned int' 2147483648

    APInt(32b, 0u 0s)

Here it can be seen that there has been an overflow since the result is less than the operands.

Best regards,
Daniel Marjamäki

..................................................................................................................
Daniel Marjamäki Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden

Mobile: +46 (0)709 12 42 62
E-mail: Daniel.Marjamaki@evidente.se

www.evidente.se

My dump also shows the same thing:
ParenExpr 0x30debe0 'unsigned int'
`-BinaryOperator 0x30debb8 'unsigned int' '+'
  >-IntegerLiteral 0x30deb78 'unsigned int' 2147483648
  `-IntegerLiteral 0x30deb98 'unsigned int' 2147483648
APInt(32b, 0u 0s)

but when i use getExtValue() it returns 0xFFFFFFFF which is not a wrap-around.
maybe i shouldnt get the value like that?

My dump also shows the same thing:
ParenExpr 0x30debe0 'unsigned int'
`-BinaryOperator 0x30debb8 'unsigned int' '+'
  >-IntegerLiteral 0x30deb78 'unsigned int' 2147483648
  `-IntegerLiteral 0x30deb98 'unsigned int' 2147483648
APInt(32b, 0u 0s)

but when i use getExtValue() it returns 0xFFFFFFFF which is not a wrap-around.
maybe i shouldnt get the value like that?

I don't know why you get 0xFFFFFFFF from getExtValue(). I get 0.

    B->dump();

    llvm::APSInt Result;
    B->EvaluateAsInt(Result, AC->getASTContext());
    Result.dump();

    llvm::APSInt LVal;
    B->getLHS()->EvaluateAsInt(LVal, AC->getASTContext());

    __int64 x = Result.getExtValue(); // <- x=0
    bool y = Result < LVal; // <- y=true

Best regards,
Daniel Marjamäki

..................................................................................................................
Daniel Marjamäki Senior Engineer
Evidente ES East AB Warfvinges väg 34 SE-112 51 Stockholm Sweden

Mobile: +46 (0)709 12 42 62
E-mail: Daniel.Marjamaki@evidente.se

www.evidente.se

its solved now. I was matching the same expr more than once without
realizing, so i was looking at the result from a different part of the
same expr.