[clang] d612d59 - [clang][Interp] Fix local lvalue compound literals
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 27 07:57:28 PST 2024
Author: Timm Bäder
Date: 2024-02-27T16:57:17+01:00
New Revision: d612d593eff4af7976250023bbff34d2c10f7526
URL: https://github.com/llvm/llvm-project/commit/d612d593eff4af7976250023bbff34d2c10f7526
DIFF: https://github.com/llvm/llvm-project/commit/d612d593eff4af7976250023bbff34d2c10f7526.diff
LOG: [clang][Interp] Fix local lvalue compound literals
Same fix we had for global ones: leave a pointer on the stack.
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/c.c
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index b3a7bc587b647a..2a6216a67e381e 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1700,19 +1700,35 @@ bool ByteCodeExprGen<Emitter>::VisitCompoundLiteralExpr(
}
// Otherwise, use a local variable.
- if (T) {
+ if (T && !E->isLValue()) {
// For primitive types, we just visit the initializer.
return this->delegate(Init);
} else {
- if (std::optional<unsigned> LocalIndex = allocateLocal(Init)) {
- if (!this->emitGetPtrLocal(*LocalIndex, E))
+ unsigned LocalIndex;
+
+ if (T)
+ LocalIndex = this->allocateLocalPrimitive(Init, *T, false, false);
+ else if (std::optional<unsigned> MaybeIndex = this->allocateLocal(Init))
+ LocalIndex = *MaybeIndex;
+ else
+ return false;
+
+ if (!this->emitGetPtrLocal(LocalIndex, E))
+ return false;
+
+ if (T) {
+ if (!this->visit(Init)) {
return false;
+ }
+ return this->emitInit(*T, E);
+ } else {
if (!this->visitInitializer(Init))
return false;
- if (DiscardResult)
- return this->emitPopPtr(E);
- return true;
}
+
+ if (DiscardResult)
+ return this->emitPopPtr(E);
+ return true;
}
return false;
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index caddcb5f978037..db52f6649c18ba 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1399,6 +1399,19 @@ bool StoreBitFieldPop(InterpState &S, CodePtr OpPC) {
return true;
}
+template <PrimType Name, class T = typename PrimConv<Name>::T>
+bool Init(InterpState &S, CodePtr OpPC) {
+ const T &Value = S.Stk.pop<T>();
+ const Pointer &Ptr = S.Stk.peek<Pointer>();
+ if (!CheckInit(S, OpPC, Ptr)) {
+ assert(false);
+ return false;
+ }
+ Ptr.initialize();
+ new (&Ptr.deref<T>()) T(Value);
+ return true;
+}
+
template <PrimType Name, class T = typename PrimConv<Name>::T>
bool InitPop(InterpState &S, CodePtr OpPC) {
const T &Value = S.Stk.pop<T>();
diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index 3f71087ebee567..3e3ba1b163e339 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -476,6 +476,7 @@ def StoreBitField : StoreBitFieldOpcode {}
def StoreBitFieldPop : StoreBitFieldOpcode {}
// [Pointer, Value] -> []
+def Init : StoreOpcode {}
def InitPop : StoreOpcode {}
// [Pointer, Value] -> [Pointer]
def InitElem : Opcode {
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index a6244c3af202a1..2a72c24b43d1cd 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -180,3 +180,19 @@ void test4(void) {
t1 = sizeof(int);
}
+void localCompoundLiteral(void) {
+ struct S { int x, y; } s = {}; // pedantic-expected-warning {{use of an empty initializer}} \
+ // pedantic-ref-warning {{use of an empty initializer}}
+ struct T {
+ int i;
+ struct S s;
+ } t1 = { 1, {} }; // pedantic-expected-warning {{use of an empty initializer}} \
+ // pedantic-ref-warning {{use of an empty initializer}}
+
+ struct T t3 = {
+ (int){}, // pedantic-expected-warning {{use of an empty initializer}} \
+ // pedantic-ref-warning {{use of an empty initializer}}
+ {} // pedantic-expected-warning {{use of an empty initializer}} \
+ // pedantic-ref-warning {{use of an empty initializer}}
+ };
+}
More information about the cfe-commits
mailing list