r367520 - Delay emitting dllexport explicitly defaulted members until the class is fully parsed (PR40006)
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 5 00:26:52 PDT 2019
Merged to release_90 in r367804.
On Thu, Aug 1, 2019 at 10:00 AM Hans Wennborg via cfe-commits
<cfe-commits at 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 at InClassInits@@QAEAAU01 at 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 at InClassInits@@QAE at XZ"
> +
> }
>
> // We had an issue where instantiating A would force emission of B's delayed
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list