@@ -31,6 +31,8 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
3131 cgm.errorNYI (d.getSourceRange (), " emitAutoVarAlloca: address space" );
3232
3333 mlir::Location loc = getLoc (d.getSourceRange ());
34+ bool nrvo =
35+ getContext ().getLangOpts ().ElideConstructors && d.isNRVOVariable ();
3436
3537 CIRGenFunction::AutoVarEmission emission (d);
3638 emission.IsEscapingByRef = d.isEscapingByref ();
@@ -44,16 +46,37 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d,
4446 if (ty->isVariablyModifiedType ())
4547 cgm.errorNYI (d.getSourceRange (), " emitAutoVarDecl: variably modified type" );
4648
49+ assert (!cir::MissingFeatures::openMP ());
50+
4751 Address address = Address::invalid ();
4852 if (!ty->isConstantSizeType ())
4953 cgm.errorNYI (d.getSourceRange (), " emitAutoVarDecl: non-constant size type" );
5054
5155 // A normal fixed sized variable becomes an alloca in the entry block,
52- mlir::Type allocaTy = convertTypeForMem (ty);
53- // Create the temp alloca and declare variable using it.
54- address = createTempAlloca (allocaTy, alignment, loc, d.getName (),
55- /* arraySize=*/ nullptr , /* alloca=*/ nullptr , ip);
56- declare (address.getPointer (), &d, ty, getLoc (d.getSourceRange ()), alignment);
56+ // unless:
57+ // - it's an NRVO variable.
58+ // - we are compiling OpenMP and it's an OpenMP local variable.
59+ if (nrvo) {
60+ // The named return value optimization: allocate this variable in the
61+ // return slot, so that we can elide the copy when returning this
62+ // variable (C++0x [class.copy]p34).
63+ address = returnValue;
64+
65+ if (const auto *rd = ty->getAsRecordDecl ()) {
66+ if (const auto *cxxrd = dyn_cast<CXXRecordDecl>(rd);
67+ (cxxrd && !cxxrd->hasTrivialDestructor ()) ||
68+ rd->isNonTrivialToPrimitiveDestroy ())
69+ cgm.errorNYI (d.getSourceRange (), " emitAutoVarAlloca: set NRVO flag" );
70+ }
71+ } else {
72+ // A normal fixed sized variable becomes an alloca in the entry block,
73+ mlir::Type allocaTy = convertTypeForMem (ty);
74+ // Create the temp alloca and declare variable using it.
75+ address = createTempAlloca (allocaTy, alignment, loc, d.getName (),
76+ /* arraySize=*/ nullptr , /* alloca=*/ nullptr , ip);
77+ declare (address.getPointer (), &d, ty, getLoc (d.getSourceRange ()),
78+ alignment);
79+ }
5780
5881 emission.Addr = address;
5982 setAddrOfLocalVar (&d, address);
0 commit comments