-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang][Analysis] Handle && and || against variable and its negation …
…as tautology This patch introduces a new warning flag -Wtautological-negation-compare grouped in -Wtautological-compare that warns on the use of && or || operators against a variable and its negation. e.g. x || !x and !x && x This also makes the -Winfinite-recursion diagnose more cases. Fixes #56035 Differential Revision: https://reviews.llvm.org/D152093
- Loading branch information
Showing
10 changed files
with
111 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-negation-compare -Wno-constant-logical-operand %s | ||
// RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-compare -Wno-constant-logical-operand %s | ||
// RUN: %clang_cc1 -fsyntax-only -verify -Wall -Wno-unused -Wno-loop-analysis -Wno-constant-logical-operand %s | ||
|
||
#define COPY(x) x | ||
|
||
void test_int(int x) { | ||
if (x || !x) {} // expected-warning {{'||' of a value and its negation always evaluates to true}} | ||
if (!x || x) {} // expected-warning {{'||' of a value and its negation always evaluates to true}} | ||
if (x && !x) {} // expected-warning {{'&&' of a value and its negation always evaluates to false}} | ||
if (!x && x) {} // expected-warning {{'&&' of a value and its negation always evaluates to false}} | ||
|
||
// parentheses are ignored | ||
if (x || (!x)) {} // expected-warning {{'||' of a value and its negation always evaluates to true}} | ||
if (!(x) || x) {} // expected-warning {{'||' of a value and its negation always evaluates to true}} | ||
|
||
// don't warn on macros | ||
if (COPY(x) || !x) {} | ||
if (!x || COPY(x)) {} | ||
if (x && COPY(!x)) {} | ||
if (COPY(!x && x)) {} | ||
|
||
// dont' warn on literals | ||
if (1 || !1) {} | ||
if (!42 && 42) {} | ||
|
||
|
||
// don't warn on overloads | ||
struct Foo{ | ||
int val; | ||
Foo operator!() const { return Foo{!val}; } | ||
bool operator||(const Foo other) const { return val || other.val; } | ||
bool operator&&(const Foo other) const { return val && other.val; } | ||
}; | ||
|
||
Foo f{3}; | ||
if (f || !f) {} | ||
if (!f || f) {} | ||
if (f.val || !f.val) {} // expected-warning {{'||' of a value and its negation always evaluates to true}} | ||
if (!f.val && f.val) {} // expected-warning {{'&&' of a value and its negation always evaluates to false}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
b3469ce
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.
Could this patch be the reason why for a couple of months I've been seeing the following compiler output while building Clang using nightly builds of Clang from https://apt.llvm.org: https://gist.github.com/Endilll/dd922647c40cf44f8496812a776cc26f ? This patch doesn't seem to be concerned with equality comparisons, but it appears to be the only "recent" change in the vicinity. I'd be glad if you can help pin this down.
b3469ce
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.
Generally I don't think this patch is relevant for that. The self-comparison warning is emitted from
SemaExpr.cpp
and this patch does not touch things nearby. But I also couldn't see any changes around there, so I can't say 100% this patch is irrelevant.What looks most suspicious to me is that
-Wtautological-compare
is emitted against something that comes from macro (The last output,OO_Conditional
one). Clang is printing the text that actually is a macro expansion result (if (OO_Conditional != OO_Conditional) Results.AddResult(Result("?"));
), and it looks to expose the warning.So, I suspect that it's caused by some change in clang's handling of macros or
#include
.I'm sorry I cannot reproduce the output locally and do in-depth analysis.
b3469ce
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 sharing your thoughts!