Clang used to produce redefinition errors, see tests for examples.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
When I run this locally, it emits several unexpected errors:
While building module 'library': In file included from <module-includes>:2: /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var2.h:4:32: error: redefinition of 'zero' template <class T> constexpr T zero = 0; ^ /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var1.h:4:32: note: previous definition is here template <class T> constexpr T zero = 0; ^ While building module 'library': In file included from <module-includes>:2: /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var2.h:5:8: error: redefinition of 'Int' struct Int { ^ /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var1.h:5:8: note: previous definition is here struct Int { ^ While building module 'library': In file included from <module-includes>:2: /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var2.h:8:27: error: redefinition of 'zero<Int>' template <> constexpr int zero<Int> = {0}; ^ /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var1.h:8:27: note: previous definition is here template <> constexpr int zero<Int> = {0}; ^ While building module 'library': In file included from <module-includes>:2: /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var2.h:9:33: error: redefinition of 'zero<T *>' template <class T> constexpr T* zero<T*> = nullptr; ^ /disk2/workspace.xuchuanqi/llvm-project-for-work/build/tools/clang/test/Modules/Output/merge-var-template-spec.cpp.tmp/var1.h:9:33: note: previous definition is here template <class T> constexpr T* zero<T*> = nullptr; ^ 4 errors generated.
clang/test/Modules/merge-var-template-spec-cxx-modules.cpp | ||
---|---|---|
1 ↗ | (On Diff #450283) | Maybe it is better to rename this as merge-var-template-spec.cppm since we uses the suffix .cppm as a note for c++20 modules. |
clang/test/Modules/merge-var-template-spec-cxx-modules.cpp | ||
---|---|---|
18–23 ↗ | (On Diff #450283) | BTW, these errors are not expected by me since they are not in a named modules and they are in different TU with var_def.cppm. |
- Add the forgotten -fmodules-local-submodule-visibility flag to the test
- Add newlines to the test files
- Switch to C++14 mode for tests, they don't use C++17.
Sorry, my bad. I was testing this with -std=c++20 and later switched to -std=c++17 as this does not have any C++20-related features.
I thought I reran the tests with -std=c++17 before sending out the patch, but apparently I did not.
The reason why this worked in C++20 mode is that C++20 implies -fcxx-modules, which imply -fmodules-local-submodule-visibility.
Without the latter flag, all declarations inside the same TU are visible, even when not imported.
I have added -fmodules-local-submodule-visibility to the tests and also included a comment explaining why we need it.
While here, also switched to C++14, which seems enough here.
clang/test/Modules/merge-var-template-spec-cxx-modules.cpp | ||
---|---|---|
18–23 ↗ | (On Diff #450283) | I am not sure about this one, but my understanding of the standard was that no two definitions are allowed if any is attached to a named module. For any definable item D with definitions in multiple translation units, ... - if the definitions in different translation units do not satisfy the following requirements, the program is ill-formed; a diagnostic is required only if the definable item is attached to a named module and a prior definition is reachable at the point where a later definition occurs. ... - Each such definition shall not be attached to a named module ([module.unit]). The diagnostic seems to be required by the standard when looking at a declaration in the named module and this example is the other way around here. |
LGTM then.
clang/test/Modules/merge-var-template-spec-cxx-modules.cpp | ||
---|---|---|
18–23 ↗ | (On Diff #450283) | Oh, you are right. My bad. Sorry for wasting time. |
Missing newline