diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2011-05-31 05:41:42 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2011-05-31 05:41:42 +0000 |
commit | e54ff6cc3e479523b71e4c7eb4bd13707d84de0f (patch) | |
tree | c3508683d9859d5dfdc1b9ace8c2b4f334440225 | |
parent | b3483b3d91af65619471cdbf44563e5759eef4bc (diff) | |
download | bcm5719-llvm-e54ff6cc3e479523b71e4c7eb4bd13707d84de0f.tar.gz bcm5719-llvm-e54ff6cc3e479523b71e4c7eb4bd13707d84de0f.zip |
Expand the coverage of the warning for constants on the RHS of logical operands:
return f() || -1;
where the user meant to write '|'.
This bootstraps without any additional warnings.
Patch by Richard Trieu.
llvm-svn: 132327
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 14 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/static-init-2.cpp | 2 | ||||
-rw-r--r-- | clang/test/Sema/exprs.c | 18 | ||||
-rw-r--r-- | clang/test/SemaCXX/expressions.cpp | 31 | ||||
-rw-r--r-- | clang/test/SemaCXX/switch.cpp | 2 |
5 files changed, 59 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 0a74daa008d..e75af910bda 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7797,13 +7797,15 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14] // If the RHS can be constant folded, and if it constant folds to something // that isn't 0 or 1 (which indicate a potential logical operation that // happened to fold to true/false) then warn. + // Parens on the RHS are ignored. Expr::EvalResult Result; - if (rex.get()->Evaluate(Result, Context) && !Result.HasSideEffects && - 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 ? "&" : "|"); + if (rex.get()->Evaluate(Result, Context) && !Result.HasSideEffects) + if ((getLangOptions().Bool && !rex.get()->getType()->isBooleanType()) || + (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 ? "&" : "|"); } } diff --git a/clang/test/CodeGenCXX/static-init-2.cpp b/clang/test/CodeGenCXX/static-init-2.cpp index 65ab3bb1262..768e6de92c0 100644 --- a/clang/test/CodeGenCXX/static-init-2.cpp +++ b/clang/test/CodeGenCXX/static-init-2.cpp @@ -3,4 +3,4 @@ // Make sure we don't crash generating y; its value is constant, but the // initializer has side effects, so EmitConstantExpr should fail. int x(); -int y = x() && 0; +int y = x() & 0; diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c index e4eeaec05d9..9ce1481f16c 100644 --- a/clang/test/Sema/exprs.c +++ b/clang/test/Sema/exprs.c @@ -189,6 +189,24 @@ int test20(int x) { // no warning, this is an idiom for "true" in old C style. return x && (signed char)1; + + 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 && 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 || (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 && (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}} + } struct Test21; // expected-note 2 {{forward declaration}} diff --git a/clang/test/SemaCXX/expressions.cpp b/clang/test/SemaCXX/expressions.cpp index c4e9dccbf62..95ece48e51f 100644 --- a/clang/test/SemaCXX/expressions.cpp +++ b/clang/test/SemaCXX/expressions.cpp @@ -32,3 +32,34 @@ namespace test1 { bar(x += E_zero); // expected-error {{incompatible type}} } } + +int test2(int x) { + return x && 4; // expected-warning {{use of logical && with constant operand; switch to bitwise & or remove constant}} + + return x && sizeof(int) == 4; // no warning, RHS is logical op. + return x && true; + return x && false; + 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)1; // 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; 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}} +} diff --git a/clang/test/SemaCXX/switch.cpp b/clang/test/SemaCXX/switch.cpp index 3882a1f952c..8a8cf33049d 100644 --- a/clang/test/SemaCXX/switch.cpp +++ b/clang/test/SemaCXX/switch.cpp @@ -8,7 +8,7 @@ void test() { } int n = 3; - switch (n && 1) { // expected-warning {{bool}} + switch (n && true) { // expected-warning {{bool}} case 1: break; } |