aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp14
1 files changed, 14 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 615ba1a..bdd9fb4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -13249,6 +13249,20 @@ static void AnalyzeImplicitConversions(
<< OrigE->getSourceRange() << T->isBooleanType()
<< FixItHint::CreateReplacement(UO->getBeginLoc(), "!");
+ if (const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
+ if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
+ BO->getLHS()->isKnownToHaveBooleanValue() &&
+ 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);
+ }
+
// For conditional operators, we analyze the arguments as if they
// were being fed directly into the output.
if (auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {