summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-03 01:14:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-03 01:14:32 +0000
commit4baaa5ab52870c3d2e1961aaa7758908ea69579e (patch)
treed0b7a59ca83d21a73fbd5a907b01941e9199da31 /clang/lib/Sema/SemaInit.cpp
parent05049bed027cb37ef4afcbc6b280603e767f7971 (diff)
downloadbcm5719-llvm-4baaa5ab52870c3d2e1961aaa7758908ea69579e.tar.gz
bcm5719-llvm-4baaa5ab52870c3d2e1961aaa7758908ea69579e.zip
DR616, and part of P0135R1: member access (or pointer-to-member access) on a
temporary produces an xvalue, not a prvalue. Support this by materializing the temporary prior to performing the member access. llvm-svn: 288563
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp30
1 files changed, 21 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index f5e38b4fbdf..3937aad012d 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5963,10 +5963,7 @@ performReferenceExtension(Expr *Init,
// Step over any subobject adjustments; we may have a materialized
// temporary inside them.
- SmallVector<const Expr *, 2> CommaLHSs;
- SmallVector<SubobjectAdjustment, 2> Adjustments;
- Init = const_cast<Expr *>(
- Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
+ Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
// Per current approach for DR1376, look through casts to reference type
// when performing lifetime extension.
@@ -5996,10 +5993,7 @@ performReferenceExtension(Expr *Init,
static void performLifetimeExtension(Expr *Init,
const InitializedEntity *ExtendingEntity) {
// Dig out the expression which constructs the extended temporary.
- SmallVector<const Expr *, 2> CommaLHSs;
- SmallVector<SubobjectAdjustment, 2> Adjustments;
- Init = const_cast<Expr *>(
- Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
+ Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
Init = BTE->getSubExpr();
@@ -6218,6 +6212,22 @@ Sema::CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
return MTE;
}
+ExprResult Sema::TemporaryMaterializationConversion(Expr *E) {
+ // In C++98, we don't want to implicitly create an xvalue.
+ // FIXME: This means that AST consumers need to deal with "prvalues" that
+ // denote materialized temporaries. Maybe we should add another ValueKind
+ // for "xvalue pretending to be a prvalue" for C++98 support.
+ if (!E->isRValue() || !getLangOpts().CPlusPlus11)
+ return E;
+
+ // C++1z [conv.rval]/1: T shall be a complete type.
+ QualType T = E->getType();
+ if (RequireCompleteType(E->getExprLoc(), T, diag::err_incomplete_type))
+ return ExprError();
+
+ return CreateMaterializeTemporaryExpr(E->getType(), E, false);
+}
+
ExprResult
InitializationSequence::Perform(Sema &S,
const InitializedEntity &Entity,
@@ -6316,7 +6326,9 @@ InitializationSequence::Perform(Sema &S,
if (Args.size() == 1 && Args[0]->getType()->isArrayType() &&
Entity.getType()->isPointerType() &&
InitializedEntityOutlivesFullExpression(Entity)) {
- Expr *Init = Args[0];
+ const Expr *Init = Args[0]->skipRValueSubobjectAdjustments();
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
+ Init = MTE->GetTemporaryExpr();
Expr::LValueClassification Kind = Init->ClassifyLValue(S.Context);
if (Kind == Expr::LV_ClassTemporary || Kind == Expr::LV_ArrayTemporary)
S.Diag(Init->getLocStart(), diag::warn_temporary_array_to_pointer_decay)
OpenPOWER on IntegriCloud