jcsxky updated this revision to Diff 547124.
jcsxky added a comment.

add unittest


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156693

Files:
  clang/lib/AST/ASTImporter.cpp
  clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
  clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
  clang/test/Analysis/Inputs/ctu-friend-template.h
  clang/test/Analysis/ctu-friend-template.cpp
  clang/unittests/AST/ASTImporterTest.cpp

Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,84 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+      R"(
+        namespace __1{
+
+          template<class T, T U>
+          class A;
+
+          template<class T, T U>
+          class A{
+          public:
+            template<class P, P Q>
+            friend class A;
+
+            A(T x):x(x){}
+            
+            void foo(){
+              int i=0;
+              int j=1/i;
+              (void)j;
+            }
+            
+          private:
+            T x;
+          };
+
+      }
+      void bar();
+
+      int main(){
+        bar();
+      }
+      )",
+      Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
+      ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+      R"(
+      namespace __1{
+
+          template<class T, T U>
+          class A;
+
+          template<class T, T U>
+          class A{
+          public:
+            template<class P, P Q>
+            friend class A;
+
+            A(T x):x(x){}
+            
+            void foo(){
+              int i=0;
+              int j=1/i;
+              (void)j;
+            }
+            
+          private:
+            T x;
+          };
+
+        }
+        void bar(){
+          __1::A<int,3> a1(0);
+          a1.foo();
+        }
+      )",
+      Lang_CXX11, "input1.cc");
+  auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
+      FromTU, classTemplateDecl(hasName("A")));
+  auto *Template = Import(Definition, Lang_CXX11);
+  EXPECT_TRUE(Template);
+  auto *TemplateClass = cast<ClassTemplateDecl>(Template);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+            TemplateClass->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
        ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/test/Analysis/ctu-friend-template.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/ctu-friend-template.cpp
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: mkdir -p %t/ctudir
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -emit-pch -o %t/ctudir/ctu-friend-template-other.cpp.ast %S/Inputs/ctu-friend-template-other.cpp
+// RUN: cp %S/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
+// RUN:   -analyzer-checker=core,debug.ExprInspection \
+// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
+// RUN:   -analyzer-config ctu-dir=%t/ctudir \
+// RUN:   -Werror=ctu \
+// RUN:   -verify %s
+
+// CHECK: CTU loaded AST file
+
+#include "Inputs/ctu-friend-template.h"
+
+void bar();
+
+int main(){
+	bar(); // expected-no-diagnostics
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.h
===================================================================
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.h
@@ -0,0 +1,20 @@
+namespace __1{
+
+template<class T, T U>
+class A;
+
+template<class T, T U>
+class A{
+public:
+	template<class P, P Q>
+	friend class A;
+
+	A(T x):x(x){}
+	
+	void foo(){}
+	
+private:
+	T x;
+};
+
+}
Index: clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
===================================================================
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt
@@ -0,0 +1 @@
+9:c:@F@bar# ctu-friend-template-other.cpp.ast
Index: clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
===================================================================
--- /dev/null
+++ clang/test/Analysis/Inputs/ctu-friend-template-other.cpp
@@ -0,0 +1,6 @@
+#include "ctu-friend-template.h"
+
+void bar(){
+	__1::A<int,3> a1(0);
+	a1.foo();
+}
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -34,6 +34,7 @@
 #include "clang/AST/LambdaCapture.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/OperationKinds.h"
+#include "clang/AST/ParentMapContext.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -5821,7 +5822,11 @@
       if (FoundTemplate) {
         if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D))
           continue;
-
+        auto Parents = FoundDecl->getASTContext().getParents(*FoundDecl);
+        if (!Parents.empty() && nullptr != Parents.begin()->get<FriendDecl>() &&
+            FoundTemplate->getName() == D->getName() &&
+            !IsStructuralMatch(D, FoundTemplate, false))
+          continue;
         if (IsStructuralMatch(D, FoundTemplate)) {
           ClassTemplateDecl *TemplateWithDef =
               getTemplateDefinition(FoundTemplate);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to