[ASTImporter] Added visibility check for variable templates.
authorBalázs Kéri <1.int32@gmail.com>
Mon, 9 Mar 2020 10:01:48 +0000 (11:01 +0100)
committerBalázs Kéri <1.int32@gmail.com>
Mon, 9 Mar 2020 10:57:55 +0000 (11:57 +0100)
Summary:
ASTImporter makes now difference between variable templates
with same name in different translation units if not visible
outside.

Reviewers: a.sidorin, shafik, a_sidorin

Reviewed By: a_sidorin

Subscribers: dkrupp, Szelethus, gamesh411, teemperor, martong, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D75732

clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterVisibilityTest.cpp

index 9f174e9..ffe867c 100644 (file)
@@ -5489,6 +5489,10 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
       continue;
 
     if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(FoundDecl)) {
+      // Use the templated decl, some linkage flags are set only there.
+      if (!hasSameVisibilityContextAndLinkage(FoundTemplate->getTemplatedDecl(),
+                                              D->getTemplatedDecl()))
+        continue;
       if (IsStructuralMatch(D, FoundTemplate)) {
         // The Decl in the "From" context has a definition, but in the
         // "To" context we already have a definition.
index 14a6706..00a307b 100644 (file)
@@ -49,6 +49,12 @@ struct GetFunTemplPattern {
     return functionTemplateDecl(hasName("f"));
   }
 };
+struct GetVarTemplPattern {
+  using DeclTy = VarTemplateDecl;
+  BindableMatcher<Decl> operator()() {
+    return namedDecl(hasName("v"), has(templateTypeParmDecl()));
+  }
+};
 struct GetClassTemplPattern {
   using DeclTy = ClassTemplateDecl;
   BindableMatcher<Decl> operator()() { return classTemplateDecl(hasName("X")); }
@@ -80,6 +86,10 @@ const auto *AnonUsing = "namespace { using T = int; }";
 const auto *ExternFT = "template <class> void f();";
 const auto *StaticFT = "template <class> static void f();";
 const auto *AnonFT = "namespace { template <class> void f(); }";
+// VarTemplateDecl:
+const auto *ExternVT = "template <class> extern int v;";
+const auto *StaticVT = "template <class> static int v;";
+const auto *AnonVT = "namespace { template <class> extern int v; }";
 // ClassTemplateDecl:
 const auto *ExternCT = "template <class> class X;";
 const auto *AnonCT = "namespace { template <class> class X; }";
@@ -130,6 +140,8 @@ using ImportClassesVisibilityChain = ImportVisibilityChain<GetClassPattern>;
 using ImportScopedEnumsVisibilityChain = ImportVisibilityChain<GetEnumPattern>;
 using ImportFunctionTemplatesVisibilityChain =
     ImportVisibilityChain<GetFunTemplPattern>;
+using ImportVariableTemplatesVisibilityChain =
+    ImportVisibilityChain<GetVarTemplPattern>;
 using ImportClassTemplatesVisibilityChain =
     ImportVisibilityChain<GetClassTemplPattern>;
 
@@ -153,6 +165,10 @@ TEST_P(ImportScopedEnumsVisibilityChain, ImportChain) {
 TEST_P(ImportFunctionTemplatesVisibilityChain, ImportChain) {
   TypedTest_ImportChain();
 }
+// Value-parameterized test for variable templates.
+TEST_P(ImportVariableTemplatesVisibilityChain, ImportChain) {
+  TypedTest_ImportChain();
+}
 // Value-parameterized test for class templates.
 TEST_P(ImportClassTemplatesVisibilityChain, ImportChain) {
   TypedTest_ImportChain();
@@ -190,6 +206,11 @@ INSTANTIATE_TEST_CASE_P(ParameterizedTests,
                         ::testing::Combine(DefaultTestValuesForRunOptions,
                                            ::testing::Values(ExternFT, StaticFT,
                                                              AnonFT)), );
+INSTANTIATE_TEST_CASE_P(ParameterizedTests,
+                        ImportVariableTemplatesVisibilityChain,
+                        ::testing::Combine(DefaultTestValuesForRunOptions,
+                                           ::testing::Values(ExternVT,
+                                                             AnonVT)), );
 INSTANTIATE_TEST_CASE_P(ParameterizedTests, ImportClassTemplatesVisibilityChain,
                         ::testing::Combine(DefaultTestValuesForRunOptions,
                                            ::testing::Values(ExternCT,
@@ -306,6 +327,7 @@ using ImportEnumsVisibility = ImportVisibility<GetEnumPattern>;
 using ImportScopedEnumsVisibility = ImportVisibility<GetEnumPattern>;
 using ImportTypedefNameVisibility = ImportVisibility<GetTypedefNamePattern>;
 using ImportFunctionTemplatesVisibility = ImportVisibility<GetFunTemplPattern>;
+using ImportVariableTemplatesVisibility = ImportVisibility<GetVarTemplPattern>;
 using ImportClassTemplatesVisibility = ImportVisibility<GetClassTemplPattern>;
 
 // FunctionDecl.
@@ -356,6 +378,13 @@ TEST_P(ImportFunctionTemplatesVisibility, ImportAfter) {
 TEST_P(ImportFunctionTemplatesVisibility, ImportAfterImport) {
   TypedTest_ImportAfterImport();
 }
+// VarTemplateDecl.
+TEST_P(ImportVariableTemplatesVisibility, ImportAfter) {
+  TypedTest_ImportAfter();
+}
+TEST_P(ImportVariableTemplatesVisibility, ImportAfterImport) {
+  TypedTest_ImportAfterImport();
+}
 // ClassTemplateDecl.
 TEST_P(ImportClassTemplatesVisibility, ImportAfter) { TypedTest_ImportAfter(); }
 TEST_P(ImportClassTemplatesVisibility, ImportAfterImport) {
@@ -463,6 +492,20 @@ INSTANTIATE_TEST_CASE_P(
             std::make_tuple(AnonFT, StaticFT, ExpectUnlinkedDeclChain),
             std::make_tuple(AnonFT, AnonFT, ExpectUnlinkedDeclChain))), );
 INSTANTIATE_TEST_CASE_P(
+    ParameterizedTests, ImportVariableTemplatesVisibility,
+    ::testing::Combine(
+        DefaultTestValuesForRunOptions,
+        ::testing::Values(
+            std::make_tuple(ExternVT, ExternVT, ExpectLinkedDeclChain),
+            std::make_tuple(ExternVT, StaticVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(ExternVT, AnonVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(StaticVT, ExternVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(StaticVT, StaticVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(StaticVT, AnonVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(AnonVT, ExternVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(AnonVT, StaticVT, ExpectUnlinkedDeclChain),
+            std::make_tuple(AnonVT, AnonVT, ExpectUnlinkedDeclChain))), );
+INSTANTIATE_TEST_CASE_P(
     ParameterizedTests, ImportClassTemplatesVisibility,
     ::testing::Combine(
         DefaultTestValuesForRunOptions,