Warn when performing 'usual' conversions that require a sign change. This

implements test/Preprocessor/expr_usual_conversions.c, which produces this
output:

expr_usual_conversions.c:5:10: warning: left side of operator converted from negative value to unsigned: -42 to 18446744073709551574
#if (-42 + 0U) / -2
         ^
expr_usual_conversions.c:5:16: warning: right side of operator converted from negative value to unsigned: -2 to 18446744073709551614
#if (-42 + 0U) / -2
               ^

llvm-svn: 39406
This commit is contained in:
Chris Lattner 2007-04-11 04:14:45 +00:00
parent 8ec9355a48
commit 99ca091b9c
3 changed files with 25 additions and 3 deletions

View File

@ -430,9 +430,19 @@ static bool EvaluateDirectiveSubExpr(APSInt &LHS, unsigned MinPrec,
// either operand is unsigned. Don't do this for x and y in "x ? y : z".
APSInt Res(LHS.getBitWidth());
if (Operator != tok::question) {
if (RHS.isUnsigned()) LHS.setIsUnsigned(true);
RHS.setIsUnsigned(LHS.isUnsigned());
Res.setIsUnsigned(LHS.isUnsigned());
Res.setIsUnsigned(LHS.isUnsigned()|RHS.isUnsigned());
// If this just promoted something from signed to unsigned, and if the
// value was negative, warn about it.
if (ValueLive && Res.isUnsigned()) {
if (!LHS.isUnsigned() && LHS.isNegative())
PP.Diag(OpToken, diag::warn_pp_convert_lhs_to_positive,
LHS.toString(10, true) + " to " + LHS.toString(10, false));
if (!RHS.isUnsigned() && RHS.isNegative())
PP.Diag(OpToken, diag::warn_pp_convert_rhs_to_positive,
RHS.toString(10, true) + " to " + RHS.toString(10, false));
}
LHS.setIsUnsigned(Res.isUnsigned());
RHS.setIsUnsigned(Res.isUnsigned());
}
// FIXME: All of these should detect and report overflow??

View File

@ -116,6 +116,10 @@ DIAG(pp_invalid_string_literal, WARNING,
"invalid string literal, ignoring final '\\'")
DIAG(warn_pp_expr_overflow, WARNING,
"integer overflow in preprocessor expression")
DIAG(warn_pp_convert_lhs_to_positive, WARNING,
"left side of operator converted from negative value to unsigned: %s")
DIAG(warn_pp_convert_rhs_to_positive, WARNING,
"right side of operator converted from negative value to unsigned: %s")
DIAG(ext_pp_import_directive, EXTENSION,
"#import is a language extension")

View File

@ -0,0 +1,8 @@
// RUN: clang %s -E 2>&1 | grep warning | wc -l | grep 2
#define INTMAX_MIN (-9223372036854775807LL -1)
#if (-42 + 0U) / -2
foo
#endif