-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang] Fix specialization of non-templated member classes of class t…
…emplates Explicit specialization doesn't increase depth of template parameters, so need to be careful when gathering template parameters for instantiation. For the case: ``` template<typename T> struct X { struct impl; }; template <> struct X<int>::impl { template<int ct> int f() { return ct; }; }; ``` instantiation of `f` used to crash because type template parameter `int` of explicit specialization was taken into account, but non-type template parameter `ct` had zero depth and index so wrong parameter ended up inside of a wrong handler. Fixes #61159 Reviewed By: aaron.ballman, shafik Differential Revision: https://reviews.llvm.org/D155705
- Loading branch information
Showing
3 changed files
with
46 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s | ||
// expected-no-diagnostics | ||
|
||
namespace GH61159 { | ||
template <typename T> struct X { | ||
struct I; | ||
}; | ||
|
||
template <> struct X<int>::I { | ||
template <int ct> constexpr int f() { return ct; }; | ||
|
||
int data = 3; | ||
}; | ||
|
||
template <typename T> struct X<T>::I { | ||
template <T ct> constexpr T f() { return ct + 1; }; | ||
T data = 7; | ||
}; | ||
|
||
static_assert(X<int>::I{}.f<17>() == 17); | ||
static_assert(X<int>::I{}.data == 3); | ||
static_assert(X<short>::I{}.data == 7); | ||
static_assert(X<short>::I{}.f<18>() == 19); | ||
|
||
template <typename T> struct Y { | ||
struct I; | ||
}; | ||
|
||
template <> struct Y<int> { | ||
struct I { | ||
template <int ct> constexpr int f() { return ct; }; | ||
int data = 3; | ||
}; | ||
}; | ||
|
||
static_assert(Y<int>::I{}.f<17>() == 17); | ||
static_assert(Y<int>::I{}.data == 3); | ||
|
||
} // namespace GH61159 |