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

None

>From 609b14ff51520373247a85dc27e11ccc7335cee9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Tue, 29 Apr 2025 09:28:39 +0200
Subject: [PATCH] [clang][bytecode] Start implementing
 builtin_is_within_lifetime

---
 clang/lib/AST/ByteCode/InterpBuiltin.cpp      | 49 +++++++++++++++++++
 clang/test/AST/ByteCode/builtin-functions.cpp | 33 +++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp 
b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 34baae1986c35..2804985cb867b 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2184,6 +2184,50 @@ static bool interp__builtin_object_size(InterpState &S, 
CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
+                                               const CallExpr *Call) {
+
+  if (!S.inConstantContext())
+    return false;
+
+  const Pointer &Ptr = S.Stk.peek<Pointer>();
+
+  auto Error = [&](int Diag) {
+    bool CalledFromStd = false;
+    const auto *Callee = S.Current->getCallee();
+    if (Callee && Callee->isInStdNamespace()) {
+      const IdentifierInfo *Identifier = Callee->getIdentifier();
+      CalledFromStd = Identifier && Identifier->isStr("is_within_lifetime");
+    }
+    S.CCEDiag(CalledFromStd
+                  ? S.Current->Caller->getSource(S.Current->getRetPC())
+                  : S.Current->getSource(OpPC),
+              diag::err_invalid_is_within_lifetime)
+        << (CalledFromStd ? "std::is_within_lifetime"
+                          : "__builtin_is_within_lifetime")
+        << Diag;
+    return false;
+  };
+
+  if (Ptr.isZero())
+    return Error(0);
+  if (Ptr.isOnePastEnd())
+    return Error(1);
+
+  bool Result = true;
+  if (!Ptr.isActive()) {
+    Result = false;
+  } else {
+    if (!CheckLive(S, OpPC, Ptr, AK_Read))
+      return false;
+    if (!CheckMutable(S, OpPC, Ptr))
+      return false;
+  }
+
+  pushInteger(S, Result, Call->getType());
+  return true;
+}
+
 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
                       uint32_t BuiltinID) {
   if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID))
@@ -2693,6 +2737,11 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, 
const CallExpr *Call,
       return false;
     break;
 
+  case Builtin::BI__builtin_is_within_lifetime:
+    if (!interp__builtin_is_within_lifetime(S, OpPC, Call))
+      return false;
+    break;
+
   default:
     S.FFDiag(S.Current->getLocation(OpPC),
              diag::note_invalid_subexpr_in_const_expr)
diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp 
b/clang/test/AST/ByteCode/builtin-functions.cpp
index a4c8ec4856ecc..a7fbb1c6743d8 100644
--- a/clang/test/AST/ByteCode/builtin-functions.cpp
+++ b/clang/test/AST/ByteCode/builtin-functions.cpp
@@ -1697,3 +1697,36 @@ namespace Invalid {
   static_assert(test() == 0); // both-error {{not an integral constant 
expression}} \
                               // both-note {{in call to}}
 }
+
+#if __cplusplus >= 202002L
+namespace WithinLifetime {
+  constexpr int a = 10;
+  static_assert(__builtin_is_within_lifetime(&a));
+
+  consteval int IsActive(bool ReadB) {
+    union {
+      int a, b;
+    } A;
+    A.a = 10;
+    if (ReadB)
+      return __builtin_is_within_lifetime(&A.b);
+    return __builtin_is_within_lifetime(&A.a);
+  }
+  static_assert(IsActive(false));
+  static_assert(!IsActive(true));
+
+  static_assert(__builtin_is_within_lifetime((void*)nullptr)); // both-error 
{{not an integral constant expression}} \
+                                                               // both-note 
{{'__builtin_is_within_lifetime' cannot be called with a null pointer}}
+
+  constexpr int i = 2;
+  constexpr int arr[2]{};
+  void f() {
+    __builtin_is_within_lifetime(&i + 1); // both-error {{call to consteval 
function '__builtin_is_within_lifetime' is not a constant expression}} \
+                                          // both-note 
{{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end 
pointer}} \
+                                          // both-warning {{expression result 
unused}}
+    __builtin_is_within_lifetime(arr + 2); // both-error {{call to consteval 
function '__builtin_is_within_lifetime' is not a constant expression}} \
+                                           // both-note 
{{'__builtin_is_within_lifetime' cannot be called with a one-past-the-end 
pointer}} \
+                                           // both-warning {{expression result 
unused}}
+  }
+}
+#endif

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

Reply via email to