Skip to content

Commit a93ca35

Browse files
xguptatru
authored andcommitted
Revert "[Clang] Fix -Wconstant-logical-operand when LHS is a constant"
This reverts commit dfdfd30. An issue is reported for wrong warning, this has to be reconsidered. Differential Revision: https://reviews.llvm.org/D157352
1 parent 6bff1eb commit a93ca35

File tree

9 files changed

+43
-114
lines changed

9 files changed

+43
-114
lines changed

clang/include/clang/Sema/Sema.h

-2
Original file line numberDiff line numberDiff line change
@@ -12694,8 +12694,6 @@ class Sema final {
1269412694
QualType CheckBitwiseOperands( // C99 6.5.[10...12]
1269512695
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
1269612696
BinaryOperatorKind Opc);
12697-
void diagnoseLogicalInsteadOfBitwise(Expr *Op1, Expr *Op2, SourceLocation Loc,
12698-
BinaryOperatorKind Opc);
1269912697
QualType CheckLogicalOperands( // C99 6.5.[13,14]
1270012698
ExprResult &LHS, ExprResult &RHS, SourceLocation Loc,
1270112699
BinaryOperatorKind Opc);

clang/lib/Sema/SemaExpr.cpp

+37-58
Original file line numberDiff line numberDiff line change
@@ -13880,56 +13880,6 @@ inline QualType Sema::CheckBitwiseOperands(ExprResult &LHS, ExprResult &RHS,
1388013880
return InvalidOperands(Loc, LHS, RHS);
1388113881
}
1388213882

13883-
// Diagnose cases where the user write a logical and/or but probably meant a
13884-
// bitwise one. We do this when one of the operands is a non-bool integer and
13885-
// the other is a constant.
13886-
void Sema::diagnoseLogicalInsteadOfBitwise(Expr *Op1, Expr *Op2,
13887-
SourceLocation Loc,
13888-
BinaryOperatorKind Opc) {
13889-
if (Op1->getType()->isIntegerType() && !Op1->getType()->isBooleanType() &&
13890-
Op2->getType()->isIntegerType() && !Op2->isValueDependent() &&
13891-
// Don't warn in macros or template instantiations.
13892-
!Loc.isMacroID() && !inTemplateInstantiation() &&
13893-
!Op2->getExprLoc().isMacroID() &&
13894-
!Op1->getExprLoc().isMacroID()) {
13895-
bool IsOp1InMacro = Op1->getExprLoc().isMacroID();
13896-
bool IsOp2InMacro = Op2->getExprLoc().isMacroID();
13897-
13898-
// Exclude the specific expression from triggering the warning.
13899-
if (!(IsOp1InMacro && IsOp2InMacro && Op1->getSourceRange() == Op2->getSourceRange())) {
13900-
// If the RHS can be constant folded, and if it constant folds to something
13901-
// that isn't 0 or 1 (which indicate a potential logical operation that
13902-
// happened to fold to true/false) then warn.
13903-
// Parens on the RHS are ignored.
13904-
// If the RHS can be constant folded, and if it constant folds to something
13905-
// that isn't 0 or 1 (which indicate a potential logical operation that
13906-
// happened to fold to true/false) then warn.
13907-
// Parens on the RHS are ignored.
13908-
Expr::EvalResult EVResult;
13909-
if (Op2->EvaluateAsInt(EVResult, Context)) {
13910-
llvm::APSInt Result = EVResult.Val.getInt();
13911-
if ((getLangOpts().Bool && !Op2->getType()->isBooleanType() &&
13912-
!Op2->getExprLoc().isMacroID()) ||
13913-
(Result != 0 && Result != 1)) {
13914-
Diag(Loc, diag::warn_logical_instead_of_bitwise)
13915-
<< Op2->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
13916-
// Suggest replacing the logical operator with the bitwise version
13917-
Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
13918-
<< (Opc == BO_LAnd ? "&" : "|")
13919-
<< FixItHint::CreateReplacement(
13920-
SourceRange(Loc, getLocForEndOfToken(Loc)),
13921-
Opc == BO_LAnd ? "&" : "|");
13922-
if (Opc == BO_LAnd)
13923-
// Suggest replacing "Foo() && kNonZero" with "Foo()"
13924-
Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
13925-
<< FixItHint::CreateRemoval(SourceRange(
13926-
getLocForEndOfToken(Op1->getEndLoc()), Op2->getEndLoc()));
13927-
}
13928-
}
13929-
}
13930-
}
13931-
}
13932-
1393313883
// C99 6.5.[13,14]
1393413884
inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1393513885
SourceLocation Loc,
@@ -13948,6 +13898,9 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1394813898
}
1394913899
}
1395013900

13901+
if (EnumConstantInBoolContext)
13902+
Diag(Loc, diag::warn_enum_constant_in_bool_context);
13903+
1395113904
// WebAssembly tables can't be used with logical operators.
1395213905
QualType LHSTy = LHS.get()->getType();
1395313906
QualType RHSTy = RHS.get()->getType();
@@ -13958,14 +13911,40 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1395813911
return InvalidOperands(Loc, LHS, RHS);
1395913912
}
1396013913

13961-
if (EnumConstantInBoolContext) {
13962-
// Warn when converting the enum constant to a boolean
13963-
Diag(Loc, diag::warn_enum_constant_in_bool_context);
13964-
} else {
13965-
// Diagnose cases where the user write a logical and/or but probably meant a
13966-
// bitwise one.
13967-
diagnoseLogicalInsteadOfBitwise(LHS.get(), RHS.get(), Loc, Opc);
13968-
diagnoseLogicalInsteadOfBitwise(RHS.get(), LHS.get(), Loc, Opc);
13914+
// Diagnose cases where the user write a logical and/or but probably meant a
13915+
// bitwise one. We do this when the LHS is a non-bool integer and the RHS
13916+
// is a constant.
13917+
if (!EnumConstantInBoolContext && LHS.get()->getType()->isIntegerType() &&
13918+
!LHS.get()->getType()->isBooleanType() &&
13919+
RHS.get()->getType()->isIntegerType() && !RHS.get()->isValueDependent() &&
13920+
// Don't warn in macros or template instantiations.
13921+
!Loc.isMacroID() && !inTemplateInstantiation()) {
13922+
// If the RHS can be constant folded, and if it constant folds to something
13923+
// that isn't 0 or 1 (which indicate a potential logical operation that
13924+
// happened to fold to true/false) then warn.
13925+
// Parens on the RHS are ignored.
13926+
Expr::EvalResult EVResult;
13927+
if (RHS.get()->EvaluateAsInt(EVResult, Context)) {
13928+
llvm::APSInt Result = EVResult.Val.getInt();
13929+
if ((getLangOpts().Bool && !RHS.get()->getType()->isBooleanType() &&
13930+
!RHS.get()->getExprLoc().isMacroID()) ||
13931+
(Result != 0 && Result != 1)) {
13932+
Diag(Loc, diag::warn_logical_instead_of_bitwise)
13933+
<< RHS.get()->getSourceRange() << (Opc == BO_LAnd ? "&&" : "||");
13934+
// Suggest replacing the logical operator with the bitwise version
13935+
Diag(Loc, diag::note_logical_instead_of_bitwise_change_operator)
13936+
<< (Opc == BO_LAnd ? "&" : "|")
13937+
<< FixItHint::CreateReplacement(
13938+
SourceRange(Loc, getLocForEndOfToken(Loc)),
13939+
Opc == BO_LAnd ? "&" : "|");
13940+
if (Opc == BO_LAnd)
13941+
// Suggest replacing "Foo() && kNonZero" with "Foo()"
13942+
Diag(Loc, diag::note_logical_instead_of_bitwise_remove_constant)
13943+
<< FixItHint::CreateRemoval(
13944+
SourceRange(getLocForEndOfToken(LHS.get()->getEndLoc()),
13945+
RHS.get()->getEndLoc()));
13946+
}
13947+
}
1396913948
}
1397013949

1397113950
if (!Context.getLangOpts().CPlusPlus) {

clang/test/C/drs/dr4xx.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,7 @@ void dr489(void) {
308308
case (int){ 2 }: break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
309309
c89only-warning {{compound literals are a C99-specific feature}}
310310
*/
311-
case 12 || main(): break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}}
312-
expected-warning {{use of logical '||' with constant operand}} \
313-
expected-note {{use '|' for a bitwise operation}} */
311+
case 12 || main(): break; /* expected-warning {{expression is not an integer constant expression; folding it to a constant is a GNU extension}} */
314312
}
315313
}
316314

clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p5.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,9 @@ constexpr S InitList3(int a) { return a ? S{ a, a } : S{ a, ng }; }; // ok
7272

7373
constexpr int LogicalAnd1(int n) { return n && (throw, 0); } // ok
7474
constexpr int LogicalAnd2(int n) { return 1 && (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
75-
// expected-warning@-1 {{use of logical '&&' with constant operand}}
76-
// expected-note@-2 {{use '&' for a bitwise operation}}
77-
// expected-note@-3 {{remove constant to silence this warning}}
7875

7976
constexpr int LogicalOr1(int n) { return n || (throw, 0); } // ok
8077
constexpr int LogicalOr2(int n) { return 0 || (throw, 0); } // expected-error {{never produces}} expected-note {{subexpression}}
81-
// expected-warning@-1 {{use of logical '||' with constant operand}}
82-
// expected-note@-2 {{use '|' for a bitwise operation}}
83-
8478

8579
constexpr int Conditional1(bool b, int n) { return b ? n : ng; } // ok
8680
constexpr int Conditional2(bool b, int n) { return b ? n * ng : n + ng; } // expected-error {{never produces}} expected-note {{both arms of conditional operator are unable to produce a constant expression}}

clang/test/Parser/cxx2a-concept-declaration.cpp

-5
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ template<typename T> concept C16 = true && (0 && 0); // expected-error {{atomic
7979
// expected-warning@-1{{use of logical '&&' with constant operand}}
8080
// expected-note@-2{{use '&' for a bitwise operation}}
8181
// expected-note@-3{{remove constant to silence this warning}}
82-
// expected-warning@-4{{use of logical '&&' with constant operand}}
83-
// expected-note@-5{{use '&' for a bitwise operation}}
84-
// expected-note@-6{{remove constant to silence this warning}}
85-
86-
8782
template<typename T> concept C17 = T{};
8883
static_assert(!C17<bool>);
8984
template<typename T> concept C18 = (bool&&)true;

clang/test/Sema/exprs.c

-7
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,6 @@ int test20(int x) {
212212
// expected-note {{use '&' for a bitwise operation}} \
213213
// expected-note {{remove constant to silence this warning}}
214214

215-
return 4 && x; // expected-warning {{use of logical '&&' with constant operand}} \
216-
// expected-note {{use '&' for a bitwise operation}} \
217-
// expected-note {{remove constant to silence this warning}}
218-
219215
return x && sizeof(int) == 4; // no warning, RHS is logical op.
220216

221217
// no warning, this is an idiom for "true" in old C style.
@@ -227,9 +223,6 @@ int test20(int x) {
227223
// expected-note {{use '|' for a bitwise operation}}
228224
return x || 5; // expected-warning {{use of logical '||' with constant operand}} \
229225
// expected-note {{use '|' for a bitwise operation}}
230-
return 5 || x; // expected-warning {{use of logical '||' with constant operand}} \
231-
// expected-note {{use '|' for a bitwise operation}}
232-
233226
return x && 0;
234227
return x && 1;
235228
return x && -1; // expected-warning {{use of logical '&&' with constant operand}} \

clang/test/SemaCXX/expressions.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,6 @@ int test2(int x) {
4444
return x && 4; // expected-warning {{use of logical '&&' with constant operand}} \
4545
// expected-note {{use '&' for a bitwise operation}} \
4646
// expected-note {{remove constant to silence this warning}}
47-
return 4 && x; // expected-warning {{use of logical '&&' with constant operand}} \
48-
// expected-note {{use '&' for a bitwise operation}} \
49-
// expected-note {{remove constant to silence this warning}}
5047

5148
return x && sizeof(int) == 4; // no warning, RHS is logical op.
5249
return x && true;
@@ -69,8 +66,6 @@ int test2(int x) {
6966
// expected-note {{use '|' for a bitwise operation}}
7067
return x || 5; // expected-warning {{use of logical '||' with constant operand}} \
7168
// expected-note {{use '|' for a bitwise operation}}
72-
return 5 || x; // expected-warning {{use of logical '||' with constant operand}} \
73-
// expected-note {{use '|' for a bitwise operation}}
7469
return x && 0; // expected-warning {{use of logical '&&' with constant operand}} \
7570
// expected-note {{use '&' for a bitwise operation}} \
7671
// expected-note {{remove constant to silence this warning}}
@@ -144,5 +139,6 @@ void test4() {
144139
bool r1 = X || Y;
145140

146141
#define Y2 2
147-
bool r2 = X || Y2;
142+
bool r2 = X || Y2; // expected-warning {{use of logical '||' with constant operand}} \
143+
// expected-note {{use '|' for a bitwise operation}}
148144
}

clang/test/SemaCXX/warn-unsequenced.cpp

+2-24
Original file line numberDiff line numberDiff line change
@@ -76,37 +76,15 @@ void test() {
7676

7777
(xs[2] && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
7878
// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
79-
80-
(0 && (a = 0)) + a; // cxx11-warning {{use of logical '&&' with constant operand}}
81-
// cxx11-note@-1 {{use '&' for a bitwise operation}}
82-
// cxx11-note@-2 {{remove constant to silence this warning}}
83-
// cxx17-warning@-3 {{use of logical '&&' with constant operand}}
84-
// cxx17-note@-4 {{use '&' for a bitwise operation}}
85-
// cxx17-note@-5 {{remove constant to silence this warning}}
86-
79+
(0 && (a = 0)) + a; // ok
8780
(1 && (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
8881
// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
89-
// cxx11-warning@-2 {{use of logical '&&' with constant operand}}
90-
// cxx11-note@-3 {{use '&' for a bitwise operation}}
91-
// cxx11-note@-4 {{remove constant to silence this warning}}
92-
// cxx17-warning@-5 {{use of logical '&&' with constant operand}}
93-
// cxx17-note@-6 {{use '&' for a bitwise operation}}
94-
// cxx17-note@-7 {{remove constant to silence this warning}}
95-
9682

9783
(xs[3] || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
9884
// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
9985
(0 || (a = 0)) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
10086
// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}
101-
// cxx11-warning@-2 {{use of logical '||' with constant operand}}
102-
// cxx11-note@-3 {{use '|' for a bitwise operation}}
103-
// cxx17-warning@-4 {{use of logical '||' with constant operand}}
104-
// cxx17-note@-5 {{use '|' for a bitwise operation}}
105-
(1 || (a = 0)) + a; // cxx11-warning {{use of logical '||' with constant operand}}
106-
// cxx11-note@-1 {{use '|' for a bitwise operation}}
107-
// cxx17-warning@-2 {{use of logical '||' with constant operand}}
108-
// cxx17-note@-3 {{use '|' for a bitwise operation}}
109-
87+
(1 || (a = 0)) + a; // ok
11088

11189
(xs[4] ? a : ++a) + a; // cxx11-warning {{unsequenced modification and access to 'a'}}
11290
// cxx17-warning@-1 {{unsequenced modification and access to 'a'}}

clang/test/SemaTemplate/dependent-expr.cpp

+1-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ namespace PR7198 {
4343

4444
namespace PR7724 {
4545
template<typename OT> int myMethod()
46-
{ return 2 && sizeof(OT); } // expected-warning {{use of logical '&&' with constant operand}} \
47-
// expected-note {{use '&' for a bitwise operation}} \
48-
// expected-note {{remove constant to silence this warning}}
46+
{ return 2 && sizeof(OT); }
4947
}
5048

5149
namespace test4 {

0 commit comments

Comments
 (0)