https://github.com/MitalAshok created https://github.com/llvm/llvm-project/pull/101702
Make sure that the functions are instantiated to deduce the return type. Fixes #101614 Allow `BuiltinFnTy` in `BuildDecltypeType` (these are wrapped in a `DeclRefExpr` that has the actual type). Fixes #101690 >From eacddd4c79893295e406d43ce537be2d4aa014b1 Mon Sep 17 00:00:00 2001 From: Mital Ashok <mi...@mitalashok.co.uk> Date: Fri, 2 Aug 2024 16:27:54 +0100 Subject: [PATCH] [Clang] Support for LibBuiltins with placeholder return types --- clang/docs/ReleaseNotes.rst | 1 + .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 +- clang/lib/Sema/SemaType.cpp | 4 +- .../builtin-std-move-placeholder-return.cpp | 62 +++++++++++++++++++ clang/test/SemaCXX/builtin-std-move.cpp | 4 ++ 5 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 25f5bd37bbe94..a873d8ab0e4e8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -173,6 +173,7 @@ Bug Fixes to C++ Support - Clang now correctly parses potentially declarative nested-name-specifiers in pointer-to-member declarators. - Fix a crash when checking the initialzier of an object that was initialized with a string literal. (#GH82167) +- Clang can now use the definition of ``std::forward_like`` libstdc++ 14.1 and 14.2. (#GH101614) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index f93cd113988ae..2f9b537814661 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4895,7 +4895,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, // Never implicitly instantiate a builtin; we don't actually need a function // body. if (Function->getBuiltinID() && TSK == TSK_ImplicitInstantiation && - !DefinitionRequired) + !DefinitionRequired && !Function->getReturnType()->isUndeducedType()) return; // Don't instantiate a definition if we already have one. diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 6fa39cdccef2b..5a2dfc3228690 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -9468,7 +9468,9 @@ QualType Sema::getDecltypeForExpr(Expr *E) { } QualType Sema::BuildDecltypeType(Expr *E, bool AsUnevaluated) { - assert(!E->hasPlaceholderType() && "unexpected placeholder"); + assert((!E->hasPlaceholderType() || + E->getType()->isSpecificBuiltinType(BuiltinType::Kind::BuiltinFn)) && + "unexpected placeholder"); if (AsUnevaluated && CodeSynthesisContexts.empty() && !E->isInstantiationDependent() && E->HasSideEffects(Context, false)) { diff --git a/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp b/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp new file mode 100644 index 0000000000000..62446fdf4f3db --- /dev/null +++ b/clang/test/SemaCXX/builtin-std-move-placeholder-return.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="decltype(auto)" +// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="auto&&" +// RUN: %clang_cc1 -std=c++23 -verify %s -DPLACEHOLDER="True decltype(auto)" + +// expected-no-diagnostics + +template<class T> +concept True = true; + +namespace std { + template<class T> + constexpr PLACEHOLDER move(T&& t) noexcept { + return static_cast<__remove_reference_t(T)&&>(t); + } + constexpr PLACEHOLDER move_if_noexcept(auto& t) noexcept { + return static_cast<__remove_reference_t(decltype(t))&&>(t); + } + template<class T, class U> + constexpr PLACEHOLDER forward_like(U&& x) noexcept { + if constexpr (__is_const(__remove_reference_t(T))) { + using copy_const = const __remove_reference_t(U); + if constexpr (__is_rvalue_reference(T&&)) { + using V = __remove_reference_t(copy_const)&&; + return static_cast<V>(x); + } else { + using V = copy_const&; + return static_cast<V>(x); + } + } else { + using copy_const = __remove_reference_t(U); + if constexpr (__is_rvalue_reference(T&&)) { + using V = __remove_reference_t(copy_const)&&; + return static_cast<V>(x); + } else { + using V = copy_const&; + return static_cast<V>(x); + } + } + } +} + +namespace GH101614 { +int i; +static_assert(__is_same(decltype(std::move(i)), int&&)); +static_assert(__is_same(decltype(std::move_if_noexcept(i)), int&&)); +static_assert(__is_same(decltype(std::forward_like<char>(i)), int&&)); +static_assert(__is_same(decltype(std::forward_like<char&>(i)), int&)); + +constexpr bool is_i(int&& x) { return &x == &i; } +void is_i(int&) = delete; +void is_i(auto&&) = delete; + +static_assert(is_i(std::move(i))); +static_assert(is_i(std::move_if_noexcept(i))); +static_assert(is_i(std::forward_like<char>(i))); +static_assert(&std::forward_like<char&>(i) == &i); + +// These types are incorrect, but make sure the types as declared are used +static_assert(__is_same(decltype(std::move<int(&)()>), auto(int(&)()) noexcept -> int(&)())); +static_assert(__is_same(decltype(std::move_if_noexcept<int(&)()>), auto(int(&)()) noexcept -> int(&)())); +static_assert(__is_same(decltype(std::forward_like<int, int(&)()>), auto(int(&)()) noexcept -> int(&)())); +} // namespace GH101614 diff --git a/clang/test/SemaCXX/builtin-std-move.cpp b/clang/test/SemaCXX/builtin-std-move.cpp index a2ae21986308a..da85703c5d58e 100644 --- a/clang/test/SemaCXX/builtin-std-move.cpp +++ b/clang/test/SemaCXX/builtin-std-move.cpp @@ -172,3 +172,7 @@ namespace std { template<typename T> int &move(T); } int bad_signature = std::move(0); // expected-error {{unsupported signature for 'std::move<int>'}} + +namespace GH101690 { +decltype(std::move_if_noexcept<int>)* p = nullptr; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits