mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 20:56:06 +00:00

When using the && operator within a || operator, both Clang and GCC produce a warning for potentially confusing operator precedence. However, Clang avoids this warning for certain patterns, such as a && b || 0 or a || b && 1, where the operator precedence of && and || does not change the result. However, this behavior appears inconsistent when using the const or constexpr qualifiers. For example: bool t = true; bool tt = true || false && t; // Warning: '&&' within '||' const bool t = true; bool tt = true || false && t; // No warning const bool t = false; bool tt = true || false && t; // Warning: '&&' within '||' The second example does not produce a warning because true || false && t matches the a || b && 1 pattern, while the third one does not match any of them. This behavior can lead to the lack of warnings for complicated constexpr expressions. Clang should only suppress this warning when literal values are placed in the place of t in the examples above. This patch adds the literal-or-not check to fix the inconsistent warnings for && within || when using const or constexpr.
102 lines
3.9 KiB
C
102 lines
3.9 KiB
C
// RUN: %clang_cc1 -fsyntax-only -verify %s -DSILENCE
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wlogical-op-parentheses
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s -Wparentheses
|
|
// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s -Wlogical-op-parentheses 2>&1 | FileCheck %s
|
|
|
|
#ifdef SILENCE
|
|
// expected-no-diagnostics
|
|
#endif
|
|
|
|
void logical_op_parentheses(unsigned i) {
|
|
const unsigned t = 1;
|
|
(void)(i ||
|
|
i && i);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:20-[[@LINE-6]]:20}:")"
|
|
|
|
(void)(t ||
|
|
t && t);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:14-[[@LINE-5]]:14}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:20-[[@LINE-6]]:20}:")"
|
|
|
|
(void)(t &&
|
|
t || t);
|
|
#ifndef SILENCE
|
|
// expected-warning@-3 {{'&&' within '||'}}
|
|
// expected-note@-4 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:10-[[@LINE-6]]:10}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:15-[[@LINE-6]]:15}:")"
|
|
|
|
(void)(i || i && "w00t");
|
|
(void)("w00t" && i || i);
|
|
(void)("w00t" && t || t);
|
|
(void)(t && t || 0);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:")"
|
|
(void)(1 && t || t);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:")"
|
|
(void)(0 || t && t);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
|
|
(void)(t || t && 1);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
|
|
|
|
(void)(i || i && "w00t" || i);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:26-[[@LINE-6]]:26}:")"
|
|
|
|
(void)(i || "w00t" && i || i);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:26-[[@LINE-6]]:26}:")"
|
|
|
|
(void)(i && i || 0);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:10-[[@LINE-5]]:10}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:16-[[@LINE-6]]:16}:")"
|
|
(void)(0 || i && i);
|
|
#ifndef SILENCE
|
|
// expected-warning@-2 {{'&&' within '||'}}
|
|
// expected-note@-3 {{place parentheses around the '&&' expression to silence this warning}}
|
|
#endif
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-5]]:15-[[@LINE-5]]:15}:"("
|
|
// CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:21-[[@LINE-6]]:21}:")"
|
|
}
|