Merged to release_90 in r367804.
On Thu, Aug 1, 2019 at 10:00 AM Hans Wennborg via cfe-commits <cfe-commits@lists.llvm.org> wrote: > > Author: hans > Date: Thu Aug 1 01:01:09 2019 > New Revision: 367520 > > URL: http://llvm.org/viewvc/llvm-project?rev=367520&view=rev > Log: > Delay emitting dllexport explicitly defaulted members until the class is > fully parsed (PR40006) > > This is similar to r245139, but that only addressed dllexported classes. > It was still possible to run into the same problem with dllexported > members in an otherwise normal class (see bug). This uses the same > strategy to fix: delay defining the method until the whole class has > been parsed. > > (The easiest way to see the ordering problem is in > Parser::ParseCXXMemberSpecification(): it calls > ParseLexedMemberInitializers() *after* ActOnFinishCXXMemberDecls(), > which was trying to define the dllexport method. Now we delay it to > ActOnFinishCXXNonNestedClass() which is called after both of those.) > > Differential revision: https://reviews.llvm.org/D65511 > > Modified: > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Sema/Sema.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/test/CodeGenCXX/dllexport.cpp > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=367520&r1=367519&r2=367520&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Thu Aug 1 01:01:09 2019 > @@ -11136,6 +11136,7 @@ public: > // Emitting members of dllexported classes is delayed until the class > // (including field initializers) is fully parsed. > SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; > + SmallVector<CXXMethodDecl*, 4> DelayedDllExportMemberFunctions; > > private: > class SavePendingParsedClassStateRAII { > > Modified: cfe/trunk/lib/Sema/Sema.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=367520&r1=367519&r2=367520&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/Sema.cpp (original) > +++ cfe/trunk/lib/Sema/Sema.cpp Thu Aug 1 01:01:09 2019 > @@ -961,6 +961,7 @@ void Sema::ActOnEndOfTranslationUnit() { > > // All dllexport classes should have been processed already. > assert(DelayedDllExportClasses.empty()); > + assert(DelayedDllExportMemberFunctions.empty()); > > // Remove file scoped decls that turned out to be used. > UnusedFileScopedDecls.erase( > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=367520&r1=367519&r2=367520&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 1 01:01:09 2019 > @@ -6283,8 +6283,8 @@ void Sema::CheckCompletedCXXClass(CXXRec > M->dropAttr<DLLExportAttr>(); > > if (M->hasAttr<DLLExportAttr>()) { > - DefineImplicitSpecialMember(*this, M, M->getLocation()); > - ActOnFinishInlineFunctionDef(M); > + // Define after any fields with in-class initializers have been > parsed. > + DelayedDllExportMemberFunctions.push_back(M); > } > } > }; > @@ -11537,6 +11537,15 @@ void Sema::ActOnFinishCXXMemberDecls() { > > void Sema::ActOnFinishCXXNonNestedClass(Decl *D) { > referenceDLLExportedClassMethods(); > + > + if (!DelayedDllExportMemberFunctions.empty()) { > + SmallVector<CXXMethodDecl*, 4> WorkList; > + std::swap(DelayedDllExportMemberFunctions, WorkList); > + for (CXXMethodDecl *M : WorkList) { > + DefineImplicitSpecialMember(*this, M, M->getLocation()); > + ActOnFinishInlineFunctionDef(M); > + } > + } > } > > void Sema::referenceDLLExportedClassMethods() { > > Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=367520&r1=367519&r2=367520&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) > +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Thu Aug 1 01:01:09 2019 > @@ -851,6 +851,15 @@ struct __declspec(dllexport) Baz { > // Baz's operator=, causing instantiation of Foo<int> after which > // ActOnFinishCXXNonNestedClass is called, and we would bite our own tail. > // M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc > dereferenceable(1) %"struct.InClassInits::Baz"* > @"??4Baz@InClassInits@@QAEAAU01@ABU01@@Z" > + > +// Trying to define the explicitly defaulted ctor must be delayed until the > +// in-class initializer for x has been processed. > +struct PR40006 { > + __declspec(dllexport) PR40006() = default; > + int x = 42; > +}; > +// M32-DAG: define weak_odr dso_local dllexport x86_thiscallcc > %"struct.InClassInits::PR40006"* @"??0PR40006@InClassInits@@QAE@XZ" > + > } > > // We had an issue where instantiating A would force emission of B's delayed > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits