Skip to content

Commit

Permalink
[C++20] [Modules] Fix the duplicated static initializer problem (#114193
Browse files Browse the repository at this point in the history
)

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.

(cherry picked from commit 259eaa6)
  • Loading branch information
ChuanqiXu9 authored and tru committed Nov 15, 2024
1 parent c9e8540 commit 863b2e5
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7080,8 +7080,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
Expand Down
18 changes: 18 additions & 0 deletions clang/test/Modules/static-initializer.cppm
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 863b2e5

Please sign in to comment.