aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
authorBhuminjay Soni <Soni5Happy@gmail.com>2024-03-18 17:49:44 +0530
committerGitHub <noreply@github.com>2024-03-18 08:19:44 -0400
commitab28c1de23f3880d7d2becf936fe560abe68e020 (patch)
treebdc3969b262736b8d7bab685e1ab79d431a5db7c /clang
parentdaebe5c4f27ba140ac8d13abf41e3fe4db72b91a (diff)
downloadllvm-ab28c1de23f3880d7d2becf936fe560abe68e020.zip
llvm-ab28c1de23f3880d7d2becf936fe560abe68e020.tar.gz
llvm-ab28c1de23f3880d7d2becf936fe560abe68e020.tar.bz2
fix unnecessary warning when using bitand with boolean operators (#81976)
This pull request fixes #77601 where using the `bitand` operator with boolean operands should not trigger the warning, as it would indicate an intentional use of bitwise AND rather than a typo or error. Fixes #77601
Diffstat (limited to 'clang')
-rw-r--r--clang/docs/ReleaseNotes.rst4
-rw-r--r--clang/lib/Sema/SemaChecking.cpp26
-rw-r--r--clang/test/Sema/warn-bitwise-and-bool.c10
-rw-r--r--clang/test/Sema/warn-bitwise-or-bool.c8
4 files changed, 38 insertions, 10 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 125d51c..b4c90b1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -250,6 +250,10 @@ Improvements to Clang's diagnostics
such as attempting to call ``free`` on an unallocated object. Fixes
`#79443 <https://github.com/llvm/llvm-project/issues/79443>`_.
+- Clang no longer warns when the ``bitand`` operator is used with boolean
+ operands, distinguishing it from potential typographical errors or unintended
+ bitwise operations. Fixes #GH77601.
+
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index de544a0..a0b256a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16605,12 +16605,26 @@ static void AnalyzeImplicitConversions(
BO->getRHS()->isKnownToHaveBooleanValue() &&
BO->getLHS()->HasSideEffects(S.Context) &&
BO->getRHS()->HasSideEffects(S.Context)) {
- S.Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
- << (BO->getOpcode() == BO_And ? "&" : "|") << OrigE->getSourceRange()
- << FixItHint::CreateReplacement(
- BO->getOperatorLoc(),
- (BO->getOpcode() == BO_And ? "&&" : "||"));
- S.Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
+ SourceManager &SM = S.getSourceManager();
+ const LangOptions &LO = S.getLangOpts();
+ SourceLocation BLoc = BO->getOperatorLoc();
+ SourceLocation ELoc = Lexer::getLocForEndOfToken(BLoc, 0, SM, LO);
+ StringRef SR = clang::Lexer::getSourceText(
+ clang::CharSourceRange::getTokenRange(BLoc, ELoc), SM, LO);
+ // To reduce false positives, only issue the diagnostic if the operator
+ // is explicitly spelled as a punctuator. This suppresses the diagnostic
+ // when using 'bitand' or 'bitor' either as keywords in C++ or as macros
+ // in C, along with other macro spellings the user might invent.
+ if (SR.str() == "&" || SR.str() == "|") {
+
+ S.Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
+ << (BO->getOpcode() == BO_And ? "&" : "|")
+ << OrigE->getSourceRange()
+ << FixItHint::CreateReplacement(
+ BO->getOperatorLoc(),
+ (BO->getOpcode() == BO_And ? "&&" : "||"));
+ S.Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
+ }
}
// For conditional operators, we analyze the arguments as if they
diff --git a/clang/test/Sema/warn-bitwise-and-bool.c b/clang/test/Sema/warn-bitwise-and-bool.c
index 6bec1be..c30498e 100644
--- a/clang/test/Sema/warn-bitwise-and-bool.c
+++ b/clang/test/Sema/warn-bitwise-and-bool.c
@@ -19,6 +19,8 @@ boolean baz(void) __attribute__((const));
void sink(boolean);
#define FOO foo()
+#define MY_AND &
+#define My_BITAND bitand
void test(boolean a, boolean b, int *p, volatile int *q, int i) {
b = a & b;
@@ -44,9 +46,12 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) {
b = b & foo();
b = bar() & (i > 4);
b = (i == 7) & foo();
+ b = b MY_AND foo(); // OK, no warning expected
+
#ifdef __cplusplus
- b = foo() bitand bar(); // expected-warning {{use of bitwise '&' with boolean operands}}
- // expected-note@-1 {{cast one or both operands to int to silence this warning}}
+ b = foo() bitand bar(); // Ok, no warning expected
+ b = foo() My_BITAND bar(); // Ok, no warning expected
+
#endif
if (foo() & bar()) // expected-warning {{use of bitwise '&' with boolean operands}}
@@ -60,4 +65,5 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) {
int n = i + 10;
b = (n & (n - 1));
+
}
diff --git a/clang/test/Sema/warn-bitwise-or-bool.c b/clang/test/Sema/warn-bitwise-or-bool.c
index ae867909..e45ef28 100644
--- a/clang/test/Sema/warn-bitwise-or-bool.c
+++ b/clang/test/Sema/warn-bitwise-or-bool.c
@@ -19,6 +19,8 @@ boolean baz(void) __attribute__((const));
void sink(boolean);
#define FOO foo()
+#define MY_OR |
+#define My_BITOR bitor
void test(boolean a, boolean b, int *p, volatile int *q, int i) {
b = a | b;
@@ -44,9 +46,11 @@ void test(boolean a, boolean b, int *p, volatile int *q, int i) {
b = b | foo();
b = bar() | (i > 4);
b = (i == 7) | foo();
+ b = b MY_OR foo(); // OK, no warning expected
#ifdef __cplusplus
- b = foo() bitor bar(); // expected-warning {{use of bitwise '|' with boolean operands}}
- // expected-note@-1 {{cast one or both operands to int to silence this warning}}
+ b = foo() bitor bar(); //Ok, no warning expected
+ b = foo() My_BITOR bar(); // Ok, no warning expected
+
#endif
if (foo() | bar()) // expected-warning {{use of bitwise '|' with boolean operands}}