summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-01-12 10:48:03 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-01-12 10:48:03 +0000
commit569ad73d6b64cc7b5ed9340e5246f10fbaaf1da9 (patch)
tree78206d8f7bfea5a4ac9bf8be793c5cdbd04835c5 /clang/lib
parent4294de3aa08bf135d192a2911fc52590cda17124 (diff)
downloadbcm5719-llvm-569ad73d6b64cc7b5ed9340e5246f10fbaaf1da9.tar.gz
bcm5719-llvm-569ad73d6b64cc7b5ed9340e5246f10fbaaf1da9.zip
Avoid multiple -Wunreachable-code diagnostics that are triggered by
the same source range and use the unary operator fixit only when it actually silences the warning. rdar://24570531 Differential Revision: https://reviews.llvm.org/D28231 llvm-svn: 291757
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp20
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp10
2 files changed, 25 insertions, 5 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index 69d000c03ba..a2f3203762f 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -218,11 +218,21 @@ static bool isConfigurationValue(const Stmt *S,
}
case Stmt::UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(S);
- if (SilenceableCondVal)
- *SilenceableCondVal = UO->getSourceRange();
- return UO->getOpcode() == UO_LNot &&
- isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
- IncludeIntegers, WrappedInParens);
+ if (UO->getOpcode() != UO_LNot)
+ return false;
+ bool SilenceableCondValNotSet =
+ SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid();
+ bool IsSubExprConfigValue =
+ isConfigurationValue(UO->getSubExpr(), PP, SilenceableCondVal,
+ IncludeIntegers, WrappedInParens);
+ // Update the silenceable condition value source range only if the range
+ // was set directly by the child expression.
+ if (SilenceableCondValNotSet &&
+ SilenceableCondVal->getBegin().isValid() &&
+ *SilenceableCondVal ==
+ UO->getSubExpr()->IgnoreCasts()->getSourceRange())
+ *SilenceableCondVal = UO->getSourceRange();
+ return IsSubExprConfigValue;
}
default:
return false;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 5953d020b4f..a987a8ce0b3 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -56,6 +56,8 @@ using namespace clang;
namespace {
class UnreachableCodeHandler : public reachable_code::Callback {
Sema &S;
+ SourceRange PreviousSilenceableCondVal;
+
public:
UnreachableCodeHandler(Sema &s) : S(s) {}
@@ -64,6 +66,14 @@ namespace {
SourceRange SilenceableCondVal,
SourceRange R1,
SourceRange R2) override {
+ // Avoid reporting multiple unreachable code diagnostics that are
+ // triggered by the same conditional value.
+ if (PreviousSilenceableCondVal.isValid() &&
+ SilenceableCondVal.isValid() &&
+ PreviousSilenceableCondVal == SilenceableCondVal)
+ return;
+ PreviousSilenceableCondVal = SilenceableCondVal;
+
unsigned diag = diag::warn_unreachable;
switch (UK) {
case reachable_code::UK_Break:
OpenPOWER on IntegriCloud