aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp43
1 files changed, 24 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2159a0d..10f0ec3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -20565,31 +20565,36 @@ void Sema::MarkDeclarationsReferencedInExpr(Expr *E,
}
/// Emit a diagnostic when statements are reachable.
-/// FIXME: check for reachability even in expressions for which we don't build a
-/// CFG (eg, in the initializer of a global or in a constant expression).
-/// For example,
-/// namespace { auto *p = new double[3][false ? (1, 2) : 3]; }
bool Sema::DiagIfReachable(SourceLocation Loc, ArrayRef<const Stmt *> Stmts,
const PartialDiagnostic &PD) {
- if (!Stmts.empty() && getCurFunctionOrMethodDecl()) {
- if (!FunctionScopes.empty())
- FunctionScopes.back()->PossiblyUnreachableDiags.push_back(
- sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
- return true;
- }
-
+ VarDecl *Decl = ExprEvalContexts.back().DeclForInitializer;
// The initializer of a constexpr variable or of the first declaration of a
// static data member is not syntactically a constant evaluated constant,
// but nonetheless is always required to be a constant expression, so we
// can skip diagnosing.
- // FIXME: Using the mangling context here is a hack.
- if (auto *VD = dyn_cast_or_null<VarDecl>(
- ExprEvalContexts.back().ManglingContextDecl)) {
- if (VD->isConstexpr() ||
- (VD->isStaticDataMember() && VD->isFirstDecl() && !VD->isInline()))
- return false;
- // FIXME: For any other kind of variable, we should build a CFG for its
- // initializer and check whether the context in question is reachable.
+ if (Decl &&
+ (Decl->isConstexpr() || (Decl->isStaticDataMember() &&
+ Decl->isFirstDecl() && !Decl->isInline())))
+ return false;
+
+ if (Stmts.empty()) {
+ Diag(Loc, PD);
+ return true;
+ }
+
+ if (getCurFunction()) {
+ FunctionScopes.back()->PossiblyUnreachableDiags.push_back(
+ sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
+ return true;
+ }
+
+ // For non-constexpr file-scope variables with reachability context (non-empty
+ // Stmts), build a CFG for the initializer and check whether the context in
+ // question is reachable.
+ if (Decl && Decl->isFileVarDecl()) {
+ AnalysisWarnings.registerVarDeclWarning(
+ Decl, sema::PossiblyUnreachableDiag(PD, Loc, Stmts));
+ return true;
}
Diag(Loc, PD);