New tautological warning for bitwise-or with non-zero constant always true.
Taking a value and the bitwise-or it with a non-zero constant will always
result in a non-zero value. In a boolean context, this is always true.
if (x | 0x4) {} // always true, intended '&'
This patch creates a new warning group -Wtautological-bitwise-compare for this
warning. It also moves in the existing tautological bitwise comparisons into
this group. A few other changes were needed to the CFGBuilder so that all bool
contexts would be checked. The warnings in -Wtautological-bitwise-compare will
be off by default due to using the CFG.
Fixes: https://bugs.llvm.org/show_bug.cgi?id=42666
Differential Revision: https://reviews.llvm.org/D66046
llvm-svn: 375318
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 01648fe..2c70c05 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -159,6 +159,20 @@
S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_always)
<< DiagRange << isAlwaysTrue;
}
+
+ void compareBitwiseOr(const BinaryOperator *B) override {
+ if (HasMacroID(B))
+ return;
+
+ SourceRange DiagRange = B->getSourceRange();
+ S.Diag(B->getExprLoc(), diag::warn_comparison_bitwise_or) << DiagRange;
+ }
+
+ static bool hasActiveDiagnostics(DiagnosticsEngine &Diags,
+ SourceLocation Loc) {
+ return !Diags.isIgnored(diag::warn_tautological_overlap_comparison, Loc) ||
+ !Diags.isIgnored(diag::warn_comparison_bitwise_or, Loc);
+ }
};
} // anonymous namespace
@@ -2070,10 +2084,9 @@
.setAlwaysAdd(Stmt::AttributedStmtClass);
}
- // Install the logical handler for -Wtautological-overlap-compare
+ // Install the logical handler.
llvm::Optional<LogicalErrorHandler> LEH;
- if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
- D->getBeginLoc())) {
+ if (LogicalErrorHandler::hasActiveDiagnostics(Diags, D->getBeginLoc())) {
LEH.emplace(S);
AC.getCFGBuildOptions().Observer = &*LEH;
}
@@ -2222,9 +2235,8 @@
checkThrowInNonThrowingFunc(S, FD, AC);
// If none of the previous checks caused a CFG build, trigger one here
- // for -Wtautological-overlap-compare
- if (!Diags.isIgnored(diag::warn_tautological_overlap_comparison,
- D->getBeginLoc())) {
+ // for the logical error handler.
+ if (LogicalErrorHandler::hasActiveDiagnostics(Diags, D->getBeginLoc())) {
AC.getCFG();
}