Skip to content

Commit 774f1ab

Browse files
author
huqizhi
committed
[Clang][Sema] fix outline member function template with default align crash
1 parent b4f24be commit 774f1ab

File tree

2 files changed

+60
-2
lines changed

2 files changed

+60
-2
lines changed

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3051,6 +3051,7 @@ bool Sema::SubstDefaultArgument(
30513051
// default argument expression appears.
30523052
ContextRAII SavedContext(*this, FD);
30533053
std::unique_ptr<LocalInstantiationScope> LIS;
3054+
auto NewTemplateArgs = TemplateArgs;
30543055

30553056
if (ForCallExpr) {
30563057
// When instantiating a default argument due to use in a call expression,
@@ -3063,11 +3064,18 @@ bool Sema::SubstDefaultArgument(
30633064
/*ForDefinition*/ false);
30643065
if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
30653066
return true;
3067+
if (FD->isOutOfLine()) {
3068+
auto *CurrentTemplateArgumentList = TemplateArgumentList::CreateCopy(
3069+
getASTContext(), TemplateArgs.getInnermost());
3070+
NewTemplateArgs = getTemplateInstantiationArgs(
3071+
FD, FD->getDeclContext(), true, CurrentTemplateArgumentList, true,
3072+
nullptr, false, false);
3073+
}
30663074
}
30673075

30683076
runWithSufficientStackSpace(Loc, [&] {
3069-
Result = SubstInitializer(PatternExpr, TemplateArgs,
3070-
/*DirectInit*/false);
3077+
Result = SubstInitializer(PatternExpr, NewTemplateArgs,
3078+
/*DirectInit*/ false);
30713079
});
30723080
}
30733081
if (Result.isInvalid())
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
3+
// expected-no-diagnostics
4+
5+
template<typename TemplateParam>
6+
struct Problem{
7+
template<typename FunctionTemplateParam>
8+
constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
9+
10+
template<typename FunctionTemplateParam>
11+
constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam));
12+
13+
template<typename FunctionTemplateParam>
14+
constexpr int FuncAlign2(int param = alignof(TemplateParam));
15+
16+
template<typename FunctionTemplateParam>
17+
constexpr int FuncSizeof2(int param = sizeof(TemplateParam));
18+
};
19+
20+
template <>
21+
template<typename FunctionTemplateParam>
22+
constexpr int Problem<int>::FuncAlign(int param) {
23+
return param;
24+
}
25+
26+
template <>
27+
template<typename FunctionTemplateParam>
28+
constexpr int Problem<int>::FuncSizeof(int param) {
29+
return param;
30+
}
31+
32+
template <>
33+
template<typename FunctionTemplateParam>
34+
constexpr int Problem<int>::FuncAlign2(int param) {
35+
return param;
36+
}
37+
38+
template <>
39+
template<typename FunctionTemplateParam>
40+
constexpr int Problem<int>::FuncSizeof2(int param) {
41+
return param;
42+
}
43+
44+
int main(){
45+
Problem<int> p = {};
46+
static_assert(p.FuncAlign<char>() == alignof(char));
47+
static_assert(p.FuncSizeof<char>() == sizeof(char));
48+
static_assert(p.FuncAlign2<char>() == alignof(int));
49+
static_assert(p.FuncSizeof2<char>() == sizeof(int));
50+
}

0 commit comments

Comments
 (0)