diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a0291afeed..c31850313a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6539,17 +6539,39 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Expr *Init = var->getInit(); bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); - if (!var->getDeclContext()->isDependentContext() && - (var->isConstexpr() || IsGlobal) && Init && - !Init->isConstantInitializer(Context, baseType->isReferenceType())) { - // FIXME: Improve this diagnostic to explain why the initializer is not - // a constant expression. - if (var->isConstexpr()) - Diag(var->getLocation(), diag::err_constexpr_var_requires_const_init) - << var << Init->getSourceRange(); - if (IsGlobal) + if (!var->getDeclContext()->isDependentContext() && Init) { + if (IsGlobal && !var->isConstexpr() && + getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, + var->getLocation()) + != DiagnosticsEngine::Ignored && + !Init->isConstantInitializer(Context, baseType->isReferenceType())) Diag(var->getLocation(), diag::warn_global_constructor) << Init->getSourceRange(); + + QualType Type = var->getType(); + if (var->isConstexpr()) { + llvm::SmallVector<PartialDiagnosticAt, 8> Notes; + if (!var->evaluateValue(Notes) || !var->isInitICE()) { + SourceLocation DiagLoc = var->getLocation(); + // If the note doesn't add any useful information other than a source + // location, fold it into the primary diagnostic. + if (Notes.size() == 1 && Notes[0].second.getDiagID() == + diag::note_invalid_subexpr_in_const_expr) { + DiagLoc = Notes[0].first; + Notes.clear(); + } + Diag(DiagLoc, diag::err_constexpr_var_requires_const_init) + << var << Init->getSourceRange(); + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + Diag(Notes[I].first, Notes[I].second); + } + } else if (getLangOptions().CPlusPlus && !Type.isVolatileQualified() && + Type.isConstQualified() && Type->isIntegralOrEnumerationType()) { + // Check whether the initializer of a const variable of integral or + // enumeration type is an ICE now, since we can't tell whether it was + // initialized by a constant expression if we check later. + var->checkInitIsICE(); + } } // Require the destructor. |