summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-09-19 22:00:16 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-09-19 22:00:16 +0000
commit9e4451359e49b07daff391ed20fbf47b63df9bf2 (patch)
tree5b60f39a5ede7a831e4e40a9167c13b8242f703c /lib/Sema/SemaOverload.cpp
parent095b0e84abfea76c8c5d58468e2b0de5c7835f0b (diff)
downloadclang-9e4451359e49b07daff391ed20fbf47b63df9bf2.tar.gz
Model converted constant expressions as full-expressions.
This is groundwork for C++20's P0784R7, where non-trivial destructors can be constexpr, so we need ExprWithCleanups markers in constant expressions. No functionality change intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372359 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6887cdd7ee..b8e1d2c035 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -257,8 +257,18 @@ isPointerConversionToVoidPointer(ASTContext& Context) const {
/// Skip any implicit casts which could be either part of a narrowing conversion
/// or after one in an implicit conversion.
-static const Expr *IgnoreNarrowingConversion(const Expr *Converted) {
- while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Converted)) {
+static const Expr *IgnoreNarrowingConversion(ASTContext &Ctx,
+ const Expr *Converted) {
+ // We can have cleanups wrapping the converted expression; these need to be
+ // preserved so that destructors run if necessary.
+ if (auto *EWC = dyn_cast<ExprWithCleanups>(Converted)) {
+ Expr *Inner =
+ const_cast<Expr *>(IgnoreNarrowingConversion(Ctx, EWC->getSubExpr()));
+ return ExprWithCleanups::Create(Ctx, Inner, EWC->cleanupsHaveSideEffects(),
+ EWC->getObjects());
+ }
+
+ while (auto *ICE = dyn_cast<ImplicitCastExpr>(Converted)) {
switch (ICE->getCastKind()) {
case CK_NoOp:
case CK_IntegralCast:
@@ -332,7 +342,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
if (IgnoreFloatToIntegralConversion)
return NK_Not_Narrowing;
llvm::APSInt IntConstantValue;
- const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+ const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);
assert(Initializer && "Unknown conversion expression");
// If it's value-dependent, we can't tell whether it's narrowing.
@@ -370,7 +380,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
if (FromType->isRealFloatingType() && ToType->isRealFloatingType() &&
Ctx.getFloatingTypeOrder(FromType, ToType) == 1) {
// FromType is larger than ToType.
- const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+ const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);
// If it's value-dependent, we can't tell whether it's narrowing.
if (Initializer->isValueDependent())
@@ -416,7 +426,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
(FromSigned && !ToSigned)) {
// Not all values of FromType can be represented in ToType.
llvm::APSInt InitializerValue;
- const Expr *Initializer = IgnoreNarrowingConversion(Converted);
+ const Expr *Initializer = IgnoreNarrowingConversion(Ctx, Converted);
// If it's value-dependent, we can't tell whether it's narrowing.
if (Initializer->isValueDependent())
@@ -5465,6 +5475,14 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From,
if (Result.isInvalid())
return Result;
+ // C++2a [intro.execution]p5:
+ // A full-expression is [...] a constant-expression [...]
+ Result =
+ S.ActOnFinishFullExpr(Result.get(), From->getExprLoc(),
+ /*DiscardedValue=*/false, /*IsConstexpr=*/true);
+ if (Result.isInvalid())
+ return Result;
+
// Check for a narrowing implicit conversion.
APValue PreNarrowingValue;
QualType PreNarrowingType;