diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Analysis/ReachableCode.cpp | 16 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-unreachable.cpp | 7 |
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 +} + |