Skip to content

[clang][bytecode] Start implementing builtin_is_within_lifetime #137765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 29, 2025

Conversation

tbaederr
Copy link
Contributor

No description provided.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Apr 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 29, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

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

2 Files Affected:

  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+49)
  • (modified) clang/test/AST/ByteCode/builtin-functions.cpp (+33)
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

@tbaederr tbaederr merged commit 4bf356b into llvm:main Apr 29, 2025
15 checks passed
gizmondo pushed a commit to gizmondo/llvm-project that referenced this pull request Apr 29, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
Ankur-0429 pushed a commit to Ankur-0429/llvm-project that referenced this pull request May 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants