From 9b127f3b44e685cbe513595b7e0115b0884b0604 Mon Sep 17 00:00:00 2001 From: Matt Beaumont-Gay Date: Mon, 15 Aug 2011 17:50:06 +0000 Subject: [PATCH] Add fixit notes for -Wconstant-logical-operand. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137620 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 8 ++- lib/Sema/SemaExpr.cpp | 21 +++++- test/Sema/exprs.c | 32 ++++++--- test/Sema/i-c-e.c | 3 +- test/SemaCXX/bool.cpp | 7 +- test/SemaCXX/expressions.cpp | 75 ++++++++++++++++------ 6 files changed, 108 insertions(+), 38 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 88d6e784c6..2430372c3d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2940,8 +2940,12 @@ def note_precedence_conditional_silence : Note< "place parentheses around the '%0' expression to silence this warning">; def warn_logical_instead_of_bitwise : Warning< - "use of logical %0 with constant operand; switch to bitwise %1 or " - "remove constant">, InGroup>; + "use of logical '%0' with constant operand">, + InGroup>; +def note_logical_instead_of_bitwise_change_operator : Note< + "use '%0' for a bitwise operation">; +def note_logical_instead_of_bitwise_remove_constant : Note< + "remove constant to silence this warning">; def warn_bitwise_and_in_bitwise_or : Warning< "'&' within '|'">, InGroup; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index efc05de90e..20d129da99 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6719,9 +6719,24 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] (Result.Val.getInt() != 0 && Result.Val.getInt() != 1)) { Diag(Loc, diag::warn_logical_instead_of_bitwise) << rex.get()->getSourceRange() - << (Opc == BO_LAnd ? "&&" : "||") - << (Opc == BO_LAnd ? "&" : "|"); - } + << (Opc == BO_LAnd ? "&&" : "||"); + // Suggest replacing the logical operator with the bitwise version + Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator) + << (Opc == BO_LAnd ? "&" : "|") + << FixItHint::CreateReplacement(SourceRange( + Loc, Lexer::getLocForEndOfToken(Loc, 0, getSourceManager(), + getLangOptions())), + Opc == BO_LAnd ? "&" : "|"); + if (Opc == BO_LAnd) + // Suggest replacing "Foo() && kNonZero" with "Foo()" + Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant) + << FixItHint::CreateRemoval( + SourceRange( + Lexer::getLocForEndOfToken(lex.get()->getLocEnd(), + 0, getSourceManager(), + getLangOptions()), + rex.get()->getLocEnd())); + } } if (!Context.getLangOptions().CPlusPlus) { diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index 460f72cb17..72cff65f48 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -183,7 +183,9 @@ void test19() { } int test20(int x) { - return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x && 4; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} return x && sizeof(int) == 4; // no warning, RHS is logical op. @@ -192,20 +194,32 @@ int test20(int x) { return x || 0; return x || 1; - return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} + return x || -1; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || 5; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} return x && 0; return x && 1; - return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x && -1; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && 5; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} return x || (0); return x || (1); - return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} + return x || (-1); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || (5); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} return x && (0); return x && (1); - return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x && (-1); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && (5); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} } diff --git a/test/Sema/i-c-e.c b/test/Sema/i-c-e.c index 1aac51e204..9b50916f85 100644 --- a/test/Sema/i-c-e.c +++ b/test/Sema/i-c-e.c @@ -53,7 +53,8 @@ char z[__builtin_constant_p(4) ? 1 : -1]; // Comma tests int comma1[0?1,2:3]; // expected-warning {{expression result unused}} int comma2[1||(1,2)]; // expected-warning {{expression result unused}} \ - // expected-warning {{use of logical || with constant operand}} + // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} int comma3[(1,2)]; // expected-warning {{size of static array must be an integer constant expression}} \ // expected-warning {{expression result unused}} diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp index 726fa6cb60..2b3ab68848 100644 --- a/test/SemaCXX/bool.cpp +++ b/test/SemaCXX/bool.cpp @@ -25,6 +25,9 @@ void static_assert_arg_is_bool(T x) { void test2() { int n = 2; - static_assert_arg_is_bool(n && 4); // expected-warning {{use of logical && with constant operand}} - static_assert_arg_is_bool(n || 5); // expected-warning {{use of logical || with constant operand}} + static_assert_arg_is_bool(n && 4); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + static_assert_arg_is_bool(n || 5); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} } diff --git a/test/SemaCXX/expressions.cpp b/test/SemaCXX/expressions.cpp index 8a294face3..355833e693 100644 --- a/test/SemaCXX/expressions.cpp +++ b/test/SemaCXX/expressions.cpp @@ -34,7 +34,9 @@ namespace test1 { } int test2(int x) { - return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x && 4; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} return x && sizeof(int) == 4; // no warning, RHS is logical op. return x && true; @@ -42,38 +44,69 @@ int test2(int x) { return x || true; return x || false; - return x && (unsigned)0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x && (unsigned)0; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} - return x || (unsigned)1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} + return x || (unsigned)1; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} - return x || 0; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || 1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || -1; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || 5; // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x && 0; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && 1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && -1; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && 5; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x || (0); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || (1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || (-1); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x || (5); // expected-warning {{use of logical || with constant operand; switch to bitwise | or remove constant}} - return x && (0); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && (1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && (-1); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} - return x && (5); // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + return x || 0; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || 1; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || -1; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || 5; // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x && 0; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && 1; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && -1; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && 5; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x || (0); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || (1); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || (-1); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x || (5); // expected-warning {{use of logical '||' with constant operand}} \ + // expected-note {{use '|' for a bitwise operation}} + return x && (0); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && (1); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && (-1); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} + return x && (5); // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} } template struct S { enum { e1 = A && B, - e2 = A && 7 // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + e2 = A && 7 // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} }; int foo() { int x = A && B; - int y = B && 3; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + int y = B && 3; // expected-warning {{use of logical '&&' with constant operand}} \ + // expected-note {{use '&' for a bitwise operation}} \ + // expected-note {{remove constant to silence this warning}} return x + y; } -- 2.40.0