-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][bytecode] Allow forming pointers to fields of extern globals #137211
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
Conversation
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesThis should be fine as long as we're not reading from it. Note that this regresses 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:
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.
…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.
…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.
…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.
…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.
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:
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.