aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp65
1 files changed, 38 insertions, 27 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index fc3c5aac01..5d61406959 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1756,18 +1756,16 @@ static bool CheckTrivialDefaultConstructor(EvalInfo &Info, SourceLocation Loc,
if (!CD->isTrivial() || !CD->isDefaultConstructor())
return false;
- if (!CD->isConstexpr()) {
+ // Value-initialization does not call a trivial default constructor, so such a
+ // call is a core constant expression whether or not the constructor is
+ // constexpr.
+ if (!CD->isConstexpr() && !IsValueInitialization) {
if (Info.getLangOpts().CPlusPlus0x) {
- // Value-initialization does not call a trivial default constructor, so
- // such a call is a core constant expression whether or not the
- // constructor is constexpr.
- if (!IsValueInitialization) {
- // FIXME: If DiagDecl is an implicitly-declared special member function,
- // we should be much more explicit about why it's not constexpr.
- Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
- << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
- Info.Note(CD->getLocation(), diag::note_declared_at);
- }
+ // FIXME: If DiagDecl is an implicitly-declared special member function,
+ // we should be much more explicit about why it's not constexpr.
+ Info.CCEDiag(Loc, diag::note_constexpr_invalid_function, 1)
+ << /*IsConstexpr*/0 << /*IsConstructor*/1 << CD;
+ Info.Note(CD->getLocation(), diag::note_declared_at);
} else {
Info.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
}
@@ -5944,24 +5942,12 @@ static bool EvaluateCPlusPlus11IntegralConstantExpr(ASTContext &Ctx,
return false;
}
- Expr::EvalResult Result;
- llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
- Result.Diag = &Diags;
- EvalInfo Info(Ctx, Result);
-
- bool IsICE = EvaluateAsRValue(Info, E, Result.Val);
- if (!Diags.empty()) {
- IsICE = false;
- if (Loc) *Loc = Diags[0].first;
- } else if (!IsICE && Loc) {
- *Loc = E->getExprLoc();
- }
-
- if (!IsICE)
+ APValue Result;
+ if (!E->isCXX11ConstantExpr(Ctx, &Result, Loc))
return false;
- assert(Result.Val.isInt() && "pointer cast to int is not an ICE");
- if (Value) *Value = Result.Val.getInt();
+ assert(Result.isInt() && "pointer cast to int is not an ICE");
+ if (Value) *Value = Result.getInt();
return true;
}
@@ -5988,3 +5974,28 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, ASTContext &Ctx,
llvm_unreachable("ICE cannot be evaluated!");
return true;
}
+
+bool Expr::isCXX11ConstantExpr(ASTContext &Ctx, APValue *Result,
+ SourceLocation *Loc) const {
+ // We support this checking in C++98 mode in order to diagnose compatibility
+ // issues.
+ assert(Ctx.getLangOptions().CPlusPlus);
+
+ Expr::EvalStatus Status;
+ llvm::SmallVector<PartialDiagnosticAt, 8> Diags;
+ Status.Diag = &Diags;
+ EvalInfo Info(Ctx, Status);
+
+ APValue Scratch;
+ bool IsConstExpr = ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch);
+
+ if (!Diags.empty()) {
+ IsConstExpr = false;
+ if (Loc) *Loc = Diags[0].first;
+ } else if (!IsConstExpr) {
+ // FIXME: This shouldn't happen.
+ if (Loc) *Loc = getExprLoc();
+ }
+
+ return IsConstExpr;
+}