Skip to content

Commit

Permalink
[Clang] Fix finding instantiated decls for class template specializat…
Browse files Browse the repository at this point in the history
…ions during instantiation (#72346)

This change aims to fix
#70375

It appears to me that the logic here should be handling specializations
in general, not just partial specialization. It also seems that both the
comment before the block and the `isInstantiationOf(ClassTemplate,
SpecTemplate)` below agree with my judgement.

The issue might just be a mistake that someone mistaken specialization
as a special case of partial specializations, while it's actually the
other way around.

Needs some experts to comment here if this is the right fix. 

The code that caused clang ICE is added as a test case.
  • Loading branch information
yuxuanchen1997 committed Nov 21, 2023
1 parent eaffcc8 commit d328512
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 4 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ Bug Fixes in This Version

- Fixed an issue that a benign assertion might hit when instantiating a pack expansion
inside a lambda. (`#61460 <https://github.com/llvm/llvm-project/issues/61460>`_)
- Fix crash during instantiation of some class template specializations within class
templates. Fixes (`#70375 <https://github.com/llvm/llvm-project/issues/70375>`_)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6207,13 +6207,13 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
return D;

// Determine whether this record is the "templated" declaration describing
// a class template or class template partial specialization.
// a class template or class template specialization.
ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
if (ClassTemplate)
ClassTemplate = ClassTemplate->getCanonicalDecl();
else if (ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))
ClassTemplate = PartialSpec->getSpecializedTemplate()->getCanonicalDecl();
else if (ClassTemplateSpecializationDecl *Spec =
dyn_cast<ClassTemplateSpecializationDecl>(Record))
ClassTemplate = Spec->getSpecializedTemplate()->getCanonicalDecl();

// Walk the current context to find either the record or an instantiation of
// it.
Expand Down
33 changes: 33 additions & 0 deletions clang/test/SemaCXX/template-specialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,36 @@ int main() {
B::foo<4>(); // expected-note {{in instantiation of function template specialization 'B::foo<4>'}}
return 0;
}

namespace GH70375 {

template <typename Ty>
struct S {
static void bar() {
Ty t;
t.foo();
}

static void take(Ty&) {}
};

template <typename P>
struct Outer {
template <typename C>
struct Inner;

using U = S<Inner<P>>;

template <>
struct Inner<void> {
void foo() {
U::take(*this);
}
};
};

void instantiate() {
Outer<void>::U::bar();
}

}

0 comments on commit d328512

Please sign in to comment.