Skip to content

Commit fbf5cca

Browse files
author
huqizhi
committed
[Clang][Sema] fix outline member function template with default align crash
1 parent 02d5680 commit fbf5cca

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ Bug Fixes to C++ Support
115115

116116
- Fix crash when using lifetimebound attribute in function with trailing return.
117117
Fixes (`#73619 <https://github.com/llvm/llvm-project/issues/73619>`_)
118+
- Fix a crash when specializing an out-of-line member function with a default
119+
parameter where we did an incorrect specialization of the initialization of
120+
the default parameter.
121+
Fixes (`#68490 <https://github.com/llvm/llvm-project/issues/68490>`_)
118122

119123
Bug Fixes to AST Handling
120124
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,6 +3049,7 @@ bool Sema::SubstDefaultArgument(
30493049
// default argument expression appears.
30503050
ContextRAII SavedContext(*this, FD);
30513051
std::unique_ptr<LocalInstantiationScope> LIS;
3052+
MultiLevelTemplateArgumentList NewTemplateArgs = TemplateArgs;
30523053

30533054
if (ForCallExpr) {
30543055
// When instantiating a default argument due to use in a call expression,
@@ -3061,11 +3062,19 @@ bool Sema::SubstDefaultArgument(
30613062
/*ForDefinition*/ false);
30623063
if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
30633064
return true;
3065+
if (FD->isOutOfLine()) {
3066+
TemplateArgumentList *CurrentTemplateArgumentList =
3067+
TemplateArgumentList::CreateCopy(getASTContext(),
3068+
TemplateArgs.getInnermost());
3069+
NewTemplateArgs = getTemplateInstantiationArgs(
3070+
FD, FD->getDeclContext(), /*Final=*/false,
3071+
CurrentTemplateArgumentList, /*RelativeToPrimary=*/true);
3072+
}
30643073
}
30653074

30663075
runWithSufficientStackSpace(Loc, [&] {
3067-
Result = SubstInitializer(PatternExpr, TemplateArgs,
3068-
/*DirectInit*/false);
3076+
Result = SubstInitializer(PatternExpr, NewTemplateArgs,
3077+
/*DirectInit*/ false);
30693078
});
30703079
}
30713080
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)