[PATCH] D120397: [C++20] [Modules] Make the linkage consistent for template and its specialization

Chuanqi Xu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 21 20:41:43 PDT 2022


ChuanqiXu updated this revision to Diff 417175.
ChuanqiXu added a comment.

Use Unittest instead of `expected-no-diagnostic` tests.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120397/new/

https://reviews.llvm.org/D120397

Files:
  clang/lib/AST/Decl.cpp
  clang/test/CodeGenCXX/inconsistent-export-template.cpp
  clang/unittests/AST/DeclTest.cpp


Index: clang/unittests/AST/DeclTest.cpp
===================================================================
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -171,3 +171,26 @@
       selectFirst<FunctionDecl>("f", match(functionDecl().bind("f"), Ctx));
   EXPECT_TRUE(f->isInExportDeclContext());
 }
+
+TEST(Decl, InConsistLinkageForTemplates) {
+  llvm::Annotations Code(R"(
+    export module m;
+    export template <class T>
+    void f() {}
+
+    template <>
+    void f<int>() {})");
+
+  auto AST =
+      tooling::buildASTFromCodeWithArgs(Code.code(), /*Args=*/{"-std=c++20"});
+  ASTContext &Ctx = AST->getASTContext();
+
+  llvm::SmallVector<ast_matchers::BoundNodes, 2> Funcs =
+      match(functionDecl().bind("f"), Ctx);
+
+  EXPECT_TRUE(Funcs.size() == 2);
+  const FunctionDecl *TemplateF = Funcs[0].getNodeAs<FunctionDecl>("f");
+  const FunctionDecl *SpecializedF = Funcs[1].getNodeAs<FunctionDecl>("f");
+  EXPECT_TRUE(TemplateF->getLinkageInternal() ==
+              SpecializedF->getLinkageInternal());
+}
Index: clang/test/CodeGenCXX/inconsistent-export-template.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/inconsistent-export-template.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++20 %s -S -emit-llvm -triple %itanium_abi_triple -disable-llvm-passes -o - | FileCheck %s
+
+export module m;
+export template <class T>
+void f() {
+}
+
+// CHECK: void @_Z1fIiEvv
+template <>
+void f<int>() {
+}
Index: clang/lib/AST/Decl.cpp
===================================================================
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -391,11 +391,18 @@
   bool considerVisibility =
     shouldConsiderTemplateVisibility(fn, specInfo);
 
-  // Merge information from the template parameters.
   FunctionTemplateDecl *temp = specInfo->getTemplate();
-  LinkageInfo tempLV =
-    getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
-  LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
+
+  // Merge information from the template declaration.
+  LinkageInfo tempLV = getLVForDecl(temp, computation);
+  // The linkage of the specialization should be consistent with the
+  // template declaration.
+  LV.setLinkage(tempLV.getLinkage());
+
+  // Merge information from the template parameters.
+  LinkageInfo paramsLV =
+      getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+  LV.mergeMaybeWithVisibility(paramsLV, considerVisibility);
 
   // Merge information from the template arguments.
   const TemplateArgumentList &templateArgs = *specInfo->TemplateArguments;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120397.417175.patch
Type: text/x-patch
Size: 2657 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220322/3d2ea50c/attachment-0001.bin>


More information about the cfe-commits mailing list