[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 17 08:53:23 PST 2023
Timm =?utf-8?q?Bäder?= <tbaeder at redhat.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/70772 at 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?= <tbaeder at 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?= <tbaeder at 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, "");
}
More information about the cfe-commits
mailing list