alexander-shaposhnikov created this revision. alexander-shaposhnikov added reviewers: rsmith, aaron.ballman. alexander-shaposhnikov created this object with visibility "All Users". Herald added a project: All. alexander-shaposhnikov requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This diff fixes linkage of template parameter objects. The associated GitHub issue: https://github.com/llvm/llvm-project/issues/51571# Test plan: 1/ ninja check-all 2/ bootstrapped Clang passes tests Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145859 Files: clang/lib/CodeGen/CodeGenModule.cpp clang/test/CodeGenCXX/template-param-objects-linkage.cpp Index: clang/test/CodeGenCXX/template-param-objects-linkage.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/template-param-objects-linkage.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s + +struct S { char buf[32]; }; +template<S s> constexpr const char* f() { return s.buf; } +const char* fbuf = f<S{"a"}>(); +// CHECK: @_ZTAXtl1StlA32_cLc97EEEE = linkonce_odr constant { <{ i8, [31 x i8] }> } + +namespace { + struct UN { char buf[64]; }; +} +template <UN un> constexpr const char* g() { return un.buf; } +const char* gbuf = g<UN{"b"}>(); +// CHECK: @_ZTAXtlN12_GLOBAL__N_12UNEtlA64_cLc98EEEE = internal constant { <{ i8, [63 x i8] }> } + +struct Foo { int *i; }; +int m = 0; +namespace { int n; } + +template <Foo foo> +const int* h() { return foo.i; } + +const int* hm = h<Foo{&m}>(); +// CHECK: @_ZTAXtl3FooadL_Z1mEEE = linkonce_odr constant %struct.Foo { ptr @m } + +const int* hn = h<Foo{&n}>(); +// CHECK: @_ZTAXtl3FooadL_ZN12_GLOBAL__N_11nEEEE = internal constant %struct.Foo { ptr @_ZN12_GLOBAL__N_11nE } Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -3238,9 +3238,12 @@ return ConstantAddress::invalid(); } - auto *GV = new llvm::GlobalVariable( - getModule(), Init->getType(), - /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name); + llvm::GlobalValue::LinkageTypes Linkage = + isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage()) + ? llvm::GlobalValue::LinkOnceODRLinkage + : llvm::GlobalValue::InternalLinkage; + auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), + /*isConstant=*/true, Linkage, Init, Name); if (supportsCOMDAT()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV);
Index: clang/test/CodeGenCXX/template-param-objects-linkage.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/template-param-objects-linkage.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 %s -emit-llvm -o - | FileCheck %s + +struct S { char buf[32]; }; +template<S s> constexpr const char* f() { return s.buf; } +const char* fbuf = f<S{"a"}>(); +// CHECK: @_ZTAXtl1StlA32_cLc97EEEE = linkonce_odr constant { <{ i8, [31 x i8] }> } + +namespace { + struct UN { char buf[64]; }; +} +template <UN un> constexpr const char* g() { return un.buf; } +const char* gbuf = g<UN{"b"}>(); +// CHECK: @_ZTAXtlN12_GLOBAL__N_12UNEtlA64_cLc98EEEE = internal constant { <{ i8, [63 x i8] }> } + +struct Foo { int *i; }; +int m = 0; +namespace { int n; } + +template <Foo foo> +const int* h() { return foo.i; } + +const int* hm = h<Foo{&m}>(); +// CHECK: @_ZTAXtl3FooadL_Z1mEEE = linkonce_odr constant %struct.Foo { ptr @m } + +const int* hn = h<Foo{&n}>(); +// CHECK: @_ZTAXtl3FooadL_ZN12_GLOBAL__N_11nEEEE = internal constant %struct.Foo { ptr @_ZN12_GLOBAL__N_11nE } Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -3238,9 +3238,12 @@ return ConstantAddress::invalid(); } - auto *GV = new llvm::GlobalVariable( - getModule(), Init->getType(), - /*isConstant=*/true, llvm::GlobalValue::LinkOnceODRLinkage, Init, Name); + llvm::GlobalValue::LinkageTypes Linkage = + isExternallyVisible(TPO->getLinkageAndVisibility().getLinkage()) + ? llvm::GlobalValue::LinkOnceODRLinkage + : llvm::GlobalValue::InternalLinkage; + auto *GV = new llvm::GlobalVariable(getModule(), Init->getType(), + /*isConstant=*/true, Linkage, Init, Name); if (supportsCOMDAT()) GV->setComdat(TheModule.getOrInsertComdat(GV->getName())); Emitter.finalize(GV);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits