summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp16
-rw-r--r--clang/test/SemaCXX/warn-unreachable.cpp7
2 files changed, 21 insertions, 2 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index f563cbdc593..47f8f2b90cd 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -194,8 +194,20 @@ static bool isConfigurationValue(const Stmt *S) {
switch (S->getStmtClass()) {
case Stmt::DeclRefExprClass: {
const DeclRefExpr *DR = cast<DeclRefExpr>(S);
- const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
- return ED ? isConfigurationValue(ED->getInitExpr()) : false;
+ const ValueDecl *D = DR->getDecl();
+ if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D))
+ return ED ? isConfigurationValue(ED->getInitExpr()) : false;
+ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ // As a heuristic, treat globals as configuration values. Note
+ // that we only will get here if Sema evaluated this
+ // condition to a constant expression, which means the global
+ // had to be declared in a way to be a truly constant value.
+ // We could generalize this to local variables, but it isn't
+ // clear if those truly represent configuration values that
+ // gate unreachable code.
+ return !VD->hasLocalStorage();
+ }
+ return false;
}
case Stmt::IntegerLiteralClass:
return isExpandedFromConfigurationMacro(S);
diff --git a/clang/test/SemaCXX/warn-unreachable.cpp b/clang/test/SemaCXX/warn-unreachable.cpp
index 1030c993ada..8c191f6fadc 100644
--- a/clang/test/SemaCXX/warn-unreachable.cpp
+++ b/clang/test/SemaCXX/warn-unreachable.cpp
@@ -155,3 +155,10 @@ bool testBool() {
return true; // no-warning
}
+static const bool ConditionVar = 1;
+int test_global_as_conditionVariable() {
+ if (ConditionVar)
+ return 1;
+ return 0; // no-warning
+}
+
OpenPOWER on IntegriCloud