https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/78400
>From b9de8c52a2ffbd03c8a5368f6e62ba6c68ce2125 Mon Sep 17 00:00:00 2001 From: huqizhi <huqi...@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 8bb26fcae18d6b..ccdce2c299b022 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -828,6 +828,9 @@ Bug Fixes in This Version - Fix an issue with missing symbol definitions when the first coroutine statement appears in a discarded ``if constexpr`` branch. Fixes (`#78290 <https://github.com/llvm/llvm-project/issues/78290>`_) +- 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 fc80515b45e35b..d310dfdd61c600 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3051,6 +3051,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, @@ -3063,11 +3064,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 00000000000000..4bcea7eaa10176 --- /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)); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits