File tree Expand file tree Collapse file tree 2 files changed +20
-1
lines changed
Expand file tree Collapse file tree 2 files changed +20
-1
lines changed Original file line number Diff line number Diff line change @@ -3235,7 +3235,8 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
32353235 return this ->visitInitializer (E->getArg (0 ));
32363236
32373237 // Zero initialization.
3238- if (E->requiresZeroInitialization ()) {
3238+ bool ZeroInit = E->requiresZeroInitialization ();
3239+ if (ZeroInit) {
32393240 const Record *R = getRecord (E->getType ());
32403241
32413242 if (!this ->visitZeroRecordInitializer (R, E))
@@ -3246,6 +3247,16 @@ bool Compiler<Emitter>::VisitCXXConstructExpr(const CXXConstructExpr *E) {
32463247 return true ;
32473248 }
32483249
3250+ // Avoid materializing a temporary for an elidable copy/move constructor.
3251+ if (!ZeroInit && E->isElidable ()) {
3252+ const Expr *SrcObj = E->getArg (0 );
3253+ assert (SrcObj->isTemporaryObject (Ctx.getASTContext (), Ctor->getParent ()));
3254+ assert (Ctx.getASTContext ().hasSameUnqualifiedType (E->getType (),
3255+ SrcObj->getType ()));
3256+ if (const auto *ME = dyn_cast<MaterializeTemporaryExpr>(SrcObj))
3257+ return this ->visitInitializer (ME->getSubExpr ());
3258+ }
3259+
32493260 const Function *Func = getFunction (Ctor);
32503261
32513262 if (!Func)
Original file line number Diff line number Diff line change @@ -379,3 +379,11 @@ namespace DiscardedAddrLabel {
379379 }
380380}
381381
382+ struct Counter {
383+ int copies;
384+ constexpr Counter (int copies) : copies(copies) {}
385+ constexpr Counter (const Counter& other) : copies(other.copies + 1 ) {}
386+ };
387+ // Passing an lvalue by value makes a non-elidable copy.
388+ constexpr int PassByValue (Counter c) { return c.copies ; }
389+ static_assert (PassByValue(Counter(0 )) == 0 , " expect no copies" );
You can’t perform that action at this time.
0 commit comments