Exporting global variables from clang c++20 modules

Viewed 338

When building a c++20 module with clang 12 (it also repros with clang 10) exporting global variable from the module and declaring a global variable from the same exported class in another compilation unit results in "multiple definition of `vtable for foo'".

My understanding is that c++20 module can be created with a single cppm source (clang uses cppm for modules) and the compiler will generate both the module declarations and the definitions from it. In this case it seems clang++ does generate the vtable twice.

Here is the setup

foo.cppm:

export module foo;

export struct foo {
   virtual void vf();
};

void foo::vf() {}

export foo module_foo; // variable, exported

main.cpp:

import foo;

foo main_foo;

int main() {
  return 0;
}

Compilation steps to build the main executable:

/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules --precompile foo.cppm -o foo.pcm
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules --compile foo.cppm -o foo.o
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules -fmodule-file=foo.pcm --compile main.cpp -o main.o
/usr/lib/llvm-12/bin/clang++ -std=c++20 -fmodules foo.o main.o -o main

Results in the duplicate vtable and type info for foo class:

/usr/bin/ld: main.o:(.rodata+0x20): multiple definition of `typeinfo for foo'; foo.o:(.rodata+0x20): first defined here
/usr/bin/ld: main.o:(.rodata+0x18): multiple definition of `typeinfo name for foo'; foo.o:(.rodata+0x18): first defined here
/usr/bin/ld: main.o:(.rodata+0x0): multiple definition of `vtable for foo'; foo.o:(.rodata+0x0): first defined here

Is this a llvm bug or I'm doing something wrong and I'm confused on how modules should work?

0 Answers
Related