rsmith added a comment. Thank you for working on this! Please also add a test to test/CXX/drs/dr15xx.cpp with a "// dr1579: 3.9" comment (we have a script that turns those comments into www/cxx_dr_status.html).
================ Comment at: include/clang/Sema/Sema.h:3473 @@ -3472,3 +3472,3 @@ VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, - bool AllowFunctionParameters); + bool AllowParamOrMoveConstructable); bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, ---------------- Constructable -> Constructible. ================ Comment at: lib/Sema/SemaStmt.cpp:2756-2759 @@ -2755,4 +2755,6 @@ // ... the same cv-unqualified type as the function return type ... if (!VDType->isDependentType() && - !Context.hasSameUnqualifiedType(ReturnType, VDType)) - return false; + !Context.hasSameUnqualifiedType(ReturnType, VDType)) { + // When considering moving this expression out, allow dissimilar types. + if (!AllowParamOrMoveConstructable) + return false; ---------------- Combine these conditions into a single `if`, and put the (cheapest) `bool` check first. ================ Comment at: lib/Sema/SemaStmt.cpp:2773-2783 @@ -2769,13 +2772,13 @@ // ...non-volatile... if (VD->getType().isVolatileQualified()) return false; // __block variables can't be allocated in a way that permits NRVO. if (VD->hasAttr<BlocksAttr>()) return false; // Variables with higher required alignment than their type's ABI // alignment cannot use NRVO. if (!VD->getType()->isDependentType() && VD->hasAttr<AlignedAttr>() && Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VD->getType())) return false; ---------------- None of this should be checked for the `AllowParamOrMoveConstructible` case. ================ Comment at: lib/Sema/SemaStmt.cpp:2820 @@ -2814,5 +2819,3 @@ - // [...] If overload resolution fails, or if the type of the first - // parameter of the selected constructor is not an rvalue reference - // to the object's type (possibly cv-qualified), overload resolution - // is performed again, considering the object as an lvalue. + InitializationKind Kind = InitializationKind::CreateDirect( + Value->getLocStart(), Value->getLocStart(), Value->getLocEnd()); ---------------- Why are you using direct-initialization here? The return value should always be copy-initialized. http://reviews.llvm.org/D21619 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits