[clang] 03888a9 - [clang][bytecode] Handle non-arrays in initElem{,Pop} (#112719)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 17 10:07:50 PDT 2024
Author: Timm Baeder
Date: 2024-10-17T19:07:47+02:00
New Revision: 03888a9046167c50c20e219e790d616b42b91608
URL: https://github.com/llvm/llvm-project/commit/03888a9046167c50c20e219e790d616b42b91608
DIFF: https://github.com/llvm/llvm-project/commit/03888a9046167c50c20e219e790d616b42b91608.diff
LOG: [clang][bytecode] Handle non-arrays in initElem{,Pop} (#112719)
... provided the given index is 0. Skip the atIndex() in that case.
Added:
Modified:
clang/lib/AST/ByteCode/Interp.h
clang/test/AST/ByteCode/placement-new.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index dece95971b7617..a1a92562cc5e3d 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1863,13 +1863,24 @@ bool InitPop(InterpState &S, CodePtr OpPC) {
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool InitElem(InterpState &S, CodePtr OpPC, uint32_t Idx) {
const T &Value = S.Stk.pop<T>();
- const Pointer &Ptr = S.Stk.peek<Pointer>().atIndex(Idx);
+ const Pointer &Ptr = S.Stk.peek<Pointer>();
+
if (Ptr.isUnknownSizeArray())
return false;
- if (!CheckInit(S, OpPC, Ptr))
+
+ // In the unlikely event that we're initializing the first item of
+ // a non-array, skip the atIndex().
+ if (Idx == 0 && !Ptr.getFieldDesc()->isArray()) {
+ Ptr.initialize();
+ new (&Ptr.deref<T>()) T(Value);
+ return true;
+ }
+
+ const Pointer &ElemPtr = Ptr.atIndex(Idx);
+ if (!CheckInit(S, OpPC, ElemPtr))
return false;
- Ptr.initialize();
- new (&Ptr.deref<T>()) T(Value);
+ ElemPtr.initialize();
+ new (&ElemPtr.deref<T>()) T(Value);
return true;
}
@@ -1877,13 +1888,23 @@ bool InitElem(InterpState &S, CodePtr OpPC, uint32_t Idx) {
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool InitElemPop(InterpState &S, CodePtr OpPC, uint32_t Idx) {
const T &Value = S.Stk.pop<T>();
- const Pointer &Ptr = S.Stk.pop<Pointer>().atIndex(Idx);
+ const Pointer &Ptr = S.Stk.pop<Pointer>();
if (Ptr.isUnknownSizeArray())
return false;
- if (!CheckInit(S, OpPC, Ptr))
+
+ // In the unlikely event that we're initializing the first item of
+ // a non-array, skip the atIndex().
+ if (Idx == 0 && !Ptr.getFieldDesc()->isArray()) {
+ Ptr.initialize();
+ new (&Ptr.deref<T>()) T(Value);
+ return true;
+ }
+
+ const Pointer &ElemPtr = Ptr.atIndex(Idx);
+ if (!CheckInit(S, OpPC, ElemPtr))
return false;
- Ptr.initialize();
- new (&Ptr.deref<T>()) T(Value);
+ ElemPtr.initialize();
+ new (&ElemPtr.deref<T>()) T(Value);
return true;
}
diff --git a/clang/test/AST/ByteCode/placement-new.cpp b/clang/test/AST/ByteCode/placement-new.cpp
index caf3ac97fd1c04..6bd83f2372eab6 100644
--- a/clang/test/AST/ByteCode/placement-new.cpp
+++ b/clang/test/AST/ByteCode/placement-new.cpp
@@ -52,6 +52,20 @@ consteval auto ok4() {
}
static_assert(ok4() == 37);
+consteval int ok5() {
+ int i;
+ new (&i) int[1]{1};
+
+ struct S {
+ int a; int b;
+ } s;
+ new (&s) S[1]{{12, 13}};
+
+ return 25;
+ // return s.a + s.b; FIXME: Broken in the current interpreter.
+}
+static_assert(ok5() == 25);
+
/// FIXME: Broken in both interpreters.
#if 0
consteval int ok5() {
More information about the cfe-commits
mailing list