aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-06-15 00:54:52 +0000
committerTed Kremenek <kremenek@apple.com>2011-06-15 00:54:52 +0000
commitfa821380182f00eddfa536280b5a103c59e5c1c4 (patch)
tree65f12f40281156d8e9c162498bf579894d9aff85
parent741be6a49f7a892ef8de6d8a499fdf45a7d57654 (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td10
-rw-r--r--lib/Sema/SemaExpr.cpp11
-rw-r--r--test/Sema/shift.c2
3 files changed, 14 insertions, 9 deletions
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<DiagGroup<"shift-overflow">>;
-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<DiagGroup<"shift-overflow">>;
+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<DiagGroup<"shift-sign-overflow">>, 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);