Skip to content

Commit b732e14

Browse files
authored
[Clang] Default the warning for chained comparison to an error. (#128145)
Boolean constructs of the form `a < b < c` never express the likely intent of the user and we have been warning on them since clang 19. WG21 is likely to deprecate or make that construct in the future. To gain more experience and to improve safety, this patches preempt future language evolution by turning warn_consecutive_comparison in an error, by default (which can be disabled with `-Wno-error=parentheses`)
1 parent bff6b92 commit b732e14

File tree

10 files changed

+15
-14
lines changed

10 files changed

+15
-14
lines changed

clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %check_clang_tidy %s bugprone-chained-comparison %t
1+
// RUN: %check_clang_tidy --extra-arg=-Wno-error=parentheses %s bugprone-chained-comparison %t
22

33
void badly_chained_1(int x, int y, int z)
44
{

clang-tools-extra/test/clang-tidy/checkers/bugprone/chained-comparison.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %check_clang_tidy -std=c++98-or-later %s bugprone-chained-comparison %t
1+
// RUN: %check_clang_tidy -std=c++98-or-later --extra-arg=-Wno-error=parentheses %s bugprone-chained-comparison %t
22

33
void badly_chained_1(int x, int y, int z)
44
{

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ Improvements to Clang's diagnostics
147147
- The ``-Wunsafe-buffer-usage`` warning has been updated to warn
148148
about unsafe libc function calls. Those new warnings are emitted
149149
under the subgroup ``-Wunsafe-buffer-usage-in-libc-call``.
150+
- Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with
151+
``-Wno-error=parentheses``.
150152

151153
Improvements to Clang's time-trace
152154
----------------------------------

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7126,7 +7126,7 @@ def note_precedence_conditional_first : Note<
71267126

71277127
def warn_consecutive_comparison : Warning<
71287128
"comparisons like 'X<=Y<=Z' don't have their mathematical meaning">,
7129-
InGroup<Parentheses>;
7129+
InGroup<Parentheses>, DefaultError;
71307130

71317131
def warn_enum_constant_in_bool_context : Warning<
71327132
"converting the enum constant to a boolean">,

clang/test/Sema/bool-compare.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void f(int x, int y, int z) {
8585
if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}}
8686

8787
if ((a<y) == z) {} // no warning
88-
if (a>y<z) {} // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
88+
if (a>y<z) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
8989
if ((a<y) > z) {} // no warning
9090
if((a<y)>(z<y)) {} // no warning
9191
if((a<y)==(z<y)){} // no warning
@@ -145,7 +145,7 @@ void f(int x, int y, int z) {
145145
if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
146146

147147
if (z ==(a<y)) {} // no warning
148-
if (z<a>y) {} // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
148+
if (z<a>y) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
149149
if (z > (a<y)) {} // no warning
150150
if((z<y)>(a<y)) {} // no warning
151151
if((z<y)==(a<y)){} // no warning

clang/test/Sema/parentheses.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -Wparentheses -fsyntax-only -verify %s
2-
// RUN: %clang_cc1 -Wparentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
1+
// RUN: %clang_cc1 -Wno-error=parentheses -fsyntax-only -verify %s
2+
// RUN: %clang_cc1 -Wno-error=parentheses -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
33

44
bool someConditionFunc();
55

clang/test/SemaCXX/bool-compare.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ void f(int x, int y, int z) {
9898
if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
9999

100100
if ((a<y) == z) {} // no warning
101-
if (a>y<z) {} // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
101+
if (a>y<z) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
102102
if ((a<y) > z) {} // no warning
103103
if((a<y)>(z<y)) {} // no warning
104104
if((a<y)==(z<y)){} // no warning
@@ -159,7 +159,7 @@ void f(int x, int y, int z) {
159159
if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
160160

161161
if (z ==(a<y)) {} // no warning
162-
if (z<a>y) {} // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
162+
if (z<a>y) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
163163
if (z > (a<y)) {} // no warning
164164
if((z<y)>(a<y)) {} // no warning
165165
if((z<y)==(a<y)){} // no warning
@@ -186,8 +186,7 @@ template<typename T, typename U, typename V> struct X6 {
186186
return v; // expected-error{{cannot initialize return object of type}}
187187
}
188188
bool r;
189-
// FIXME: We should warn here, DiagRuntimeBehavior does currently not detect this.
190-
if(r<0){}
189+
if(r<0){} // expected-warning {{result of comparison of constant 0 with expression of type 'bool' is always false}}
191190

192191
if (T x = t) {
193192
t = x;

clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int e = h<0>(q); // ok, found by unqualified lookup
2727
void fn() {
2828
f<0>(q);
2929
int f;
30-
f<0>(q); // expected-error {{invalid operands to binary expression}} // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
30+
f<0>(q); // expected-error {{invalid operands to binary expression}} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
3131
}
3232

3333
void disambig() {

clang/test/SemaTemplate/typo-dependent-name.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct X : Base<T> {
2020
bool f(T other) {
2121
// A pair of comparisons; 'inner' is a dependent name so can't be assumed
2222
// to be a template.
23-
return this->inner < other > ::z; // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
23+
return this->inner < other > ::z; // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
2424
}
2525
};
2626

clang/test/SemaTemplate/typo-template-name.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ namespace InExpr {
3636

3737
// These are valid expressions.
3838
foo<foo; // expected-warning {{self-comparison}}
39-
foo<int()>(0); // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
39+
foo<int()>(0); // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
4040
foo<int(), true>(false);
4141
foo<Base{}.n;
4242
}

0 commit comments

Comments
 (0)