summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2016-02-08 22:23:09 +0000
committerNico Weber <nicolasweber@gmx.de>2016-02-08 22:23:09 +0000
commit26911c7733dfcc345074f9148a449c10962216fa (patch)
treec4921e1756e3e48921c68e777fa8d9a7ca091242
parent06dacd851fe4df04d9ad321950755f7d1ed0c6e5 (diff)
downloadbcm5719-llvm-26911c7733dfcc345074f9148a449c10962216fa.tar.gz
bcm5719-llvm-26911c7733dfcc345074f9148a449c10962216fa.zip
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). llvm-svn: 260159
-rw-r--r--clang/lib/Sema/SemaOverload.cpp1
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTest.cpp7
2 files changed, 7 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index eaac06162f7..d71b307d15b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/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<FunctionDecl>(Specialization->getCanonicalDecl());
assert(S.isSameOrCompatibleFunctionType(
Context.getCanonicalType(Specialization->getType()),
Context.getCanonicalType(TargetFunctionType)));
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
index 2aaa92c35b8..5578e066a22 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -4333,6 +4333,13 @@ TEST(HasAncestor, NonParmDependentTemplateParmVarDeclRefExpr) {
declRefExpr(to(decl(hasAncestor(decl()))))));
}
+TEST(HasAncestor, AddressOfExplicitSpecializationFunction) {
+ EXPECT_TRUE(matches("template <class T> void f();\n"
+ "template <> void f<int>();\n"
+ "void (*get_f())() { return f<int>; }\n",
+ declRefExpr(to(decl(hasAncestor(decl()))))));
+}
+
TEST(HasParent, MatchesAllParents) {
EXPECT_TRUE(matches(
"template <typename T> struct C { static void f() { 42; } };"
OpenPOWER on IntegriCloud