From 7e61ac5a3c84416773f7bf64d51ae856978252dc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 11 Apr 2007 03:42:36 +0000 Subject: [PATCH] Catch overflow of negate. This allows us to emit: t.c:2:17: warning: integer overflow in preprocessor expression #if -(INTMAX_MAX+1) ^ t.c:2:5: warning: integer overflow in preprocessor expression #if -(INTMAX_MAX+1) ^ GCC has some seriously confused source locations in this case: t.c:2:19: warning: integer overflow in preprocessor expression t.c:2:20: warning: integer overflow in preprocessor expression column 19/20 are off the end of the line. llvm-svn: 39404 --- clang/Lex/PPExpressions.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/clang/Lex/PPExpressions.cpp b/clang/Lex/PPExpressions.cpp index 4c17dd1be8b5..a012d8fe7b8d 100644 --- a/clang/Lex/PPExpressions.cpp +++ b/clang/Lex/PPExpressions.cpp @@ -261,13 +261,26 @@ static bool EvaluateValue(APSInt &Result, LexerToken &PeekTok, // Unary plus doesn't modify the value. PP.LexNonComment(PeekTok); return EvaluateValue(Result, PeekTok, DT, ValueLive, PP); - case tok::minus: + case tok::minus: { + SourceLocation Loc = PeekTok.getLocation(); PP.LexNonComment(PeekTok); if (EvaluateValue(Result, PeekTok, DT, ValueLive, PP)) return true; // C99 6.5.3.3p3: The sign of the result matches the sign of the operand. Result = -Result; + + bool Overflow = false; + if (Result.isUnsigned()) + Overflow = !Result.isPositive(); + else if (Result.isMinSignedValue()) + Overflow = true; // -MININT is the only thing that overflows. + + // If this operator is live and overflowed, report the issue. + if (Overflow && ValueLive) + PP.Diag(Loc, diag::warn_pp_expr_overflow); + DT.State = DefinedTracker::Unknown; return false; + } case tok::tilde: PP.LexNonComment(PeekTok); -- GitLab