<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hmm, never mind. The test seems to preclude copy elision if I'm looking in the right place:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Menlo" class="">std::streambuf &get();</font></div></div><div class=""><div class=""><font face="Menlo" class=""><br class=""></font></div></div><div class=""><div class=""><font face="Menlo" class="">int main()</font></div></div><div class=""><div class=""><font face="Menlo" class="">{</font></div></div><div class=""><div class=""><font face="Menlo" class=""> std::streambuf sb = get(); // expected-error</font></div></div><div class=""><div class=""><font face="Menlo" class="">}</font></div></div></blockquote><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><blockquote type="cite" class="">On 2016-Dec-08, at 19:17, Duncan P. N. Exon Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""><br class="">+Eric, Marshall<br class=""><br class="">I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there is a bug/incompatibility in the test. It likely relies on the compiler trying (and failing) to copy something in a context where r288866 guarantees that there is no copy.<br class=""><br class=""><blockquote type="cite" class="">On 2016-Dec-08, at 18:00, Adrian Prantl <<a href="mailto:aprantl@apple.com" class="">aprantl@apple.com</a>> wrote:<br class=""><br class="">Hi Richard,<br class=""><br class="">at this point this is more a heads-up than anything actionable, but I wanted to let you know that I bisected this bot failure (<a href="http://lab.llvm.org:8080/green/job/clang-stage2-cmake-" class="">http://lab.llvm.org:8080/green/job/clang-stage2-cmake-</a>RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404) of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp down to this commit.<br class=""><br class="">I will follow up once I have a better understanding what is going on there.<br class=""><br class="">-- adrian<br class=""><br class=""><blockquote type="cite" class="">On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a>> wrote:<br class=""><br class="">Author: rsmith<br class="">Date: Tue Dec 6 17:52:28 2016<br class="">New Revision: 288866<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=288866&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=288866&view=rev</a><br class="">Log:<br class="">[c++17] P0135R1: Guaranteed copy elision.<br class=""><br class="">When an object of class type is initialized from a prvalue of the same type<br class="">(ignoring cv qualifications), use the prvalue to initialize the object directly<br class="">instead of inserting a redundant elidable call to a copy constructor.<br class=""><br class="">Added:<br class=""> cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp<br class=""> cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp<br class="">Modified:<br class=""> cfe/trunk/include/clang/AST/Expr.h<br class=""> cfe/trunk/lib/AST/Expr.cpp<br class=""> cfe/trunk/lib/AST/ExprConstant.cpp<br class=""> cfe/trunk/lib/CodeGen/CGExpr.cpp<br class=""> cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br class=""> cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br class=""> cfe/trunk/lib/Sema/SemaExprCXX.cpp<br class=""> cfe/trunk/lib/Sema/SemaInit.cpp<br class=""> cfe/trunk/lib/Sema/SemaOverload.cpp<br class=""> cfe/trunk/test/CXX/drs/dr0xx.cpp<br class=""> cfe/trunk/test/CXX/drs/dr10xx.cpp<br class=""> cfe/trunk/test/CXX/drs/dr1xx.cpp<br class=""> cfe/trunk/test/CXX/drs/dr4xx.cpp<br class=""> cfe/trunk/test/SemaCXX/aggregate-initialization.cpp<br class=""> cfe/trunk/www/cxx_dr_status.html<br class=""> cfe/trunk/www/cxx_status.html<br class=""><br class="">Modified: cfe/trunk/include/clang/AST/Expr.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/AST/Expr.h (original)<br class="">+++ cfe/trunk/include/clang/AST/Expr.h Tue Dec 6 17:52:28 2016<br class="">@@ -3786,7 +3786,7 @@ public:<br class=""><br class="">/// \brief Build an empty initializer list.<br class="">explicit InitListExpr(EmptyShell Empty)<br class="">- : Expr(InitListExprClass, Empty) { }<br class="">+ : Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }<br class=""><br class="">unsigned getNumInits() const { return InitExprs.size(); }<br class=""><br class="">@@ -3894,6 +3894,11 @@ public:<br class="">// literal or an @encode?<br class="">bool isStringLiteralInit() const;<br class=""><br class="">+ /// Is this a transparent initializer list (that is, an InitListExpr that is<br class="">+ /// purely syntactic, and whose semantics are that of the sole contained<br class="">+ /// initializer)?<br class="">+ bool isTransparent() const;<br class="">+<br class="">SourceLocation getLBraceLoc() const { return LBraceLoc; }<br class="">void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }<br class="">SourceLocation getRBraceLoc() const { return RBraceLoc; }<br class=""><br class="">Modified: cfe/trunk/lib/AST/Expr.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/Expr.cpp (original)<br class="">+++ cfe/trunk/lib/AST/Expr.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()<br class="">return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);<br class="">}<br class=""><br class="">+bool InitListExpr::isTransparent() const {<br class="">+ assert(isSemanticForm() && "syntactic form never semantically transparent");<br class="">+<br class="">+ // A glvalue InitListExpr is always just sugar.<br class="">+ if (isGLValue()) {<br class="">+ assert(getNumInits() == 1 && "multiple inits in glvalue init list");<br class="">+ return true;<br class="">+ }<br class="">+<br class="">+ // Otherwise, we're sugar if and only if we have exactly one initializer that<br class="">+ // is of the same type.<br class="">+ if (getNumInits() != 1 || !getInit(0))<br class="">+ return false;<br class="">+<br class="">+ return getType().getCanonicalType() ==<br class="">+ getInit(0)->getType().getCanonicalType();<br class="">+}<br class="">+<br class="">SourceLocation InitListExpr::getLocStart() const {<br class="">if (InitListExpr *SyntacticForm = getSyntacticForm())<br class=""> return SyntacticForm->getLocStart();<br class="">@@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const<br class=""> // effects (e.g. a placement new with an uninitialized POD).<br class="">case CXXDeleteExprClass:<br class=""> return false;<br class="">+ case MaterializeTemporaryExprClass:<br class="">+ return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()<br class="">+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);<br class="">case CXXBindTemporaryExprClass:<br class="">- return (cast<CXXBindTemporaryExpr>(this)<br class="">- ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));<br class="">+ return cast<CXXBindTemporaryExpr>(this)->getSubExpr()<br class="">+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);<br class="">case ExprWithCleanupsClass:<br class="">- return (cast<ExprWithCleanups>(this)<br class="">- ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));<br class="">+ return cast<ExprWithCleanups>(this)->getSubExpr()<br class="">+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);<br class="">}<br class="">}<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br class="">+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -5670,6 +5670,9 @@ bool RecordExprEvaluator::VisitCastExpr(<br class="">}<br class=""><br class="">bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {<br class="">+ if (E->isTransparent())<br class="">+ return Visit(E->getInit(0));<br class="">+<br class="">const RecordDecl *RD = E->getType()->castAs<RecordType>()->getDecl();<br class="">if (RD->isInvalidDecl()) return false;<br class="">const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -3522,7 +3522,7 @@ LValue CodeGenFunction::EmitInitListLVal<br class=""> return EmitAggExprToLValue(E);<br class=""><br class="">// An lvalue initializer list must be initializing a reference.<br class="">- assert(E->getNumInits() == 1 && "reference init with multiple values");<br class="">+ assert(E->isTransparent() && "non-transparent glvalue init list");<br class="">return EmitLValue(E->getInit(0));<br class="">}<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -1145,15 +1145,15 @@ void AggExprEmitter::VisitInitListExpr(I<br class="">if (E->hadArrayRangeDesignator())<br class=""> CGF.ErrorUnsupported(E, "GNU array range designator extension");<br class=""><br class="">+ if (E->isTransparent())<br class="">+ return Visit(E->getInit(0));<br class="">+<br class="">AggValueSlot Dest = EnsureSlot(E->getType());<br class=""><br class="">LValue DestLV = CGF.MakeAddrLValue(Dest.getAddress(), E->getType());<br class=""><br class="">// Handle initialization of an array.<br class="">if (E->getType()->isArrayType()) {<br class="">- if (E->isStringLiteralInit())<br class="">- return Visit(E->getInit(0));<br class="">-<br class=""> QualType elementType =<br class=""> CGF.getContext().getAsArrayType(E->getType())->getElementType();<br class=""><br class="">@@ -1162,16 +1162,6 @@ void AggExprEmitter::VisitInitListExpr(I<br class=""> return;<br class="">}<br class=""><br class="">- if (E->getType()->isAtomicType()) {<br class="">- // An _Atomic(T) object can be list-initialized from an expression<br class="">- // of the same type.<br class="">- assert(E->getNumInits() == 1 &&<br class="">- CGF.getContext().hasSameUnqualifiedType(E->getInit(0)->getType(),<br class="">- E->getType()) &&<br class="">- "unexpected list initialization for atomic object");<br class="">- return Visit(E->getInit(0));<br class="">- }<br class="">-<br class="">assert(E->getType()->isRecordType() && "Only support structs/unions here!");<br class=""><br class="">// Do struct initialization; this code just sets each individual member<br class=""><br class="">Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)<br class="">+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -778,9 +778,6 @@ public:<br class="">}<br class=""><br class="">llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {<br class="">- if (ILE->isStringLiteralInit())<br class="">- return Visit(ILE->getInit(0));<br class="">-<br class=""> llvm::ArrayType *AType =<br class=""> cast<llvm::ArrayType>(ConvertType(ILE->getType()));<br class=""> llvm::Type *ElemTy = AType->getElementType();<br class="">@@ -845,6 +842,9 @@ public:<br class="">}<br class=""><br class="">llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {<br class="">+ if (ILE->isTransparent())<br class="">+ return Visit(ILE->getInit(0));<br class="">+<br class=""> if (ILE->getType()->isArrayType())<br class=""> return EmitArrayInitialization(ILE);<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -6836,6 +6836,16 @@ ExprResult Sema::IgnoredValueConversions<br class=""> return E;<br class=""> E = Res.get();<br class=""> }<br class="">+<br class="">+ // C++1z:<br class="">+ // If the expression is a prvalue after this optional conversion, the<br class="">+ // temporary materialization conversion is applied.<br class="">+ //<br class="">+ // We skip this step: IR generation is able to synthesize the storage for<br class="">+ // itself in the aggregate case, and adding the extra node to the AST is<br class="">+ // just clutter.<br class="">+ // FIXME: We don't emit lifetime markers for the temporaries due to this.<br class="">+ // FIXME: Do any other AST consumers care about this?<br class=""> return E;<br class="">}<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaInit.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaInit.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -3546,8 +3546,14 @@ static void TryConstructorInitialization<br class=""> InitializationSequence &Sequence,<br class=""> bool IsListInit = false,<br class=""> bool IsInitListCopy = false) {<br class="">- assert((!IsListInit || (Args.size() == 1 && isa<InitListExpr>(Args[0]))) &&<br class="">- "IsListInit must come with a single initializer list argument.");<br class="">+ assert(((!IsListInit && !IsInitListCopy) ||<br class="">+ (Args.size() == 1 && isa<InitListExpr>(Args[0]))) &&<br class="">+ "IsListInit/IsInitListCopy must come with a single initializer list "<br class="">+ "argument.");<br class="">+ InitListExpr *ILE =<br class="">+ (IsListInit || IsInitListCopy) ? cast<InitListExpr>(Args[0]) : nullptr;<br class="">+ MultiExprArg UnwrappedArgs =<br class="">+ ILE ? MultiExprArg(ILE->getInits(), ILE->getNumInits()) : Args;<br class=""><br class="">// The type we're constructing needs to be complete.<br class="">if (!S.isCompleteType(Kind.getLocation(), DestType)) {<br class="">@@ -3555,6 +3561,35 @@ static void TryConstructorInitialization<br class=""> return;<br class="">}<br class=""><br class="">+ // C++1z [dcl.init]p17:<br class="">+ // - If the initializer expression is a prvalue and the cv-unqualified<br class="">+ // version of the source type is the same class as the class of the<br class="">+ // destination, the initializer expression is used to initialize the<br class="">+ // destination object.<br class="">+ // Per DR (no number yet), this does not apply when initializing a base<br class="">+ // class or delegating to another constructor from a mem-initializer.<br class="">+ if (S.getLangOpts().CPlusPlus1z &&<br class="">+ Entity.getKind() != InitializedEntity::EK_Base &&<br class="">+ Entity.getKind() != InitializedEntity::EK_Delegating &&<br class="">+ UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() &&<br class="">+ S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {<br class="">+ // Convert qualifications if necessary.<br class="">+ QualType InitType = UnwrappedArgs[0]->getType();<br class="">+ ImplicitConversionSequence ICS;<br class="">+ ICS.setStandard();<br class="">+ ICS.Standard.setAsIdentityConversion();<br class="">+ ICS.Standard.setFromType(InitType);<br class="">+ ICS.Standard.setAllToTypes(InitType);<br class="">+ if (!S.Context.hasSameType(InitType, DestType)) {<br class="">+ ICS.Standard.Third = ICK_Qualification;<br class="">+ ICS.Standard.setToType(2, DestType);<br class="">+ }<br class="">+ Sequence.AddConversionSequenceStep(ICS, DestType);<br class="">+ if (ILE)<br class="">+ Sequence.RewrapReferenceInitList(DestType, ILE);<br class="">+ return;<br class="">+ }<br class="">+<br class="">const RecordType *DestRecordType = DestType->getAs<RecordType>();<br class="">assert(DestRecordType && "Constructor initialization requires record type");<br class="">CXXRecordDecl *DestRecordDecl<br class="">@@ -3588,20 +3623,16 @@ static void TryConstructorInitialization<br class="">// constructors of the class T and the argument list consists of the<br class="">// initializer list as a single argument.<br class="">if (IsListInit) {<br class="">- InitListExpr *ILE = cast<InitListExpr>(Args[0]);<br class=""> AsInitializerList = true;<br class=""><br class=""> // If the initializer list has no elements and T has a default constructor,<br class=""> // the first phase is omitted.<br class="">- if (ILE->getNumInits() != 0 || !DestRecordDecl->hasDefaultConstructor())<br class="">+ if (!(UnwrappedArgs.empty() && DestRecordDecl->hasDefaultConstructor()))<br class=""> Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,<br class=""> CandidateSet, Ctors, Best,<br class=""> CopyInitialization, AllowExplicit,<br class=""> /*OnlyListConstructor=*/true,<br class=""> IsListInit);<br class="">-<br class="">- // Time to unwrap the init list.<br class="">- Args = MultiExprArg(ILE->getInits(), ILE->getNumInits());<br class="">}<br class=""><br class="">// C++11 [over.match.list]p1:<br class="">@@ -3611,7 +3642,7 @@ static void TryConstructorInitialization<br class="">// elements of the initializer list.<br class="">if (Result == OR_No_Viable_Function) {<br class=""> AsInitializerList = false;<br class="">- Result = ResolveConstructorOverload(S, Kind.getLocation(), Args,<br class="">+ Result = ResolveConstructorOverload(S, Kind.getLocation(), UnwrappedArgs,<br class=""> CandidateSet, Ctors, Best,<br class=""> CopyInitialization, AllowExplicit,<br class=""> /*OnlyListConstructors=*/false,<br class="">@@ -3821,8 +3852,8 @@ static void TryListInitialization(Sema &<br class=""> QualType InitType = InitList->getInit(0)->getType();<br class=""> if (S.Context.hasSameUnqualifiedType(InitType, DestType) ||<br class=""> S.IsDerivedFrom(InitList->getLocStart(), InitType, DestType)) {<br class="">- Expr *InitAsExpr = InitList->getInit(0);<br class="">- TryConstructorInitialization(S, Entity, Kind, InitAsExpr, DestType,<br class="">+ Expr *InitListAsExpr = InitList;<br class="">+ TryConstructorInitialization(S, Entity, Kind, InitListAsExpr, DestType,<br class=""> Sequence, /*InitListSyntax*/ false,<br class=""> /*IsInitListCopy*/ true);<br class=""> return;<br class="">@@ -4332,16 +4363,21 @@ static void TryReferenceInitializationCo<br class="">}<br class=""><br class="">// - If the initializer expression<br class="">+ // C++14-and-before:<br class="">// - is an xvalue, class prvalue, array prvalue, or function lvalue and<br class="">// "cv1 T1" is reference-compatible with "cv2 T2"<br class="">+ // C++1z:<br class="">+ // - is an rvalue or function lvalue and "cv1 T1" is reference-compatible<br class="">+ // with "cv2 T2"<br class="">// Note: functions are handled below.<br class="">if (!T1Function &&<br class=""> (RefRelationship == Sema::Ref_Compatible ||<br class=""> (Kind.isCStyleOrFunctionalCast() &&<br class=""> RefRelationship == Sema::Ref_Related)) &&<br class=""> (InitCategory.isXValue() ||<br class="">- (InitCategory.isPRValue() && T2->isRecordType()) ||<br class="">- (InitCategory.isPRValue() && T2->isArrayType()))) {<br class="">+ (InitCategory.isPRValue() &&<br class="">+ (S.getLangOpts().CPlusPlus1z || T2->isRecordType() ||<br class="">+ T2->isArrayType())))) {<br class=""> ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue;<br class=""> if (InitCategory.isPRValue() && T2->isRecordType()) {<br class=""> // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the<br class="">@@ -6604,7 +6640,26 @@ InitializationSequence::Perform(Sema &S,<br class=""> CreatedObject = Conversion->getReturnType()->isRecordType();<br class=""> }<br class=""><br class="">+ // C++14 and before:<br class="">+ // - if the function is a constructor, the call initializes a temporary<br class="">+ // of the cv-unqualified version of the destination type [...]<br class="">+ // C++1z:<br class="">+ // - if the function is a constructor, the call is a prvalue of the<br class="">+ // cv-unqualified version of the destination type whose return object<br class="">+ // is initialized by the constructor [...]<br class="">+ // Both:<br class="">+ // The [..] call is used to direct-initialize, according to the rules<br class="">+ // above, the object that is the destination of the<br class="">+ // copy-initialization.<br class="">+ // In C++14 and before, that always means the "constructors are<br class="">+ // considered" bullet, because we have arrived at a reference-related<br class="">+ // type. In C++1z, it only means that if the types are different or we<br class="">+ // didn't produce a prvalue, so just check for that case here.<br class=""> bool RequiresCopy = !IsCopy && !isReferenceBinding(Steps.back());<br class="">+ if (S.getLangOpts().CPlusPlus1z && CurInit.get()->isRValue() &&<br class="">+ S.Context.hasSameUnqualifiedType(<br class="">+ Entity.getType().getNonReferenceType(), CurInit.get()->getType()))<br class="">+ RequiresCopy = false;<br class=""> bool MaybeBindToTemp = RequiresCopy || shouldBindAsTemporary(Entity);<br class=""><br class=""> if (!MaybeBindToTemp && CreatedObject && shouldDestroyTemporary(Entity)) {<br class=""><br class="">Modified: cfe/trunk/lib/Sema/SemaOverload.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)<br class="">+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -4979,7 +4979,7 @@ TryObjectArgumentInitialization(Sema &S,<br class="">// cv-qualification on the member function declaration.<br class="">//<br class="">// However, when finding an implicit conversion sequence for the argument, we<br class="">- // are not allowed to create temporaries or perform user-defined conversions<br class="">+ // are not allowed to perform user-defined conversions<br class="">// (C++ [over.match.funcs]p5). We perform a simplified version of<br class="">// reference binding here, that allows class rvalues to bind to<br class="">// non-constant references.<br class=""><br class="">Modified: cfe/trunk/test/CXX/drs/dr0xx.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr0xx.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/test/CXX/drs/dr0xx.cpp (original)<br class="">+++ cfe/trunk/test/CXX/drs/dr0xx.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -248,7 +248,7 @@ namespace dr20 { // dr20: yes<br class="">private:<br class=""> X(const X&); // expected-note {{here}}<br class="">};<br class="">- X f();<br class="">+ X &f();<br class="">X x = f(); // expected-error {{private}}<br class="">}<br class=""><br class="">@@ -316,8 +316,15 @@ namespace dr25 { // dr25: yes<br class="">namespace dr26 { // dr26: yes<br class="">struct A { A(A, const A & = A()); }; // expected-error {{must pass its first argument by reference}}<br class="">struct B {<br class="">- B(); // expected-note {{candidate}}<br class="">- B(const B &, B = B()); // expected-error {{no matching constructor}} expected-note {{candidate}} expected-note {{here}}<br class="">+ B(); // expected-note 0-1{{candidate}}<br class="">+ B(const B &, B = B());<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no matching constructor}} expected-note@-2 {{candidate}} expected-note@-2 {{here}}<br class="">+#endif<br class="">+ };<br class="">+ struct C {<br class="">+ static C &f();<br class="">+ C(const C &, C = f()); // expected-error {{no matching constructor}} expected-note {{candidate}} expected-note {{here}}<br class="">};<br class="">}<br class=""><br class="">@@ -662,25 +669,33 @@ namespace dr58 { // dr58: yes<br class=""><br class="">namespace dr59 { // dr59: yes<br class="">template<typename T> struct convert_to { operator T() const; };<br class="">- struct A {}; // expected-note 2{{volatile qualifier}} expected-note 2{{requires 0 arguments}}<br class="">- struct B : A {}; // expected-note 2{{volatile qualifier}} expected-note 2{{requires 0 arguments}}<br class="">-#if __cplusplus >= 201103L // move constructors<br class="">- // expected-note@-3 2{{volatile qualifier}}<br class="">- // expected-note@-3 2{{volatile qualifier}}<br class="">-#endif<br class="">+ struct A {}; // expected-note 5+{{candidate}}<br class="">+ struct B : A {}; // expected-note 0+{{candidate}}<br class=""><br class="">A a1 = convert_to<A>();<br class="">A a2 = convert_to<A&>();<br class="">A a3 = convert_to<const A>();<br class="">- A a4 = convert_to<const volatile A>(); // expected-error {{no viable}}<br class="">+ A a4 = convert_to<const volatile A>();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no viable}}<br class="">+#endif<br class="">A a5 = convert_to<const volatile A&>(); // expected-error {{no viable}}<br class=""><br class="">B b1 = convert_to<B>();<br class="">B b2 = convert_to<B&>();<br class="">B b3 = convert_to<const B>();<br class="">- B b4 = convert_to<const volatile B>(); // expected-error {{no viable}}<br class="">+ B b4 = convert_to<const volatile B>();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no viable}}<br class="">+#endif<br class="">B b5 = convert_to<const volatile B&>(); // expected-error {{no viable}}<br class=""><br class="">+ A c1 = convert_to<B>();<br class="">+ A c2 = convert_to<B&>();<br class="">+ A c3 = convert_to<const B>();<br class="">+ A c4 = convert_to<const volatile B>(); // expected-error {{no viable}}<br class="">+ A c5 = convert_to<const volatile B&>(); // expected-error {{no viable}}<br class="">+<br class="">int n1 = convert_to<int>();<br class="">int n2 = convert_to<int&>();<br class="">int n3 = convert_to<const int>();<br class="">@@ -920,14 +935,17 @@ namespace dr84 { // dr84: yes<br class="">struct A { operator B() const; };<br class="">struct C {};<br class="">struct B {<br class="">- B(B&); // expected-note {{candidate}}<br class="">- B(C); // expected-note {{no known conversion from 'dr84::B' to 'dr84::C'}}<br class="">+ B(B&); // expected-note 0-1{{candidate}}<br class="">+ B(C); // expected-note 0-1{{no known conversion from 'dr84::B' to 'dr84::C'}}<br class=""> operator C() const;<br class="">};<br class="">A a;<br class="">// Cannot use B(C) / operator C() pair to construct the B from the B temporary<br class="">- // here.<br class="">- B b = a; // expected-error {{no viable}}<br class="">+ // here. In C++1z, we initialize the B object directly using 'A::operator B()'.<br class="">+ B b = a;<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no viable}}<br class="">+#endif<br class="">}<br class=""><br class="">namespace dr85 { // dr85: yes<br class=""><br class="">Modified: cfe/trunk/test/CXX/drs/dr10xx.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr10xx.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr10xx.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/test/CXX/drs/dr10xx.cpp (original)<br class="">+++ cfe/trunk/test/CXX/drs/dr10xx.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -3,8 +3,6 @@<br class="">// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br class="">// RUN: %clang_cc1 -std=c++1z %s -verify -fexceptions -fcxx-exceptions -pedantic-errors<br class=""><br class="">-// expected-no-diagnostics<br class="">-<br class="">namespace std {<br class="">__extension__ typedef __SIZE_TYPE__ size_t;<br class=""><br class="">@@ -32,6 +30,18 @@ namespace dr1048 { // dr1048: 3.6<br class="">#endif<br class="">}<br class=""><br class="">+namespace dr1054 { // dr1054: no<br class="">+ // FIXME: Test is incomplete.<br class="">+ struct A {} volatile a;<br class="">+ void f() {<br class="">+ // FIXME: This is wrong: an lvalue-to-rvalue conversion is applied here,<br class="">+ // which copy-initializes a temporary from 'a'. Therefore this is<br class="">+ // ill-formed because A does not have a volatile copy constructor.<br class="">+ // (We might want to track this aspect under dr1383 instead?)<br class="">+ a; // expected-warning {{assign into a variable to force a volatile load}}<br class="">+ }<br class="">+}<br class="">+<br class="">namespace dr1070 { // dr1070: 3.5<br class="">#if __cplusplus >= 201103L<br class="">struct A {<br class=""><br class="">Modified: cfe/trunk/test/CXX/drs/dr1xx.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr1xx.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/test/CXX/drs/dr1xx.cpp (original)<br class="">+++ cfe/trunk/test/CXX/drs/dr1xx.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -576,11 +576,18 @@ namespace dr151 { // dr151: yes<br class=""><br class="">namespace dr152 { // dr152: yes<br class="">struct A {<br class="">- A(); // expected-note {{not viable}}<br class="">+ A(); // expected-note 0-2{{not viable}}<br class=""> explicit A(const A&);<br class="">};<br class="">- A a1 = A(); // expected-error {{no matching constructor}}<br class="">+ A a1 = A();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no matching constructor}}<br class="">+#endif<br class="">A a2((A()));<br class="">+<br class="">+ A &f();<br class="">+ A a3 = f(); // expected-error {{no matching constructor}}<br class="">+ A a4(f());<br class="">}<br class=""><br class="">// dr153: na<br class="">@@ -823,11 +830,20 @@ namespace dr176 { // dr176: yes<br class="">namespace dr177 { // dr177: yes<br class="">struct B {};<br class="">struct A {<br class="">- A(A &); // expected-note {{not viable: expects an l-value}}<br class="">- A(const B &); // expected-note {{not viable: no known conversion from 'dr177::A' to}}<br class="">+ A(A &); // expected-note 0-1{{not viable: expects an l-value}}<br class="">+ A(const B &); // expected-note 0-1{{not viable: no known conversion from 'dr177::A' to}}<br class="">};<br class="">B b;<br class="">- A a = b; // expected-error {{no viable constructor copying variable}}<br class="">+ A a = b;<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{no viable constructor copying variable}}<br class="">+#endif<br class="">+<br class="">+ struct C { C(C&); }; // expected-note {{not viable: no known conversion from 'dr177::D' to 'dr177::C &'}}<br class="">+ struct D : C {};<br class="">+ struct E { operator D(); };<br class="">+ E e;<br class="">+ C c = e; // expected-error {{no viable constructor copying variable of type 'dr177::D'}}<br class="">}<br class=""><br class="">namespace dr178 { // dr178: yes<br class=""><br class="">Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)<br class="">+++ cfe/trunk/test/CXX/drs/dr4xx.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -553,12 +553,21 @@ namespace dr446 { // dr446: yes<br class=""> void(b ? a : a);<br class=""> b ? A() : a; // expected-error {{deleted}}<br class=""> b ? a : A(); // expected-error {{deleted}}<br class="">- b ? A() : A(); // expected-error {{deleted}}<br class="">+ b ? A() : A();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{deleted}}<br class="">+#endif<br class=""><br class=""> void(b ? a : c);<br class=""> b ? a : C(); // expected-error {{deleted}}<br class="">- b ? c : A(); // expected-error {{deleted}}<br class="">- b ? A() : C(); // expected-error {{deleted}}<br class="">+ b ? c : A();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{deleted}}<br class="">+#endif<br class="">+ b ? A() : C();<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{deleted}}<br class="">+#endif<br class="">}<br class="">}<br class=""><br class="">@@ -874,10 +883,12 @@ namespace dr479 { // dr479: yes<br class="">void f() {<br class=""> throw S();<br class=""> // expected-error@-1 {{temporary of type 'dr479::S' has private destructor}}<br class="">- // expected-error@-2 {{calling a private constructor}}<br class="">- // expected-error@-3 {{exception object of type 'dr479::S' has private destructor}}<br class="">+ // expected-error@-2 {{exception object of type 'dr479::S' has private destructor}}<br class="">#if __cplusplus < 201103L<br class="">- // expected-error@-5 {{C++98 requires an accessible copy constructor}}<br class="">+ // expected-error@-4 {{C++98 requires an accessible copy constructor}}<br class="">+#endif<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-7 {{calling a private constructor}} (copy ctor)<br class="">#endif<br class="">}<br class="">void g() {<br class=""><br class="">Added: cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp?</a>rev=288866&view=auto<br class="">==============================================================================<br class="">--- cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp (added)<br class="">+++ cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -0,0 +1,81 @@<br class="">+// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s<br class="">+<br class="">+struct A {<br class="">+ A(int);<br class="">+ A(A&&);<br class="">+ A(const A&);<br class="">+ ~A();<br class="">+<br class="">+ int arr[10];<br class="">+};<br class="">+<br class="">+A f();<br class="">+void h();<br class="">+<br class="">+// CHECK-LABEL: define {{.*}} @_Z1gv(<br class="">+void g() {<br class="">+ // CHECK: %[[A:.*]] = alloca<br class="">+ // CHECK-NOT: alloca<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])<br class="">+ A a = A( A{ f() } );<br class="">+ // CHECK-NOT: call<br class="">+<br class="">+ // CHECK: call void @_Z1hv(<br class="">+ h();<br class="">+ // CHECK-NOT: call<br class="">+<br class="">+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK-LABEL: }<br class="">+}<br class="">+<br class="">+void f(A);<br class="">+<br class="">+// CHECK-LABEL: define {{.*}} @_Z1hv(<br class="">+void h() {<br class="">+ // CHECK: %[[A:.*]] = alloca<br class="">+ // CHECK-NOT: alloca<br class="">+ // CHECK-NOT: call<br class="">+<br class="">+ // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])<br class="">+ f(f());<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])<br class="">+<br class="">+ // CHECK: call void @_Z1hv(<br class="">+ h();<br class="">+<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK-LABEL: }<br class="">+}<br class="">+<br class="">+// We still pass classes with trivial copy/move constructors and destructors in<br class="">+// registers, even if the copy is formally omitted.<br class="">+struct B {<br class="">+ B(int);<br class="">+ int n;<br class="">+};<br class="">+<br class="">+B fB();<br class="">+void fB(B);<br class="">+<br class="">+// CHECK-LABEL: define {{.*}} @_Z1iv(<br class="">+void i() {<br class="">+ // CHECK: %[[B:.*]] = alloca<br class="">+ // CHECK-NOT: alloca<br class="">+ // CHECK-NOT: call<br class="">+<br class="">+ // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: store i32 %[[B_N]],<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: %[[B_N:.*]] = load i32<br class="">+ // CHECK-NOT: call<br class="">+ // CHECK: call void @_Z2fB1B(i32 %[[B_N]])<br class="">+ fB(fB());<br class="">+<br class="">+ // CHECK-LABEL: }<br class="">+}<br class=""><br class="">Modified: cfe/trunk/test/SemaCXX/aggregate-initialization.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/aggregate-initialization.cpp?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaCXX/aggregate-initialization.cpp (original)<br class="">+++ cfe/trunk/test/SemaCXX/aggregate-initialization.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -57,7 +57,7 @@ struct A {<br class="">A(int);<br class="">~A();<br class=""><br class="">- A(const A&) = delete; // expected-note 2 {{'A' has been explicitly marked deleted here}}<br class="">+ A(const A&) = delete; // expected-note 0-2{{'A' has been explicitly marked deleted here}}<br class="">};<br class=""><br class="">struct B {<br class="">@@ -70,10 +70,16 @@ struct C {<br class=""><br class="">void f() {<br class="">A as1[1] = { };<br class="">- A as2[1] = { 1 }; // expected-error {{copying array element of type 'A' invokes deleted constructor}}<br class="">+ A as2[1] = { 1 };<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{copying array element of type 'A' invokes deleted constructor}}<br class="">+#endif<br class=""><br class="">B b1 = { };<br class="">- B b2 = { 1 }; // expected-error {{copying member subobject of type 'A' invokes deleted constructor}}<br class="">+ B b2 = { 1 };<br class="">+#if __cplusplus <= 201402L<br class="">+ // expected-error@-2 {{copying member subobject of type 'A' invokes deleted constructor}}<br class="">+#endif<br class=""><br class="">C c1 = { 1 };<br class="">}<br class=""><br class="">Added: cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp?</a>rev=288866&view=auto<br class="">==============================================================================<br class="">--- cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp (added)<br class="">+++ cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp Tue Dec 6 17:52:28 2016<br class="">@@ -0,0 +1,134 @@<br class="">+// RUN: %clang_cc1 -std=c++1z -verify %s<br class="">+<br class="">+struct Noncopyable {<br class="">+ Noncopyable();<br class="">+ Noncopyable(const Noncopyable &) = delete; // expected-note 1+{{deleted}}<br class="">+ virtual ~Noncopyable();<br class="">+};<br class="">+struct Derived : Noncopyable {};<br class="">+struct NoncopyableAggr {<br class="">+ Noncopyable nc;<br class="">+};<br class="">+struct Indestructible {<br class="">+ Indestructible();<br class="">+ ~Indestructible() = delete; // expected-note 1+{{deleted}}<br class="">+};<br class="">+struct Incomplete; // expected-note 1+{{declar}}<br class="">+<br class="">+Noncopyable make(int kind = 0) {<br class="">+ switch (kind) {<br class="">+ case 0: return {};<br class="">+ case 1: return Noncopyable();<br class="">+ case 2: return Noncopyable{};<br class="">+ case 3: return make();<br class="">+ }<br class="">+ __builtin_unreachable();<br class="">+}<br class="">+<br class="">+Indestructible make_indestructible();<br class="">+Incomplete make_incomplete(); // expected-note 1+{{here}}<br class="">+<br class="">+void take(Noncopyable nc) {}<br class="">+<br class="">+Noncopyable nrvo() {<br class="">+ Noncopyable nrvo;<br class="">+ return nrvo; // expected-error {{deleted constructor}}<br class="">+}<br class="">+<br class="">+Noncopyable nc1 = make();<br class="">+Noncopyable nc2 = Noncopyable();<br class="">+Noncopyable nc3 = Derived(); // expected-error {{deleted constructor}}<br class="">+<br class="">+NoncopyableAggr nca1 = NoncopyableAggr{};<br class="">+NoncopyableAggr nca2 = NoncopyableAggr{{}};<br class="">+NoncopyableAggr nca3 = NoncopyableAggr{NoncopyableAggr{Noncopyable()}};<br class="">+<br class="">+void test_expressions(bool b) {<br class="">+ auto lambda = [a = make()] {};<br class="">+<br class="">+ take({});<br class="">+ take(Noncopyable());<br class="">+ take(Noncopyable{});<br class="">+ take(make());<br class="">+<br class="">+ Noncopyable &&dc1 = dynamic_cast<Noncopyable&&>(Noncopyable());<br class="">+ Noncopyable &&dc2 = dynamic_cast<Noncopyable&&>(nc1);<br class="">+ Noncopyable &&dc3 = dynamic_cast<Noncopyable&&>(Derived());<br class="">+<br class="">+ Noncopyable sc1 = static_cast<Noncopyable>(Noncopyable());<br class="">+ Noncopyable sc2 = static_cast<Noncopyable>(nc1); // expected-error {{deleted}}<br class="">+ Noncopyable sc3 = static_cast<Noncopyable&&>(Noncopyable()); // expected-error {{deleted}}<br class="">+ Noncopyable sc4 = static_cast<Noncopyable>(static_cast<Noncopyable&&>(Noncopyable())); // expected-error {{deleted}}<br class="">+<br class="">+ Noncopyable cc1 = (Noncopyable)Noncopyable();<br class="">+ Noncopyable cc2 = (Noncopyable)Derived(); // expected-error {{deleted}}<br class="">+<br class="">+ Noncopyable fc1 = Noncopyable(Noncopyable());<br class="">+ Noncopyable fc2 = Noncopyable(Derived()); // expected-error {{deleted}}<br class="">+<br class="">+ // We must check for a complete type for every materialized temporary. (Note<br class="">+ // that in the special case of the top level of a decltype, no temporary is<br class="">+ // materialized.)<br class="">+ make_incomplete(); // expected-error {{incomplete}}<br class="">+ make_incomplete().a; // expected-error {{incomplete}}<br class="">+ make_incomplete().*(int Incomplete::*)nullptr; // expected-error {{incomplete}}<br class="">+ dynamic_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}<br class="">+ const_cast<Incomplete&&>(make_incomplete()); // expected-error {{incomplete}}<br class="">+<br class="">+ sizeof(Indestructible{}); // expected-error {{deleted}}<br class="">+ sizeof(make_indestructible()); // expected-error {{deleted}}<br class="">+ sizeof(make_incomplete()); // expected-error {{incomplete}}<br class="">+ typeid(Indestructible{}); // expected-error {{deleted}}<br class="">+ typeid(make_indestructible()); // expected-error {{deleted}}<br class="">+ typeid(make_incomplete()); // expected-error {{incomplete}}<br class="">+<br class="">+ // FIXME: The first two cases here are now also valid in C++17 onwards.<br class="">+ using I = decltype(Indestructible()); // expected-error {{deleted}}<br class="">+ using I = decltype(Indestructible{}); // expected-error {{deleted}}<br class="">+ using I = decltype(make_indestructible());<br class="">+ using J = decltype(make_incomplete());<br class="">+<br class="">+ Noncopyable cond1 = b ? Noncopyable() : make();<br class="">+ Noncopyable cond2 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}<br class="">+ Noncopyable cond3 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}<br class="">+ Noncopyable cond4 = b ? Noncopyable() : nc1; // expected-error {{deleted}}<br class="">+ Noncopyable cond5 = b ? nc1 : Noncopyable(); // expected-error {{deleted}}<br class="">+ // Could convert both to an xvalue of type Noncopyable here, but we're not<br class="">+ // permitted to consider that.<br class="">+ Noncopyable &&cond6 = b ? Noncopyable() : Derived(); // expected-error {{incompatible}}<br class="">+ Noncopyable &&cond7 = b ? Derived() : Noncopyable(); // expected-error {{incompatible}}<br class="">+ // Could convert both to a const lvalue of type Noncopyable here, but we're<br class="">+ // not permitted to consider that, either.<br class="">+ const Noncopyable cnc;<br class="">+ const Noncopyable &cond8 = b ? cnc : Derived(); // expected-error {{incompatible}}<br class="">+ const Noncopyable &cond9 = b ? Derived() : cnc; // expected-error {{incompatible}}<br class="">+<br class="">+ extern const volatile Noncopyable make_cv();<br class="">+ Noncopyable cv_difference1 = make_cv();<br class="">+ const volatile Noncopyable cv_difference2 = make();<br class="">+}<br class="">+<br class="">+template<typename T> struct ConversionFunction { operator T(); };<br class="">+Noncopyable cf1 = ConversionFunction<Noncopyable>();<br class="">+Noncopyable cf2 = ConversionFunction<Noncopyable&&>(); // expected-error {{deleted}}<br class="">+Noncopyable cf3 = ConversionFunction<const volatile Noncopyable>();<br class="">+const volatile Noncopyable cf4 = ConversionFunction<Noncopyable>();<br class="">+Noncopyable cf5 = ConversionFunction<Derived>(); // expected-error {{deleted}}<br class="">+<br class="">+struct AsMember {<br class="">+ Noncopyable member;<br class="">+ AsMember() : member(make()) {}<br class="">+};<br class="">+// FIXME: DR (no number yet): we still get a copy for base or delegating construction.<br class="">+struct AsBase : Noncopyable {<br class="">+ AsBase() : Noncopyable(make()) {} // expected-error {{deleted}}<br class="">+};<br class="">+struct AsDelegating final {<br class="">+ AsDelegating(const AsDelegating &) = delete;<br class="">+ static AsDelegating make(int);<br class="">+<br class="">+ // The base constructor version of this is problematic; the complete object<br class="">+ // version would be OK. Perhaps we could allow copy omission here for final<br class="">+ // classes?<br class="">+ AsDelegating(int n) : AsDelegating(make(n)) {} // expected-error {{deleted}}<br class="">+};<br class=""><br class="">Modified: cfe/trunk/www/cxx_dr_status.html<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/www/cxx_dr_status.html (original)<br class="">+++ cfe/trunk/www/cxx_dr_status.html Tue Dec 6 17:52:28 2016<br class="">@@ -6139,7 +6139,7 @@ and <I>POD class</I></td><br class=""> <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1054" class="">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1054</a>">1054</a></td><br class=""> <td>C++11</td><br class=""> <td>Lvalue-to-rvalue conversions in expression statements</td><br class="">- <td class="none" align="center">Unknown</td><br class="">+ <td class="none" align="center">No</td><br class=""></tr><br class=""><tr id="1055"><br class=""> <td><a href="<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1055" class="">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1055</a>">1055</a></td><br class=""><br class="">Modified: cfe/trunk/www/cxx_status.html<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?</a>rev=288866&r1=288865&r2=288866&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/www/cxx_status.html (original)<br class="">+++ cfe/trunk/www/cxx_status.html Tue Dec 6 17:52:28 2016<br class="">@@ -694,7 +694,7 @@ as the draft C++1z standard evolves.<br class=""> <tr><br class=""> <td>Guaranteed copy elision</td><br class=""> <td><a href="<a href="http://wg21.link/p0135r1" class="">http://wg21.link/p0135r1</a>">P0135R1</a></td><br class="">- <td class="none" align="center">No</td><br class="">+ <td class="svn" align="center">SVN</td><br class=""> </tr><br class=""> <tr><br class=""> <td rowspan=2>Stricter expression evaluation order</td><br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></blockquote><br class=""></blockquote><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""></blockquote><br class=""></div></body></html>