[clang] [Clang][Sema] fix outline member function template with default align crash (PR #78400)
Qizhi Hu via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 22 20:54:36 PST 2024
https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/78400
>From 852e2d26ee3433e09978da93dfe6303faac92876 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Wed, 17 Jan 2024 14:16:34 +0800
Subject: [PATCH] [Clang][Sema] fix outline member function template with
default align crash
---
clang/docs/ReleaseNotes.rst | 3 ++
clang/lib/Sema/SemaTemplateInstantiate.cpp | 13 ++++-
clang/test/SemaTemplate/default-parm-init.cpp | 50 +++++++++++++++++++
3 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaTemplate/default-parm-init.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cb15dfb99bec977..bff8e496cbeed5f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -859,6 +859,9 @@ Bug Fixes in This Version
Fixes (`#78290 <https://github.com/llvm/llvm-project/issues/78290>`_)
- Fixed assertion failure with deleted overloaded unary operators.
Fixes (`#78314 <https://github.com/llvm/llvm-project/issues/78314>`_)
+- Fix crash when specialize out-of-line member function with default parameter
+ and issue with incorrect specialization of the initialization of default parameter.
+ Fixes (`#68490 <https://github.com/llvm/llvm-project/issues/68490>`_)
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index e12186d7d82f8d0..41e58b91de4e08e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -3049,6 +3049,7 @@ bool Sema::SubstDefaultArgument(
// default argument expression appears.
ContextRAII SavedContext(*this, FD);
std::unique_ptr<LocalInstantiationScope> LIS;
+ MultiLevelTemplateArgumentList NewTemplateArgs = TemplateArgs;
if (ForCallExpr) {
// When instantiating a default argument due to use in a call expression,
@@ -3061,11 +3062,19 @@ bool Sema::SubstDefaultArgument(
/*ForDefinition*/ false);
if (addInstantiatedParametersToScope(FD, PatternFD, *LIS, TemplateArgs))
return true;
+ if (FD->isOutOfLine()) {
+ TemplateArgumentList *CurrentTemplateArgumentList =
+ TemplateArgumentList::CreateCopy(getASTContext(),
+ TemplateArgs.getInnermost());
+ NewTemplateArgs = getTemplateInstantiationArgs(
+ FD, FD->getDeclContext(), /*Final=*/false,
+ CurrentTemplateArgumentList, /*RelativeToPrimary=*/true);
+ }
}
runWithSufficientStackSpace(Loc, [&] {
- Result = SubstInitializer(PatternExpr, TemplateArgs,
- /*DirectInit*/false);
+ Result = SubstInitializer(PatternExpr, NewTemplateArgs,
+ /*DirectInit*/ false);
});
}
if (Result.isInvalid())
diff --git a/clang/test/SemaTemplate/default-parm-init.cpp b/clang/test/SemaTemplate/default-parm-init.cpp
new file mode 100644
index 000000000000000..4bcea7eaa101763
--- /dev/null
+++ b/clang/test/SemaTemplate/default-parm-init.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++17 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// expected-no-diagnostics
+
+template<typename TemplateParam>
+struct Problem{
+ template<typename FunctionTemplateParam>
+ constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
+
+ template<typename FunctionTemplateParam>
+ constexpr int FuncSizeof(int param = sizeof(FunctionTemplateParam));
+
+ template<typename FunctionTemplateParam>
+ constexpr int FuncAlign2(int param = alignof(TemplateParam));
+
+ template<typename FunctionTemplateParam>
+ constexpr int FuncSizeof2(int param = sizeof(TemplateParam));
+};
+
+template <>
+template<typename FunctionTemplateParam>
+constexpr int Problem<int>::FuncAlign(int param) {
+ return param;
+}
+
+template <>
+template<typename FunctionTemplateParam>
+constexpr int Problem<int>::FuncSizeof(int param) {
+ return param;
+}
+
+template <>
+template<typename FunctionTemplateParam>
+constexpr int Problem<int>::FuncAlign2(int param) {
+ return param;
+}
+
+template <>
+template<typename FunctionTemplateParam>
+constexpr int Problem<int>::FuncSizeof2(int param) {
+ return param;
+}
+
+int main(){
+ Problem<int> p = {};
+ static_assert(p.FuncAlign<char>() == alignof(char));
+ static_assert(p.FuncSizeof<char>() == sizeof(char));
+ static_assert(p.FuncAlign2<char>() == alignof(int));
+ static_assert(p.FuncSizeof2<char>() == sizeof(int));
+}
More information about the cfe-commits
mailing list