diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-18 05:21:49 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-18 05:21:49 +0000 |
commit | 4c3fc9b38d3723f73e4ded594cebf38c76f91d93 (patch) | |
tree | cdba7956c4da548d2d932d58a1e99b14be707e05 /lib/AST/ExprConstant.cpp | |
parent | 8013afe5752551d72d290991046c3942138d2df1 (diff) |
Move narrowing conversion detection code from SemaInit to SemaOverload, ready
for it to be used in converted constant expression checking, and fix a couple
of issues:
- Conversion operators implicitly invoked prior to the narrowing conversion
were not being correctly handled when determining whether a constant value
was narrowed.
- For conversions from floating-point to integral types, the diagnostic text
incorrectly always claimed that the source expression was not a constant
expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148381 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 65 |
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; +} |