From bd72f06a7087050c7148b0a199956cf268a2545d Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Mon, 8 Feb 2016 22:23:09 +0000 Subject: [PATCH] Make ParentMap work with explicit specializations of function templates. For an explicit specialization, we first build a FunctionDecl, and then we call SubstDecl() on it to build a second FunctionDecl, which has the first FunctionDecl as canonical decl. The address of an explicit specialization of function template used to be the canonical decl of the FunctionDecl. This is different from all the other DeduceTemplateArguments() calls in SemaOverload, and since the canonical decl isn't visited by ParentMap while the redecl is, it also made ParentMap assert when computing the parent of a address-of-explicit-specialization-fun-template. To fix, remove the getCanonicalDecl() call. No behavior difference for clang, but it fixes an assert in ParentMap (which is e.g. used by libTooling). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@260159 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaOverload.cpp | 1 - unittests/ASTMatchers/ASTMatchersTest.cpp | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index eaac06162f..d71b307d15 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -10339,7 +10339,6 @@ private: // Template argument deduction ensures that we have an exact match or // compatible pointer-to-function arguments that would be adjusted by ICS. // This function template specicalization works. - Specialization = cast(Specialization->getCanonicalDecl()); assert(S.isSameOrCompatibleFunctionType( Context.getCanonicalType(Specialization->getType()), Context.getCanonicalType(TargetFunctionType))); diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index 2aaa92c35b..5578e066a2 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4333,6 +4333,13 @@ TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) { declRefExpr(to(decl(hasAncestor(decl())))))); } +TEST(HasAncestor, AddressOfExplicitSpecializationFunction) { + EXPECT_TRUE(matches("template void f();\n" + "template <> void f();\n" + "void (*get_f())() { return f; }\n", + declRefExpr(to(decl(hasAncestor(decl())))))); +} + TEST(HasParent, MatchesAllParents) { EXPECT_TRUE(matches( "template struct C { static void f() { 42; } };" -- 2.40.0