Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/70...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/70772 >From 5436d89e4ca3fbb1d53f27f8d5347f3eff100dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 31 Oct 2023 07:17:16 +0100 Subject: [PATCH 1/2] [clang][Interp] Handle std::move etc. builtins --- clang/lib/AST/Interp/InterpBuiltin.cpp | 18 ++++++++++++++++++ clang/test/AST/Interp/functions.cpp | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp b/clang/lib/AST/Interp/InterpBuiltin.cpp index 9cf206ecc212adb..58fedb6a96fb936 100644 --- a/clang/lib/AST/Interp/InterpBuiltin.cpp +++ b/clang/lib/AST/Interp/InterpBuiltin.cpp @@ -138,6 +138,7 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, case X: \ return Ret<X>(S, OpPC, Result); switch (*T) { + RET_CASE(PT_Ptr); RET_CASE(PT_Float); RET_CASE(PT_Bool); RET_CASE(PT_Sint8); @@ -533,6 +534,15 @@ static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, return true; } +static bool interp__builtin_move(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, const Function *Func, + const CallExpr *Call) { + + const Pointer &Arg = S.Stk.peek<Pointer>(); + S.Stk.push<Pointer>(Arg); + return Func->getDecl()->isConstexpr(); +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call) { InterpFrame *Frame = S.Current; @@ -702,6 +712,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case Builtin::BIas_const: + case Builtin::BIforward: + case Builtin::BIforward_like: + case Builtin::BImove: + if (!interp__builtin_move(S, OpPC, Frame, F, Call)) + return false; + break; + default: return false; } diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index ab562e70606b672..2ce39de3415747a 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -378,3 +378,18 @@ namespace Packs { static_assert(foo<int, char>() == 2, ""); static_assert(foo<>() == 0, ""); } + +namespace std { +template <typename T> struct remove_reference { using type = T; }; +template <typename T> struct remove_reference<T &> { using type = T; }; +template <typename T> struct remove_reference<T &&> { using type = T; }; +template <typename T> +constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept { + return static_cast<typename std::remove_reference<T>::type &&>(t); +} +} +/// The std::move declaration above gets translated to a builtin function. +namespace Move { + constexpr int A = std::move(5); + static_assert(A == 5, ""); +} >From 63f4c0937da07f807eb3170eb84a77f069790cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 2 Nov 2023 09:17:41 +0100 Subject: [PATCH 2/2] Add more tests --- clang/test/AST/Interp/functions.cpp | 74 +++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index 2ce39de3415747a..197a161b9763421 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -390,6 +390,80 @@ constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept { } /// The std::move declaration above gets translated to a builtin function. namespace Move { +#if __cplusplus >= 202002L + consteval int f_eval() { // expected-note 12{{declared here}} \ + // ref-note 12{{declared here}} + return 0; + } + + /// From test/SemaCXX/cxx2a-consteval. + struct Copy { + int(*ptr)(); + constexpr Copy(int(*p)() = nullptr) : ptr(p) {} + consteval Copy(const Copy&) = default; + }; + + constexpr const Copy &to_lvalue_ref(const Copy &&a) { + return a; + } + + void test() { + constexpr const Copy C; + // there is no the copy constructor call when its argument is a prvalue because of garanteed copy elision. + // so we need to test with both prvalue and xvalues. + { Copy c(C); } + { Copy c((Copy(&f_eval))); } // expected-error {{cannot take address of consteval}} \ + // ref-error {{cannot take address of consteval}} + { Copy c(std::move(C)); } + { Copy c(std::move(Copy(&f_eval))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c(to_lvalue_ref((Copy(&f_eval)))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c(to_lvalue_ref(std::move(C))); } + { Copy c(to_lvalue_ref(std::move(Copy(&f_eval)))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c = Copy(C); } + { Copy c = Copy(Copy(&f_eval)); } // expected-error {{cannot take address of consteval}} \ + // ref-error {{cannot take address of consteval}} + { Copy c = Copy(std::move(C)); } + { Copy c = Copy(std::move(Copy(&f_eval))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c = Copy(to_lvalue_ref(Copy(&f_eval))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c = Copy(to_lvalue_ref(std::move(C))); } + { Copy c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c; c = Copy(C); } + { Copy c; c = Copy(Copy(&f_eval)); } // expected-error {{cannot take address of consteval}} \ + // ref-error {{cannot take address of consteval}} + { Copy c; c = Copy(std::move(C)); } + { Copy c; c = Copy(std::move(Copy(&f_eval))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c; c = Copy(to_lvalue_ref(Copy(&f_eval))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + { Copy c; c = Copy(to_lvalue_ref(std::move(C))); } + { Copy c; c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); } // expected-error {{is not a constant expression}} \ + // expected-note {{to a consteval}} \ + // ref-error {{is not a constant expression}} \ + // ref-note {{to a consteval}} + } +#endif constexpr int A = std::move(5); static_assert(A == 5, ""); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits