[C++20] [Modules] Fix the duplicated static initializer problem (#114193)

Reproducer:

```
//--- a.cppm
export module a;
int func();
static int a = func();

//--- a.cpp
import a;
```

The `func()` should only execute once. However, before this patch we
will somehow import `static int a` from a.cppm incorrectly and
initialize that again.

This is super bad and can introduce serious runtime behaviors.

And also surprisingly, it looks like the root cause of the problem is
simply some oversight choosing APIs.
This commit is contained in:
Chuanqi Xu
2024-10-30 17:27:04 +08:00
committed by GitHub
parent e61a7dc256
commit 259eaa6878
2 changed files with 20 additions and 2 deletions

View File

@@ -7146,8 +7146,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// For C++ standard modules we are done - we will call the module
// initializer for imported modules, and that will likewise call those for
// any imports it has.
if (CXX20ModuleInits && Import->getImportedOwningModule() &&
!Import->getImportedOwningModule()->isModuleMapModule())
if (CXX20ModuleInits && Import->getImportedModule() &&
Import->getImportedModule()->isNamedModule())
break;
// For clang C++ module map modules the initializers for sub-modules are

View File

@@ -0,0 +1,18 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/a.cppm -emit-module-interface -o %t/a.pcm
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %t/a.cpp -fmodule-file=a=%t/a.pcm -emit-llvm -o - | FileCheck %t/a.cpp
//--- a.cppm
export module a;
int func();
static int a = func();
//--- a.cpp
import a;
// CHECK-NOT: internal global
// CHECK-NOT: __cxx_global_var_init