Skip to content

Conversation

@tbaederr
Copy link
Contributor

This should be fine as long as we're not reading from it.

Note that this regresses
CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work fine with the bytecode interpreter.

That's because this code now fails:

  struct Param;
  struct A {
    constexpr A(Param);
    int a;
  };

  struct B : A { B(); using A::A; int b = 2; };
  struct Wrap1 : B { constexpr Wrap1(); };
  struct Wrap2 : Wrap1 {};
  extern const Wrap2 b;

  struct Param {
    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
    int n;
  };

and reports that the Param() constructor is never a valid constant expression. But that's true and the current interpeter should report that as well. It also fails when calling at compile time.

@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 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Apr 24, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

This should be fine as long as we're not reading from it.

Note that this regresses
CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work fine with the bytecode interpreter.

That's because this code now fails:

  struct Param;
  struct A {
    constexpr A(Param);
    int a;
  };

  struct B : A { B(); using A::A; int b = 2; };
  struct Wrap1 : B { constexpr Wrap1(); };
  struct Wrap2 : Wrap1 {};
  extern const Wrap2 b;

  struct Param {
    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
    int n;
  };

and reports that the Param() constructor is never a valid constant expression. But that's true and the current interpeter should report that as well. It also fails when calling at compile time.


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

2 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Interp.cpp (-2)
  • (modified) clang/test/AST/ByteCode/cxx11.cpp (+6)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 6f277a7488836..23fd894bd6a3e 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1323,8 +1323,6 @@ static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
       !CheckNull(S, OpPC, Ptr, CSK_Field))
     return false;
 
-  if (!CheckExtern(S, OpPC, Ptr))
-    return false;
   if (!CheckRange(S, OpPC, Ptr, CSK_Field))
     return false;
   if (!CheckArray(S, OpPC, Ptr))
diff --git a/clang/test/AST/ByteCode/cxx11.cpp b/clang/test/AST/ByteCode/cxx11.cpp
index 004f704145afd..79a02dc4ba162 100644
--- a/clang/test/AST/ByteCode/cxx11.cpp
+++ b/clang/test/AST/ByteCode/cxx11.cpp
@@ -194,3 +194,9 @@ namespace DynamicCast {
     int g : (S*)(void*)(sptr) == sptr;
   };
 }
+
+namespace ExternPointer {
+  struct S { int a; };
+  extern const S pu;
+  constexpr const int *pua = &pu.a; // Ok.
+}

This should be fine as long as we're not reading from it.

Note that this regresses
CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work
fine with the bytecode interpreter.

That's because this code now fails:

  struct Param;
  struct A {
    constexpr A(Param);
    int a;
  };

  struct B : A { B(); using A::A; int b = 2; };
  struct Wrap1 : B { constexpr Wrap1(); };
  struct Wrap2 : Wrap1 {};
  extern const Wrap2 b;

  struct Param {
    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
    int n;
  };

and reports that the Param() constructor is never a valid constant
expression. But that's true and the current interpeter should
report that as well. It also fails when calling at compile time.
@tbaederr tbaederr merged commit 3b58a60 into llvm:main Apr 25, 2025
11 checks passed
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…lvm#137211)

This should be fine as long as we're not reading from it.

Note that this regresses
CXX/special/class.init/class.inhctor.init/p1.cpp, which used to work
fine with the bytecode interpreter.

That's because this code now fails:

```c++
  struct Param;
  struct A {
    constexpr A(Param);
    int a;
  };

  struct B : A { B(); using A::A; int b = 2; };
  struct Wrap1 : B { constexpr Wrap1(); };
  struct Wrap2 : Wrap1 {};
  extern const Wrap2 b;

  struct Param {
    constexpr Param(int c) : n(4 * b.a + b.b + c) {}
    int n;
  };
```
and reports that the Param() constructor is never a valid constant
expression. But that's true and the current interpeter should report
that as well. It also fails when calling at compile time.
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