-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Clang][diagnostics] Improve the diagnostics for chained comparisons #129285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) ChangesImprove the diagnostics for chained comparisons to report actual expressions and operators Fixes #129069 Full diff: https://github.com/llvm/llvm-project/pull/129285.diff 9 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2b72143482943..a98200f9e931a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -214,6 +214,8 @@ Improvements to Clang's diagnostics
:doc:`ThreadSafetyAnalysis` still does not perform alias analysis. The
feature will be default-enabled with ``-Wthread-safety`` in a future release.
+- Improve the diagnostics for chained comparisons to report actual expressions and operators.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d094c075ecee2..b247a4a6e6dfe 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7157,7 +7157,7 @@ def note_precedence_conditional_first : Note<
"place parentheses around the '?:' expression to evaluate it first">;
def warn_consecutive_comparison : Warning<
- "comparisons like 'X<=Y<=Z' don't have their mathematical meaning">,
+ "comparisons like '%0 %1 %2' don't have their mathematical meaning">,
InGroup<Parentheses>, DefaultError;
def warn_enum_constant_in_bool_context : Warning<
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 1738663327453..e417fc669314d 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14924,7 +14924,8 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
if (const auto *BI = dyn_cast<BinaryOperator>(LHSExpr);
BI && BI->isComparisonOp())
- Diag(OpLoc, diag::warn_consecutive_comparison);
+ Diag(OpLoc, diag::warn_consecutive_comparison)
+ << LHS.get() << BinaryOperator::getOpcodeStr(Opc) << RHS.get();
break;
case BO_EQ:
diff --git a/clang/test/Sema/bool-compare.c b/clang/test/Sema/bool-compare.c
index 861f47864ddd9..4949da1cb501f 100644
--- a/clang/test/Sema/bool-compare.c
+++ b/clang/test/Sema/bool-compare.c
@@ -85,7 +85,7 @@ void f(int x, int y, int z) {
if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}}
if ((a<y) == z) {} // no warning
- if (a>y<z) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ if (a>y<z) {} // expected-error {{comparisons like 'a > y < z' don't have their mathematical meaning}}
if ((a<y) > z) {} // no warning
if((a<y)>(z<y)) {} // no warning
if((a<y)==(z<y)){} // no warning
@@ -145,7 +145,7 @@ void f(int x, int y, int z) {
if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with boolean expression is always true}}
if (z ==(a<y)) {} // no warning
- if (z<a>y) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ if (z<a>y) {} // expected-error {{comparisons like 'z < a > y' don't have their mathematical meaning}}
if (z > (a<y)) {} // no warning
if((z<y)>(a<y)) {} // no warning
if((z<y)==(a<y)){} // no warning
diff --git a/clang/test/Sema/parentheses.cpp b/clang/test/Sema/parentheses.cpp
index 5424704ea01d5..beb10a4c281ab 100644
--- a/clang/test/Sema/parentheses.cpp
+++ b/clang/test/Sema/parentheses.cpp
@@ -217,10 +217,10 @@ namespace PR20735 {
}
void consecutive_builtin_compare(int x, int y, int z) {
- (void)(x < y < z); // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
- (void)(x < y > z); // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
- (void)(x < y <= z); // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
- (void)(x <= y > z); // expected-warning {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ (void)(x < y < z); // expected-warning {{comparisons like 'x < y < z' don't have their mathematical meaning}}
+ (void)(x < y > z); // expected-warning {{comparisons like 'x < y > z' don't have their mathematical meaning}}
+ (void)(x < y <= z); // expected-warning {{comparisons like 'x < y <= z' don't have their mathematical meaning}}
+ (void)(x <= y > z); // expected-warning {{comparisons like 'x <= y > z' don't have their mathematical meaning}}
(void)((x < y) < z); // no-warning
(void)((x < y) >= z); // no-warning
diff --git a/clang/test/SemaCXX/bool-compare.cpp b/clang/test/SemaCXX/bool-compare.cpp
index 077d55ff9367d..0de8b3a994508 100644
--- a/clang/test/SemaCXX/bool-compare.cpp
+++ b/clang/test/SemaCXX/bool-compare.cpp
@@ -98,7 +98,7 @@ void f(int x, int y, int z) {
if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
if ((a<y) == z) {} // no warning
- if (a>y<z) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ if (a>y<z) {} // expected-error {{comparisons like 'a > y < z' don't have their mathematical meaning}}
if ((a<y) > z) {} // no warning
if((a<y)>(z<y)) {} // no warning
if((a<y)==(z<y)){} // no warning
@@ -159,7 +159,7 @@ void f(int x, int y, int z) {
if (-1 !=(a<y)) {} // expected-warning {{comparison of constant -1 with expression of type 'bool' is always true}}
if (z ==(a<y)) {} // no warning
- if (z<a>y) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ if (z<a>y) {} // expected-error {{comparisons like 'z < a > y' don't have their mathematical meaning}}
if (z > (a<y)) {} // no warning
if((z<y)>(a<y)) {} // no warning
if((z<y)==(a<y)){} // no warning
diff --git a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
index fb840e1036707..3b7ea10cdf922 100644
--- a/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
+++ b/clang/test/SemaCXX/cxx2a-adl-only-template-id.cpp
@@ -27,7 +27,7 @@ int e = h<0>(q); // ok, found by unqualified lookup
void fn() {
f<0>(q);
int f;
- f<0>(q); // expected-error {{invalid operands to binary expression}} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ f<0>(q); // expected-error {{invalid operands to binary expression}} // expected-error {{comparisons like 'f < 0 > (q)' don't have their mathematical meaning}}
}
void disambig() {
diff --git a/clang/test/SemaTemplate/typo-dependent-name.cpp b/clang/test/SemaTemplate/typo-dependent-name.cpp
index 1812525ec5d7b..3d94245af8388 100644
--- a/clang/test/SemaTemplate/typo-dependent-name.cpp
+++ b/clang/test/SemaTemplate/typo-dependent-name.cpp
@@ -20,7 +20,7 @@ struct X : Base<T> {
bool f(T other) {
// A pair of comparisons; 'inner' is a dependent name so can't be assumed
// to be a template.
- return this->inner < other > ::z; // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ return this->inner < other > ::z; // expected-error {{comparisons like 'this->inner < other > ::z' don't have their mathematical meaning}}
}
};
diff --git a/clang/test/SemaTemplate/typo-template-name.cpp b/clang/test/SemaTemplate/typo-template-name.cpp
index c1d8aa7c8e27d..d03649736ee24 100644
--- a/clang/test/SemaTemplate/typo-template-name.cpp
+++ b/clang/test/SemaTemplate/typo-template-name.cpp
@@ -36,7 +36,7 @@ namespace InExpr {
// These are valid expressions.
foo<foo; // expected-warning {{self-comparison}}
- foo<int()>(0); // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}}
+ foo<int()>(0); // expected-error {{comparisons like 'foo < int() > (0)' don't have their mathematical meaning}}
foo<int(), true>(false);
foo<Base{}.n;
}
|
clang/test/Sema/bool-compare.c
Outdated
@@ -85,7 +85,7 @@ void f(int x, int y, int z) { | |||
if ((a<y) != -1) {}// expected-warning {{comparison of constant -1 with boolean expression is always true}} | |||
|
|||
if ((a<y) == z) {} // no warning | |||
if (a>y<z) {} // expected-error {{comparisons like 'X<=Y<=Z' don't have their mathematical meaning}} | |||
if (a>y<z) {} // expected-error {{comparisons like 'a > y < z' don't have their mathematical meaning}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.... @AaronBallman will probably have to comment here, but I'm not sure this is better? The point of comparisons like
here was to simplify the diagnostics to something that is like
what is there, but not actually.
This patch ends up giving us really awful warning/diagnostics in the case where these are more than simple variables, as its just dumping the entire expression. So I don't know if I like this patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes i think the word like
should be removed here, but I am thinking should we prefer the previous diagnostics or the one with actual expression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the one with the actual expression in it, as that is going to get arbitrarily large. That said, I DO wonder if there is value in using the actual operators instead of just <=
for both sides (so not printing the expression, just the operators, and still X
, Y
, Z
). That would require keeping like
though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I got your point also it will not be great with large expressions :D, I am thinking should we change the message to be different or just the old one with actual operators 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like making it so it prints the actual operators is simple enough to where we can just do that. I agree that we probably don’t want to print the entire expression because that can get rather messy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Further thought: I haven't seen the 'change' you're proposing to the message, but am willing to keep an open mind. But I also think just changing to the actual operators is a distinct improvement.
…to report actual expressions and operators
66cd32d
to
99197b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM once @erichkeane is happy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on this! I think we can make the diagnostic message a bit more clear while we're at it, WDYT?
@@ -7157,7 +7157,7 @@ def note_precedence_conditional_first : Note< | |||
"place parentheses around the '?:' expression to evaluate it first">; | |||
|
|||
def warn_consecutive_comparison : Warning< | |||
"comparisons like 'X<=Y<=Z' don't have their mathematical meaning">, | |||
"comparisons like 'X %0 Y %1 Z' don't have their mathematical meaning">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"comparisons like 'X %0 Y %1 Z' don't have their mathematical meaning">, | |
"chained comparison 'X %0 Y %1 Z' does not behave the same as a mathematical expression">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…lvm#129285) Improve the diagnostics for chained comparisons to report actual expressions and operators Fixes llvm#129069
Improve the diagnostics for chained comparisons to report actual expressions and operators
Fixes #129069