summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-05-31 05:41:42 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-05-31 05:41:42 +0000
commite54ff6cc3e479523b71e4c7eb4bd13707d84de0f (patch)
treec3508683d9859d5dfdc1b9ace8c2b4f334440225
parentb3483b3d91af65619471cdbf44563e5759eef4bc (diff)
downloadbcm5719-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.cpp14
-rw-r--r--clang/test/CodeGenCXX/static-init-2.cpp2
-rw-r--r--clang/test/Sema/exprs.c18
-rw-r--r--clang/test/SemaCXX/expressions.cpp31
-rw-r--r--clang/test/SemaCXX/switch.cpp2
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;
}
OpenPOWER on IntegriCloud