Skip to content

Commit 07b6d21

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

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-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: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2+
// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s
3+
// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
4+
// expected-no-diagnostics
5+
6+
template<typename TemplateParam>
7+
struct Problem{
8+
template<typename FunctionTemplateParam>
9+
constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
10+
11+
template<typename FunctionTemplateParam>
12+
constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam));
13+
14+
template<typename FunctionTemplateParam>
15+
constexpr int FuncAlign2(int param = alignof(TemplateParam));
16+
17+
template<typename FunctionTemplateParam>
18+
constexpr int FuncSizeof2(int param = sizeof(TemplateParam));
19+
};
20+
21+
template <>
22+
template<typename FunctionTemplateParam>
23+
constexpr int Problem<int>::FuncAlign(int param) {
24+
return param;
25+
}
26+
27+
template <>
28+
template<typename FunctionTemplateParam>
29+
constexpr int Problem<int>::FuncSizeof(int param) {
30+
return param;
31+
}
32+
33+
template <>
34+
template<typename FunctionTemplateParam>
35+
constexpr int Problem<int>::FuncAlign2(int param) {
36+
return param;
37+
}
38+
39+
template <>
40+
template<typename FunctionTemplateParam>
41+
constexpr int Problem<int>::FuncSizeof2(int param) {
42+
return param;
43+
}
44+
45+
int main(){
46+
Problem<int> p = {};
47+
static_assert(p.FuncAlign<char>() == alignof(char));
48+
static_assert(p.FuncSizeof<char>() == sizeof(char));
49+
static_assert(p.FuncAlign2<char>() == alignof(int));
50+
static_assert(p.FuncSizeof2<char>() == sizeof(int));
51+
}

0 commit comments

Comments
 (0)