[cfe-commits] r39400 - in /cfe/cfe/trunk: Lex/PPExpressions.cpp include/clang/Basic/DiagnosticKinds.def
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:43:59 PDT 2007
Author: clattner
Date: Wed Jul 11 11:43:59 2007
New Revision: 39400
URL: http://llvm.org/viewvc/llvm-project?rev=39400&view=rev
Log:
Track overflow of shift amounts, allowing diagnostics like:
t.c:6:7: warning: integer overflow in preprocessor expression
#if 1 << 63
^
t.c:8:7: warning: integer overflow in preprocessor expression
#if 4 << 62
^
t.c:10:7: warning: integer overflow in preprocessor expression
#if 4 << 66
^
but no diagnostic on:
#if 1U << 63
Modified:
cfe/cfe/trunk/Lex/PPExpressions.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/PPExpressions.cpp?rev=39400&r1=39399&r2=39400&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/PPExpressions.cpp (original)
+++ cfe/cfe/trunk/Lex/PPExpressions.cpp Wed Jul 11 11:43:59 2007
@@ -421,6 +421,7 @@
}
// FIXME: All of these should detect and report overflow??
+ bool Overflow = false;
switch (Operator) {
default: assert(0 && "Unknown operator token!");
case tok::percent:
@@ -440,16 +441,29 @@
case tok::star:
LHS *= RHS;
break;
- case tok::lessless:
- // FIXME: shift amt overflow?
- // FIXME: Don't use getZExtValue.
- LHS <<= RHS.getZExtValue();
- break;
- case tok::greatergreater:
- // FIXME: signed vs unsigned
- // FIXME: Don't use getZExtValue.
- LHS >>= RHS.getZExtValue();
+ case tok::lessless: {
+ // Determine whether overflow is about to happen.
+ unsigned ShAmt = RHS.getLimitedValue();
+ if (ShAmt >= LHS.getBitWidth())
+ Overflow = true, ShAmt = LHS.getBitWidth()-1;
+ else if (LHS.isUnsigned())
+ Overflow = ShAmt > LHS.countLeadingZeros();
+ else if (LHS.isPositive())
+ Overflow = ShAmt >= LHS.countLeadingZeros(); // Don't allow sign change.
+ else
+ Overflow = ShAmt >= LHS.countLeadingOnes();
+
+ LHS <<= ShAmt;
+ break;
+ }
+ case tok::greatergreater: {
+ // Determine whether overflow is about to happen.
+ unsigned ShAmt = RHS.getLimitedValue();
+ if (ShAmt >= LHS.getBitWidth())
+ Overflow = true, ShAmt = LHS.getBitWidth()-1;
+ LHS >>= ShAmt;
break;
+ }
case tok::plus:
LHS += RHS;
break;
@@ -532,6 +546,10 @@
PP.Diag(OpToken, diag::err_pp_colon_without_question);
return true;
}
+
+ // If this operator is live and overflowed, report the issue.
+ if (Overflow && ValueLive)
+ PP.Diag(OpToken, diag::warn_pp_expr_overflow);
}
return false;
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39400&r1=39399&r2=39400&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:59 2007
@@ -114,6 +114,8 @@
"macro is not used")
DIAG(pp_invalid_string_literal, WARNING,
"invalid string literal, ignoring final '\\'")
+DIAG(warn_pp_expr_overflow, WARNING,
+ "integer overflow in preprocessor expression")
DIAG(ext_pp_import_directive, EXTENSION,
"#import is a language extension")
More information about the cfe-commits
mailing list