[PATCH] D119409: [C++20] [Modules] Remain dynamic initializing internal-linkage variables in module interface unit

Chuanqi Xu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 18 00:38:37 PST 2022


ChuanqiXu updated this revision to Diff 409872.
ChuanqiXu retitled this revision from "[C++20] [Modules] Remain internal-linkage variables in module interface unit" to "[C++20] [Modules] Remain dynamic initializing internal-linkage variables in module interface unit ".
ChuanqiXu edited the summary of this revision.
ChuanqiXu added a comment.

Address comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119409/new/

https://reviews.llvm.org/D119409

Files:
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/test/CodeGenCXX/static-variable-in-module.cpp


Index: clang/test/CodeGenCXX/static-variable-in-module.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/static-variable-in-module.cpp
@@ -0,0 +1,34 @@
+// RUN: rm -fr %t
+// RUN: mkdir %t
+// RUN: echo "struct S { S(); };" >> %t/foo.h
+// RUN: echo "static S s = S();" >> %t/foo.h
+// RUN: echo "static int static_init_gmf = 43;" >> %t/foo.h
+// RUN: %clang_cc1 -std=c++20 -I%t %s -emit-module-interface -o %t/m.pcm
+// RUN: %clang_cc1 -std=c++20 %t/m.pcm -triple %itanium_abi_triple -S -emit-llvm -o - | FileCheck %s
+module;
+#include "foo.h"
+export module m;
+class A {
+public:
+  A();
+};
+static A a = A();
+static int static_init = 43;
+
+// We shouldn't emit unused internal linkage variable.
+// CHECK-NOT: static_init_gmf
+// CHECK: @_ZW1mEL1s = internal global %struct.S zeroinitializer
+// CHECK: @_ZW1mE1a = {{(dso_local )?}}global %class.A zeroinitializer
+// This is surprising at the first sight. But given [basic.link]4.8:
+//  - otherwise, if the declaration of the name is attached to a named module ([module.unit]) and is not exported ([module.interface]), the name has module linkage;
+//
+// So static_init has module linkage instead of internal linkage. So we should emit it even if it is not used.
+// CHECK: @_ZW1mE11static_init = global i32 43
+// CHECK: @llvm.global_ctors = appending global{{.*}}@_GLOBAL__sub_I_m.pcm
+// CHECK: define {{.*}}__cxx_global_var_init[[SUFFIX:[^)]*]]
+// CHECK: call void @_ZN1SC1Ev
+// CHECK: define {{.*}}__cxx_global_var_init[[SUFFIX2:[^)]*]]
+// CHECK: call void @_ZW1mEN1AC1Ev
+// CHECK: define {{.*}}@_GLOBAL__sub_I_m.pcm
+// CHECK: call void @__cxx_global_var_init[[SUFFIX]]
+// CHECK: call void @__cxx_global_var_init[[SUFFIX2]]
Index: clang/lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- clang/lib/Serialization/ASTWriterDecl.cpp
+++ clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1022,15 +1022,27 @@
     if (Writer.WritingModule &&
         !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
         !isa<VarTemplateSpecializationDecl>(D)) {
-      // When building a C++ Modules TS module interface unit, a strong
-      // definition in the module interface is provided by the compilation of
-      // that module interface unit, not by its users. (Inline variables are
-      // still emitted in module users.)
-      ModulesCodegen =
-          (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit ||
-           (D->hasAttr<DLLExportAttr>() &&
-            Writer.Context->getLangOpts().BuildingPCHWithObjectFile)) &&
-          Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
+      // When building a C++20 Modules module interface unit, a strong
+      // definition in the module interface is provided by the module interface
+      // unit, not by its users. (Inline variables are still emitted in module
+      // users.)
+      auto Linkage = Writer.Context->GetGVALinkageForVariable(D);
+      if (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit) {
+        ModulesCodegen = Linkage == GVA_StrongExternal;
+        if (Linkage == GVA_Internal) {
+          // FIXME: We emit internal variable with dynamic initializer here
+          // otherwise we would fail to compile a hello-world example. (See
+          // https://github.com/llvm/llvm-project/issues/51873). Look back here
+          // once we get rules in CXXABI for variables in named module.
+          const VarDecl *InitDecl;
+          const Expr *InitExpr = D->getAnyInitializer(InitDecl);
+          ModulesCodegen = InitExpr && InitDecl;
+        }
+      } else
+        ModulesCodegen =
+            D->hasAttr<DLLExportAttr>() &&
+            Writer.Context->getLangOpts().BuildingPCHWithObjectFile &&
+            Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal;
     }
     Record.push_back(ModulesCodegen);
     if (ModulesCodegen)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119409.409872.patch
Type: text/x-patch
Size: 3984 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220218/eb522706/attachment-0001.bin>


More information about the cfe-commits mailing list