[cfe-commits] r39385 - 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:50 PDT 2007
Author: clattner
Date: Wed Jul 11 11:43:50 2007
New Revision: 39385
URL: http://llvm.org/viewvc/llvm-project?rev=39385&view=rev
Log:
Switch PPExpression parsing to be in terms of APInt's whose widths are properly
sized to the target's intmax_t. This also allows us to emit diagnostic like:
t.c:11:5: warning: integer constant is too large for its type
#if 18446744073709551616 // 2^64
^
t.c:15:5: warning: integer constant is too large for its type
#if 18446744073709551617 // 2^64-1
^
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=39385&r1=39384&r2=39385&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/PPExpressions.cpp (original)
+++ cfe/cfe/trunk/Lex/PPExpressions.cpp Wed Jul 11 11:43:50 2007
@@ -24,11 +24,12 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TokenKinds.h"
#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallString.h"
using namespace llvm;
using namespace clang;
-static bool EvaluateDirectiveSubExpr(int &LHS, unsigned MinPrec,
+static bool EvaluateDirectiveSubExpr(APInt &LHS, unsigned MinPrec,
LexerToken &PeekTok, Preprocessor &PP);
/// DefinedTracker - This struct is used while parsing expressions to keep track
@@ -57,8 +58,8 @@
/// return the computed value in Result. Return true if there was an error
/// parsing. This function also returns information about the form of the
/// expression in DT. See above for information on what DT means.
-static bool EvaluateValue(int &Result, LexerToken &PeekTok, DefinedTracker &DT,
- Preprocessor &PP) {
+static bool EvaluateValue(APInt &Result, LexerToken &PeekTok,
+ DefinedTracker &DT, Preprocessor &PP) {
Result = 0;
DT.State = DefinedTracker::Unknown;
@@ -97,7 +98,7 @@
Result = II->getMacroInfo() != 0;
// If there is a macro, mark it used.
- if (Result) {
+ if (Result != 0) {
II->getMacroInfo()->setIsUsed(true);
// If this is the first use of a target-specific macro, warn about it.
@@ -153,25 +154,20 @@
PeekTok.getLocation(), PP);
if (Literal.hadError)
return true; // a diagnostic was already reported.
- else if (Literal.isIntegerLiteral()) {
- if (!Literal.GetIntegerValue(Result)) {
- // FIXME: C99 (6.10.1) dictates that all preprocessor arithmetic be
- // performed using the largest integer type found on the target
- // computer, which is intmax_t (the default) or uintmax_t (if the
- // literal contains an unsigned suffix) defined in stdint.h.
- // Since "Result" is typed as "int", the maximum legal integer
- // literal is currently INT32_MAX (or 2147483647). If the literal
- // value is larger, we will overflow and trigger this assert.
- assert(0 && "Integer Overflow in preprocessor expression");
- return true;
- }
- PP.LexNonComment(PeekTok);
- return false;
- } else {
- assert(Literal.isFloatingLiteral() && "Unknown ppnumber");
+
+ if (Literal.isFloatingLiteral()) {
PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
return true;
}
+
+ assert(Literal.isIntegerLiteral() && "Unknown ppnumber");
+ // FIXME: Handle overflow based on whether the value is signed. If signed
+ // and if the value is too large, emit a warning "integer constant is so
+ // large that it is unsigned" e.g. 12345678901234567890.
+ if (Literal.GetIntegerValue(Result))
+ PP.Diag(PeekTok, diag::warn_integer_too_large);
+ PP.LexNonComment(PeekTok);
+ return false;
}
case tok::l_paren:
PP.LexNonComment(PeekTok); // Eat the (.
@@ -278,7 +274,7 @@
/// EvaluateDirectiveSubExpr - Evaluate the subexpression whose first token is
/// PeekTok, and whose precedence is PeekPrec.
-static bool EvaluateDirectiveSubExpr(int &LHS, unsigned MinPrec,
+static bool EvaluateDirectiveSubExpr(APInt &LHS, unsigned MinPrec,
LexerToken &PeekTok, Preprocessor &PP) {
unsigned PeekPrec = getPrecedence(PeekTok.getKind());
// If this token isn't valid, report the error.
@@ -299,7 +295,7 @@
LexerToken OpToken = PeekTok;
PP.LexNonComment(PeekTok);
- int RHS;
+ APInt RHS(LHS.getBitWidth(), 0);
// Parse the RHS of the operator.
DefinedTracker DT;
if (EvaluateValue(RHS, PeekTok, DT, PP)) return true;
@@ -334,31 +330,53 @@
PP.Diag(OpToken, diag::err_pp_remainder_by_zero);
return true;
}
- LHS %= RHS;
+ // FIXME: sign.
+ LHS = LHS.urem(RHS);
break;
case tok::slash:
if (RHS == 0) {
PP.Diag(OpToken, diag::err_pp_division_by_zero);
return true;
}
- LHS /= RHS;
+ // FIXME: sign.
+ LHS = LHS.udiv(RHS);
break;
case tok::star : LHS *= RHS; break;
- case tok::lessless: LHS <<= RHS; break; // FIXME: shift amt overflow?
- case tok::greatergreater: LHS >>= RHS; break; // FIXME: signed vs unsigned
+ case tok::lessless:
+ // FIXME: shift amt overflow?
+ // FIXME: Don't use getZExtValue.
+ LHS = LHS << RHS.getZExtValue();
+ break;
+ case tok::greatergreater:
+ // FIXME: signed vs unsigned
+ // FIXME: Don't use getZExtValue.
+ LHS = LHS.ashr(RHS.getZExtValue());
+ break;
case tok::plus : LHS += RHS; break;
case tok::minus: LHS -= RHS; break;
- case tok::lessequal: LHS = LHS <= RHS; break;
- case tok::less: LHS = LHS < RHS; break;
- case tok::greaterequal: LHS = LHS >= RHS; break;
- case tok::greater: LHS = LHS > RHS; break;
+ case tok::lessequal:
+ // FIXME: signed vs unsigned
+ LHS = LHS.sle(RHS);
+ break;
+ case tok::less:
+ // FIXME: signed vs unsigned
+ LHS = LHS.slt(RHS);
+ break;
+ case tok::greaterequal:
+ // FIXME: signed vs unsigned
+ LHS = LHS.sge(RHS);
+ break;
+ case tok::greater:
+ // FIXME: signed vs unsigned
+ LHS = LHS.sgt(RHS);
+ break;
case tok::exclaimequal: LHS = LHS != RHS; break;
case tok::equalequal: LHS = LHS == RHS; break;
case tok::amp: LHS &= RHS; break;
case tok::caret: LHS ^= RHS; break;
case tok::pipe: LHS |= RHS; break;
- case tok::ampamp: LHS = LHS && RHS; break;
- case tok::pipepipe: LHS = LHS || RHS; break;
+ case tok::ampamp: LHS = LHS != 0 && RHS != 0; break;
+ case tok::pipepipe: LHS = LHS != 0 || RHS != 0; break;
case tok::comma:
PP.Diag(OpToken, diag::ext_pp_comma_expr);
LHS = RHS; // LHS = LHS,RHS -> RHS.
@@ -373,7 +391,7 @@
PP.LexNonComment(PeekTok);
// Evaluate the value after the :.
- int AfterColonVal = 0;
+ APInt AfterColonVal(LHS.getBitWidth(), 0);
DefinedTracker DT;
if (EvaluateValue(AfterColonVal, PeekTok, DT, PP)) return true;
@@ -383,7 +401,7 @@
return true;
// Now that we have the condition, the LHS and the RHS of the :, evaluate.
- LHS = LHS ? RHS : AfterColonVal;
+ LHS = LHS != 0 ? RHS : AfterColonVal;
// Figure out the precedence of the token after the : part.
PeekPrec = getPrecedence(PeekTok.getKind());
@@ -408,7 +426,9 @@
LexerToken Tok;
Lex(Tok);
- int ResVal = 0;
+ // C99 6.10.1p3 - All expressions are evaluated as intmax_t or uintmax_t.
+ unsigned BitWidth = getTargetInfo().getIntMaxTWidth(Tok.getLocation());
+ APInt ResVal(BitWidth, 0);
DefinedTracker DT;
if (EvaluateValue(ResVal, Tok, DT, *this)) {
// Parse error, skip the rest of the macro line.
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=39385&r1=39384&r2=39385&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:50 2007
@@ -480,6 +480,8 @@
"invalid suffix '%s' on integer constant")
DIAG(err_invalid_suffix_float_constant, ERROR,
"invalid suffix '%s' on floating constant")
+DIAG(warn_integer_too_large, WARNING,
+ "integer constant is too large for its type")
DIAG(err_exponent_has_no_digits, ERROR,
"exponent has no digits")
DIAG(err_hexconstant_requires_exponent, ERROR,
More information about the cfe-commits
mailing list