diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -44,6 +44,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeVisitor.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/AST/ParentMapContext.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/FileManager.h" @@ -5812,6 +5813,10 @@ if (FoundTemplate) { if (!hasSameVisibilityContextAndLinkage(FoundTemplate, D)) continue; + auto Parents = FoundDecl->getASTContext().getParents(*FoundDecl); + if (!Parents.empty() && nullptr != Parents.begin()->get()) { + continue; + } if (IsStructuralMatch(D, FoundTemplate)) { ClassTemplateDecl *TemplateWithDef = diff --git a/clang/test/Analysis/Inputs/ctu-friend-template-other.cpp b/clang/test/Analysis/Inputs/ctu-friend-template-other.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-friend-template-other.cpp @@ -0,0 +1,6 @@ +#include "ctu-friend-template.h" + +void bar(){ + __1::A a1(0); + a1.foo(); +} diff --git a/clang/test/Analysis/Inputs/ctu-friend-template.h b/clang/test/Analysis/Inputs/ctu-friend-template.h new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-friend-template.h @@ -0,0 +1,20 @@ +namespace __1{ + +template +class A; + +template +class A{ +public: + template + friend class A; + + A(T x):x(x){} + + void foo(){} + +private: + T x; +}; + +} diff --git a/clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt b/clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/Inputs/ctu-friend-template.cpp.externalDefMap-dump.txt @@ -0,0 +1 @@ +9:c:@F@bar# ctu-friend-template-other.cpp.ast diff --git a/clang/test/Analysis/ctu-friend-template.cpp b/clang/test/Analysis/ctu-friend-template.cpp new file mode 100644 --- /dev/null +++ b/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 +}