summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ReachableCode.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2014-03-20 06:44:35 +0000
committerTed Kremenek <kremenek@apple.com>2014-03-20 06:44:35 +0000
commitf5ae0bc671a40126450655c78ade7d8bb36b71c0 (patch)
treee4675afa59dda6829e8dc7e37e82cab071a56c54 /clang/lib/Analysis/ReachableCode.cpp
parent798e548955556eef47820910174118abbfa933e3 (diff)
downloadbcm5719-llvm-f5ae0bc671a40126450655c78ade7d8bb36b71c0.tar.gz
bcm5719-llvm-f5ae0bc671a40126450655c78ade7d8bb36b71c0.zip
[-Wunreachable-code] Look through member accesses for 'static const bool' configuration values.
llvm-svn: 204315
Diffstat (limited to 'clang/lib/Analysis/ReachableCode.cpp')
-rw-r--r--clang/lib/Analysis/ReachableCode.cpp50
1 files changed, 27 insertions, 23 deletions
diff --git a/clang/lib/Analysis/ReachableCode.cpp b/clang/lib/Analysis/ReachableCode.cpp
index ffe576cd052..0a9e82bb0ad 100644
--- a/clang/lib/Analysis/ReachableCode.cpp
+++ b/clang/lib/Analysis/ReachableCode.cpp
@@ -122,6 +122,8 @@ static bool isExpandedFromConfigurationMacro(const Stmt *S,
return false;
}
+static bool isConfigurationValue(const ValueDecl *D, Preprocessor &PP);
+
/// Returns true if the statement represents a configuration value.
///
/// A configuration value is something usually determined at compile-time
@@ -144,34 +146,15 @@ static bool isConfigurationValue(const Stmt *S,
dyn_cast_or_null<FunctionDecl>(cast<CallExpr>(S)->getCalleeDecl());
return Callee ? Callee->isConstexpr() : false;
}
- case Stmt::DeclRefExprClass: {
- const DeclRefExpr *DR = cast<DeclRefExpr>(S);
- const ValueDecl *D = DR->getDecl();
- if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D))
- return isConfigurationValue(ED->getInitExpr(), PP);
- 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.
- if (!VD->hasLocalStorage())
- return true;
-
- // As a heuristic, locals that have been marked 'const' explicitly
- // can be treated as configuration values as well.
- return VD->getType().isLocalConstQualified();
- }
- return false;
- }
+ case Stmt::DeclRefExprClass:
+ return isConfigurationValue(cast<DeclRefExpr>(S)->getDecl(), PP);
case Stmt::IntegerLiteralClass:
return IncludeIntegers ? isExpandedFromConfigurationMacro(S, PP)
: false;
+ case Stmt::MemberExprClass:
+ return isConfigurationValue(cast<MemberExpr>(S)->getMemberDecl(), PP);
case Stmt::ObjCBoolLiteralExprClass:
return isExpandedFromConfigurationMacro(S, PP, /* IgnoreYES_NO */ true);
-
case Stmt::UnaryExprOrTypeTraitExprClass:
return true;
case Stmt::BinaryOperatorClass: {
@@ -193,6 +176,27 @@ static bool isConfigurationValue(const Stmt *S,
}
}
+static bool isConfigurationValue(const ValueDecl *D, Preprocessor &PP) {
+ if (const EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D))
+ return isConfigurationValue(ED->getInitExpr(), PP);
+ 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.
+ if (!VD->hasLocalStorage())
+ return true;
+
+ // As a heuristic, locals that have been marked 'const' explicitly
+ // can be treated as configuration values as well.
+ return VD->getType().isLocalConstQualified();
+ }
+ return false;
+}
+
/// Returns true if we should always explore all successors of a block.
static bool shouldTreatSuccessorsAsReachable(const CFGBlock *B,
Preprocessor &PP) {
OpenPOWER on IntegriCloud