[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-31 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-31 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70772

>From 8449070d0cec2ad120c9d8a36a72594d595b7fea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 31 Oct 2023 07:17:16 +0100
Subject: [PATCH] [clang][Interp] Handle std::move etc. builtins

---
 clang/lib/AST/Interp/ByteCodeExprGen.h  |  9 +--
 clang/lib/AST/Interp/Context.h  | 13 +++-
 clang/lib/AST/Interp/Interp.cpp |  2 +-
 clang/lib/AST/Interp/InterpBuiltin.cpp  | 22 +-
 clang/test/AST/Interp/functions.cpp | 89 +
 clang/test/SemaCXX/builtin-std-move.cpp |  6 +-
 6 files changed, 129 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 893b75b028b6f..315169d487cd4 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,15 +128,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   // If the function does not exist yet, it is compiled.
   const Function *getFunction(const FunctionDecl *FD);
 
-  /// Classifies a type.
   std::optional classify(const Expr *E) const {
-if (E->isGLValue()) {
-  if (E->getType()->isFunctionType())
-return PT_FnPtr;
-  return PT_Ptr;
-}
-
-return classify(E->getType());
+return Ctx.classify(E);
   }
   std::optional classify(QualType Ty) const {
 return Ctx.classify(Ty);
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index ab83a8d132246..c7620921e467e 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -70,9 +70,20 @@ class Context final {
   /// Return the size of T in bits.
   uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
-  /// Classifies an expression.
+  /// Classifies a type.
   std::optional classify(QualType T) const;
 
+  /// Classifies an expression.
+  std::optional classify(const Expr *E) const {
+if (E->isGLValue()) {
+  if (E->getType()->isFunctionType())
+return PT_FnPtr;
+  return PT_Ptr;
+}
+
+return classify(E->getType());
+  }
+
   const CXXMethodDecl *
   getOverridingFunction(const CXXRecordDecl *DynamicDecl,
 const CXXRecordDecl *StaticDecl,
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index be9ed81af69ec..4c3184aec9968 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -141,7 +141,7 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
 namespace clang {
 namespace interp {
 static void popArg(InterpState &S, const Expr *Arg) {
-  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  PrimType Ty = S.getContext().classify(Arg).value_or(PT_Ptr);
   TYPE_SWITCH(Ty, S.Stk.discard());
 }
 
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 754ca96b0c645..280aa39398c8e 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -634,12 +634,23 @@ static bool interp__builtin_addressof(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_move(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame, const Function 
*Func,
+ const CallExpr *Call) {
+
+  PrimType ArgT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr);
+
+  TYPE_SWITCH(ArgT, const T &Arg = S.Stk.peek(); S.Stk.push(Arg););
+
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
   APValue Dummy;
 
-  std::optional ReturnT = S.getContext().classify(Call->getType());
+  std::optional ReturnT = S.getContext().classify(Call);
 
   // If classify failed, we assume void.
   assert(ReturnT || Call->getType()->isVoidType());
@@ -848,6 +859,15 @@ 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:
+  case Builtin::BImove_if_noexcept:
+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 75f3c5d192b2c..6e995ce704e39 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -413,3 +413,92 @@ namespace AddressOf {
   constexpr _Complex float F = {3, 4};
   static_assert(__builtin_addressof(F) == &F, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_ref

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-25 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70772

>From 7f4cb1f727a497c6da1fc3f4740522ff5adb3964 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 31 Oct 2023 07:17:16 +0100
Subject: [PATCH] [clang][Interp] Handle std::move etc. builtins

---
 clang/lib/AST/Interp/ByteCodeExprGen.h  |  9 +--
 clang/lib/AST/Interp/Context.h  | 13 +++-
 clang/lib/AST/Interp/Interp.cpp |  2 +-
 clang/lib/AST/Interp/InterpBuiltin.cpp  | 22 +-
 clang/test/AST/Interp/functions.cpp | 89 +
 clang/test/SemaCXX/builtin-std-move.cpp |  6 +-
 6 files changed, 129 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 63ea8292b587675..9fc8ce13b1d7fda 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,15 +128,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   // If the function does not exist yet, it is compiled.
   const Function *getFunction(const FunctionDecl *FD);
 
-  /// Classifies a type.
   std::optional classify(const Expr *E) const {
-if (E->isGLValue()) {
-  if (E->getType()->isFunctionType())
-return PT_FnPtr;
-  return PT_Ptr;
-}
-
-return classify(E->getType());
+return Ctx.classify(E);
   }
   std::optional classify(QualType Ty) const {
 return Ctx.classify(Ty);
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index ab83a8d13224670..c7620921e467e71 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -70,9 +70,20 @@ class Context final {
   /// Return the size of T in bits.
   uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
-  /// Classifies an expression.
+  /// Classifies a type.
   std::optional classify(QualType T) const;
 
+  /// Classifies an expression.
+  std::optional classify(const Expr *E) const {
+if (E->isGLValue()) {
+  if (E->getType()->isFunctionType())
+return PT_FnPtr;
+  return PT_Ptr;
+}
+
+return classify(E->getType());
+  }
+
   const CXXMethodDecl *
   getOverridingFunction(const CXXRecordDecl *DynamicDecl,
 const CXXRecordDecl *StaticDecl,
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 807b860f3565d3a..38861253b217323 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -141,7 +141,7 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
 namespace clang {
 namespace interp {
 static void popArg(InterpState &S, const Expr *Arg) {
-  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  PrimType Ty = S.getContext().classify(Arg).value_or(PT_Ptr);
   TYPE_SWITCH(Ty, S.Stk.discard());
 }
 
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 754ca96b0c645e5..280aa39398c8e9a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -634,12 +634,23 @@ static bool interp__builtin_addressof(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_move(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame, const Function 
*Func,
+ const CallExpr *Call) {
+
+  PrimType ArgT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr);
+
+  TYPE_SWITCH(ArgT, const T &Arg = S.Stk.peek(); S.Stk.push(Arg););
+
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
   APValue Dummy;
 
-  std::optional ReturnT = S.getContext().classify(Call->getType());
+  std::optional ReturnT = S.getContext().classify(Call);
 
   // If classify failed, we assume void.
   assert(ReturnT || Call->getType()->isVoidType());
@@ -848,6 +859,15 @@ 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:
+  case Builtin::BImove_if_noexcept:
+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 75f3c5d192b2cf2..6e995ce704e3949 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -413,3 +413,92 @@ namespace AddressOf {
   constexpr _Complex float F = {3, 4};
   static_assert(__builtin_addressof(F) == &F, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr type

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-19 Thread Timm Baeder via cfe-commits


@@ -378,3 +378,92 @@ namespace Packs {
   static_assert(foo() == 2, "");
   static_assert(foo<>() == 0, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::type &&>(t);
+}
+}
+/// The std::move declaration above gets translated to a builtin function.
+namespace Move {

tbaederr wrote:

I've enabled `test/SemaCXX/builtin-std-move.cpp` with the new interpreter.

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-19 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70772

>From c6c7d246b334a95306cda410e7d115353acb7c5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 31 Oct 2023 07:17:16 +0100
Subject: [PATCH] [clang][Interp] Handle std::move etc. builtins

---
 clang/lib/AST/Interp/ByteCodeExprGen.h  |  9 +--
 clang/lib/AST/Interp/Context.h  | 13 +++-
 clang/lib/AST/Interp/Interp.cpp |  2 +-
 clang/lib/AST/Interp/InterpBuiltin.cpp  | 22 +-
 clang/test/AST/Interp/functions.cpp | 89 +
 clang/test/SemaCXX/builtin-std-move.cpp |  6 +-
 6 files changed, 129 insertions(+), 12 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h 
b/clang/lib/AST/Interp/ByteCodeExprGen.h
index df4cb736299cb62..907e6f1f764502c 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -128,15 +128,8 @@ class ByteCodeExprGen : public 
ConstStmtVisitor, bool>,
   // If the function does not exist yet, it is compiled.
   const Function *getFunction(const FunctionDecl *FD);
 
-  /// Classifies a type.
   std::optional classify(const Expr *E) const {
-if (E->isGLValue()) {
-  if (E->getType()->isFunctionType())
-return PT_FnPtr;
-  return PT_Ptr;
-}
-
-return classify(E->getType());
+return Ctx.classify(E);
   }
   std::optional classify(QualType Ty) const {
 return Ctx.classify(Ty);
diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h
index ab83a8d13224670..c7620921e467e71 100644
--- a/clang/lib/AST/Interp/Context.h
+++ b/clang/lib/AST/Interp/Context.h
@@ -70,9 +70,20 @@ class Context final {
   /// Return the size of T in bits.
   uint32_t getBitWidth(QualType T) const { return Ctx.getIntWidth(T); }
 
-  /// Classifies an expression.
+  /// Classifies a type.
   std::optional classify(QualType T) const;
 
+  /// Classifies an expression.
+  std::optional classify(const Expr *E) const {
+if (E->isGLValue()) {
+  if (E->getType()->isFunctionType())
+return PT_FnPtr;
+  return PT_Ptr;
+}
+
+return classify(E->getType());
+  }
+
   const CXXMethodDecl *
   getOverridingFunction(const CXXRecordDecl *DynamicDecl,
 const CXXRecordDecl *StaticDecl,
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 807b860f3565d3a..38861253b217323 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -141,7 +141,7 @@ static bool CheckGlobal(InterpState &S, CodePtr OpPC, const 
Pointer &Ptr) {
 namespace clang {
 namespace interp {
 static void popArg(InterpState &S, const Expr *Arg) {
-  PrimType Ty = S.getContext().classify(Arg->getType()).value_or(PT_Ptr);
+  PrimType Ty = S.getContext().classify(Arg).value_or(PT_Ptr);
   TYPE_SWITCH(Ty, S.Stk.discard());
 }
 
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 754ca96b0c645e5..280aa39398c8e9a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -634,12 +634,23 @@ static bool interp__builtin_addressof(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_move(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame, const Function 
*Func,
+ const CallExpr *Call) {
+
+  PrimType ArgT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr);
+
+  TYPE_SWITCH(ArgT, const T &Arg = S.Stk.peek(); S.Stk.push(Arg););
+
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
   APValue Dummy;
 
-  std::optional ReturnT = S.getContext().classify(Call->getType());
+  std::optional ReturnT = S.getContext().classify(Call);
 
   // If classify failed, we assume void.
   assert(ReturnT || Call->getType()->isVoidType());
@@ -848,6 +859,15 @@ 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:
+  case Builtin::BImove_if_noexcept:
+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 75f3c5d192b2cf2..6e995ce704e3949 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -413,3 +413,92 @@ namespace AddressOf {
   constexpr _Complex float F = {3, 4};
   static_assert(__builtin_addressof(F) == &F, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr type

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-15 Thread via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff e3993e044ec5925e59c131f798f823a9f16f0433 
f4f4dd022d09dee65b6152d083af1c7fba9c8052 -- 
clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Context.h 
clang/lib/AST/Interp/Interp.cpp clang/lib/AST/Interp/InterpBuiltin.cpp 
clang/test/AST/Interp/functions.cpp clang/test/SemaCXX/builtin-std-move.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp
index 3956eec6cd..ae25ce13fd 100644
--- a/clang/lib/AST/Interp/Interp.cpp
+++ b/clang/lib/AST/Interp/Interp.cpp
@@ -383,9 +383,9 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const 
Function *F) {
   << CD->getInheritedConstructor().getConstructor()->getParent();
 S.Note(DiagDecl->getLocation(), diag::note_declared_at);
   } else {
-// Don't emit anything if the function isn't defined and we're 
checking for
-// a constnat expression. It might be defined at the point we're 
actually
-// calling it.
+// Don't emit anything if the function isn't defined and we're checking
+// for a constnat expression. It might be defined at the point we're
+// actually calling it.
 if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression())
   return false;
 

``




https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2024-01-15 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= ,
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70772

>From e850b96306ab5d9e6aac4171150195ea013f6ec2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 31 Oct 2023 07:17:16 +0100
Subject: [PATCH 1/5] [clang][Interp] Handle std::move etc. builtins

---
 clang/lib/AST/Interp/InterpBuiltin.cpp | 17 +
 clang/test/AST/Interp/functions.cpp| 15 +++
 2 files changed, 32 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index 754ca96b0c645e..142f92ffc337c3 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -634,6 +634,15 @@ static bool interp__builtin_addressof(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();
+  S.Stk.push(Arg);
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -848,6 +857,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 75f3c5d192b2cf..019af555c347a6 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -413,3 +413,18 @@ namespace AddressOf {
   constexpr _Complex float F = {3, 4};
   static_assert(__builtin_addressof(F) == &F, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::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 d90032c82863ea20e7896b78c1d9b78590603a15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Thu, 2 Nov 2023 09:17:41 +0100
Subject: [PATCH 2/5] 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 019af555c347a6..6e995ce704e394 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -425,6 +425,80 @@ constexpr typename std::remove_reference::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; }

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-12-08 Thread Aaron Ballman via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


https://github.com/AaronBallman approved this pull request.

LGTM assuming no surprises come up from the additional test coverage.

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-12-08 Thread Aaron Ballman via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 



@@ -378,3 +378,92 @@ namespace Packs {
   static_assert(foo() == 2, "");
   static_assert(foo<>() == 0, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::type &&>(t);
+}
+}
+/// The std::move declaration above gets translated to a builtin function.
+namespace Move {

AaronBallman wrote:

I'd like to see test coverage involving a move constructor, a move assignment 
operator, a direct call to __builtin_move, and some testing for `std::as_const` 
and `std::forward`. Of special interest would be times when there's UB in the 
move constructor/move assignment that should be caught or a non-copyable object 
where move semantics are the only thing that should work.

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-12-08 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-27 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-17 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


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?= 
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(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();
+  S.Stk.push(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() == 2, "");
   static_assert(foo<>() == 0, "");
 }
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::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?= 
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::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}} \
+  

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-17 Thread Henrik G. Olsson via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


hnrklssn wrote:

LGTM, but someone else should approve also.

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-13 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-08 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?B=C3=A4der?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

Ping

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


tbaederr wrote:

> Nice. I realise you're following the convention already established in the 
> test file, but have you considered compiling with `-verify=new,both` and 
> `-verify=ref,both`, respectively, and combining the shared diagnostics into 
> `both-error` etc. to make it easier to see when they do and don't align?

That might be an interesting approach for the next new test file I add, thanks.

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-02 Thread Henrik G. Olsson via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


hnrklssn wrote:

Nice. I realise you're following the convention already established in the test 
file, but have you considered compiling with `-verify=new,both` and 
`-verify=ref,both`, respectively, and combining the shared diagnostics into 
`both-error` etc. to make it easier to see when they do and don't align?

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-02 Thread Timm Baeder via cfe-commits
Timm =?utf-8?q?Bäder?= 
Message-ID:
In-Reply-To: 


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/70772

>From b670986c19e412b3c140b610f2c26d957544b23a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
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 | 17 +
 clang/test/AST/Interp/functions.cpp| 16 
 2 files changed, 33 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index e329794cb79243d..10e703d868f168a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -412,6 +412,15 @@ static bool interp__builtin_popcount(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();
+  S.Stk.push(Arg);
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -537,6 +546,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return retInt(S, OpPC, Dummy);
 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 Ret(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 4bef9c2f7c0d1fa..364744203424380 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -371,3 +371,19 @@ namespace Variadic {
   constexpr int (*VFP)(...) = variadic_function2;
   static_assert(VFP() == 12, "");
 }
+
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::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 84b0f98a1ab95f49d3f4fe10bb8c2add63e4d55c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
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 364744203424380..c9a6b348adc0174 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -384,6 +384,80 @@ constexpr typename std::remove_reference::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 expr

[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-11-01 Thread Henrik G. Olsson via cfe-commits

hnrklssn wrote:

Would making a class with custom move and copy constructors with side effects, 
and moving/copying an instance around a bit to affect the results of 
static_asserts, work for testing?

https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-10-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)


Changes

Only light testing here since I'm not sure how to properly test this.

---
Full diff: https://github.com/llvm/llvm-project/pull/70772.diff


2 Files Affected:

- (modified) clang/lib/AST/Interp/InterpBuiltin.cpp (+17) 
- (modified) clang/test/AST/Interp/functions.cpp (+16) 


``diff
diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index e329794cb79243d..10e703d868f168a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -412,6 +412,15 @@ static bool interp__builtin_popcount(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();
+  S.Stk.push(Arg);
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -537,6 +546,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return retInt(S, OpPC, Dummy);
 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 Ret(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 4bef9c2f7c0d1fa..364744203424380 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -371,3 +371,19 @@ namespace Variadic {
   constexpr int (*VFP)(...) = variadic_function2;
   static_assert(VFP() == 12, "");
 }
+
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::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, "");
+}

``




https://github.com/llvm/llvm-project/pull/70772
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Interp] Handle std::move etc. builtins (PR #70772)

2023-10-30 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/70772

Only light testing here since I'm not sure how to properly test this.

>From b670986c19e412b3c140b610f2c26d957544b23a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= 
Date: Tue, 31 Oct 2023 07:17:16 +0100
Subject: [PATCH] [clang][Interp] Handle std::move etc. builtins

---
 clang/lib/AST/Interp/InterpBuiltin.cpp | 17 +
 clang/test/AST/Interp/functions.cpp| 16 
 2 files changed, 33 insertions(+)

diff --git a/clang/lib/AST/Interp/InterpBuiltin.cpp 
b/clang/lib/AST/Interp/InterpBuiltin.cpp
index e329794cb79243d..10e703d868f168a 100644
--- a/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -412,6 +412,15 @@ static bool interp__builtin_popcount(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();
+  S.Stk.push(Arg);
+  return Func->getDecl()->isConstexpr();
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
   const CallExpr *Call) {
   InterpFrame *Frame = S.Current;
@@ -537,6 +546,14 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const 
Function *F,
   return retInt(S, OpPC, Dummy);
 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 Ret(S, OpPC, Dummy);
+break;
+
   default:
 return false;
   }
diff --git a/clang/test/AST/Interp/functions.cpp 
b/clang/test/AST/Interp/functions.cpp
index 4bef9c2f7c0d1fa..364744203424380 100644
--- a/clang/test/AST/Interp/functions.cpp
+++ b/clang/test/AST/Interp/functions.cpp
@@ -371,3 +371,19 @@ namespace Variadic {
   constexpr int (*VFP)(...) = variadic_function2;
   static_assert(VFP() == 12, "");
 }
+
+
+namespace std {
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template  struct remove_reference { using type = T; };
+template 
+constexpr typename std::remove_reference::type&& move(T &&t) noexcept {
+  return static_cast::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, "");
+}

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits