Skip to content

Bytecode Interpreter: Primtive arrays do not have per-element lifetime informationΒ #147528

Open
@tbaederr

Description

@tbaederr

Similar to their InitMap.

To see this in action, we have to apply

--- i/clang/lib/AST/ByteCode/Compiler.cpp
+++ w/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5008,7 +5008,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
     if (!this->emitCheckPseudoDtor(E))
       return false;
     const Expr *Base = PD->getBase();
-    if (!Base->isGLValue())
+    // if (!Base->isGLValue())
+    if (classify(Base) != PT_Ptr)
       return this->discard(Base);
     if (!this->visit(Base))
       return false;

See:

#define assert_alive(l) if (!__builtin_is_within_lifetime(&l)) (void)(1/0);
#define assert_dead(l)  if ( __builtin_is_within_lifetime(&l)) (void)(1/0);
consteval bool partial_arrays() {
  int arr[2];

  assert_alive(arr);
  assert_alive(arr[0]);
  assert_alive(arr[1]);

  std::construct_at(&arr[0]);
  assert_alive(arr);
  assert_alive(arr[0]);
  assert_alive(arr[1]);



  std::destroy_at(&arr[0]);
  assert_alive(arr);
  assert_dead(arr[0]);
  assert_alive(arr[1]);

  std::construct_at(&arr[0]);

  return true;
}
static_assert(partial_arrays());

The call to std::destroy_at(&arr[0]) will mark the entire array as dead, because that's where the base offset points at the time of calling it.
After this call, the assert_alive(arr) and the assert_alive(array[1]) both fail.

To properly support this, we need so ave the lifetime information for primitive array elements somewhere.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:bytecodeIssues for the clang bytecode constexpr interpreterclang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions