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