<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>