[llvm-branch-commits] [cfe-branch] r367804 - Merging r367520:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 5 00:27:39 PDT 2019


Author: hans
Date: Mon Aug  5 00:27:39 2019
New Revision: 367804

URL: http://llvm.org/viewvc/llvm-project?rev=367804&view=rev
Log:
Merging r367520:
------------------------------------------------------------------------
r367520 | hans | 2019-08-01 10:01:09 +0200 (Thu, 01 Aug 2019) | 15 lines

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/branches/release_90/   (props changed)
    cfe/branches/release_90/include/clang/Sema/Sema.h
    cfe/branches/release_90/lib/Sema/Sema.cpp
    cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp
    cfe/branches/release_90/test/CodeGenCXX/dllexport.cpp

Propchange: cfe/branches/release_90/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug  5 00:27:39 2019
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:366429,366448,366457,366474,366480,366483,366511,366670,366694,366699,366878,367008,367039,367055,367103,367134,367301,367305,367323,367387,367530
+/cfe/trunk:366429,366448,366457,366474,366480,366483,366511,366670,366694,366699,366878,367008,367039,367055,367103,367134,367301,367305,367323,367387,367520,367530
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_90/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/include/clang/Sema/Sema.h?rev=367804&r1=367803&r2=367804&view=diff
==============================================================================
--- cfe/branches/release_90/include/clang/Sema/Sema.h (original)
+++ cfe/branches/release_90/include/clang/Sema/Sema.h Mon Aug  5 00:27:39 2019
@@ -11165,6 +11165,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/branches/release_90/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/lib/Sema/Sema.cpp?rev=367804&r1=367803&r2=367804&view=diff
==============================================================================
--- cfe/branches/release_90/lib/Sema/Sema.cpp (original)
+++ cfe/branches/release_90/lib/Sema/Sema.cpp Mon Aug  5 00:27:39 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/branches/release_90/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp?rev=367804&r1=367803&r2=367804&view=diff
==============================================================================
--- cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/release_90/lib/Sema/SemaDeclCXX.cpp Mon Aug  5 00:27:39 2019
@@ -6165,8 +6165,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);
       }
     }
   };
@@ -11419,6 +11419,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/branches/release_90/test/CodeGenCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_90/test/CodeGenCXX/dllexport.cpp?rev=367804&r1=367803&r2=367804&view=diff
==============================================================================
--- cfe/branches/release_90/test/CodeGenCXX/dllexport.cpp (original)
+++ cfe/branches/release_90/test/CodeGenCXX/dllexport.cpp Mon Aug  5 00:27:39 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




More information about the llvm-branch-commits mailing list