From: Ted Kremenek Date: Wed, 15 Jun 2011 00:54:52 +0000 (+0000) Subject: Sema: show shift result in hexadecimal X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa821380182f00eddfa536280b5a103c59e5c1c4;p=clang Sema: show shift result in hexadecimal Change the output for -Wshift-overflow and -Wshift-sign-overflow to an unsigned hexadecimal. It makes more sense for looking at bits than a signed decimal does. Also, change the diagnostic's wording from "overrides" to "sets". This uses a new optional argument in APInt::toString() that adds the '0x' prefix to hexademical numbers. This fixes PR 9651. Patch by nobled@dreamwidth.org! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133033 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6e851091d4..985f3e4443 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2566,11 +2566,11 @@ def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; def warn_shift_negative : Warning<"shift count is negative">; def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; def warn_shift_result_gt_typewidth : Warning< - "shift result (%0) requires %1 bits to represent, but %2 only has %3 bits">, - InGroup>; -def warn_shift_result_overrides_sign_bit : Warning< - "shift result (%0) overrides the sign bit of the shift expression's type " - "(%1) and becomes negative">, + "signed shift result (%0) requires %1 bits to represent, but %2 only has " + "%3 bits">, InGroup>; +def warn_shift_result_sets_sign_bit : Warning< + "signed shift result (%0) sets the sign bit of the shift expression's " + "type (%1) and becomes negative">, InGroup>, DefaultIgnore; def warn_precedence_bitwise_rel : Warning< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 91821fb4d8..9f9c05244e 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -7394,19 +7394,24 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &lex, ExprResult &rex, llvm::APSInt Result = Left.extend(ResultBits.getLimitedValue()); Result = Result.shl(Right); + // Print the bit representation of the signed integer as an unsigned + // hexadecimal number. + llvm::SmallString<40> HexResult; + Result.toString(HexResult, 16, /*Signed =*/false, /*Literal =*/true); + // If we are only missing a sign bit, this is less likely to result in actual // bugs -- if the result is cast back to an unsigned type, it will have the // expected value. Thus we place this behind a different warning that can be // turned off separately if needed. if (LeftBits == ResultBits - 1) { - S.Diag(Loc, diag::warn_shift_result_overrides_sign_bit) - << Result.toString(10) << LHSTy + S.Diag(Loc, diag::warn_shift_result_sets_sign_bit) + << HexResult.str() << LHSTy << lex.get()->getSourceRange() << rex.get()->getSourceRange(); return; } S.Diag(Loc, diag::warn_shift_result_gt_typewidth) - << Result.toString(10) << Result.getMinSignedBits() << LHSTy + << HexResult.str() << Result.getMinSignedBits() << LHSTy << Left.getBitWidth() << lex.get()->getSourceRange() << rex.get()->getSourceRange(); } diff --git a/test/Sema/shift.c b/test/Sema/shift.c index 28407be079..142d83c43d 100644 --- a/test/Sema/shift.c +++ b/test/Sema/shift.c @@ -38,7 +38,7 @@ void test() { int i; i = 1 << (WORD_BIT - 2); i = 2 << (WORD_BIT - 1); // expected-warning {{bits to represent, but 'int' only has}} - i = 1 << (WORD_BIT - 1); // expected-warning {{overrides the sign bit of the shift expression}} + i = 1 << (WORD_BIT - 1); // expected-warning {{sets the sign bit of the shift expression}} i = -1 << (WORD_BIT - 1); i = 0 << (WORD_BIT - 1); i = (char)1 << (WORD_BIT - 2);