[clang] 635dfd5 - [clang][Interp] Fix a designated initializer testcase
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Mon Feb 12 06:57:30 PST 2024
Author: Timm Bäder
Date: 2024-02-12T15:36:07+01:00
New Revision: 635dfd5d69c6be52a8a2bb612f3483d9a1226cfa
URL: https://github.com/llvm/llvm-project/commit/635dfd5d69c6be52a8a2bb612f3483d9a1226cfa
DIFF: https://github.com/llvm/llvm-project/commit/635dfd5d69c6be52a8a2bb612f3483d9a1226cfa.diff
LOG: [clang][Interp] Fix a designated initializer testcase
This protected GetPtrField and ArrayDecay ops from dummy pointers
which fixes the attached test case for designated initializers in C.
Added:
Modified:
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Pointer.cpp
clang/test/AST/Interp/c.c
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 15c137098af355..e2fda18e3f44d4 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1187,15 +1187,18 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
/// 2) Pushes Pointer.atField(Off) on the stack
inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
+
if (S.inConstantContext() && !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 (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
- return false;
+ if (CheckDummy(S, OpPC, Ptr)) {
+ if (!CheckExtern(S, OpPC, Ptr))
+ return false;
+ if (!CheckRange(S, OpPC, Ptr, CSK_Field))
+ return false;
+ if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
+ return false;
+ }
S.Stk.push<Pointer>(Ptr.atField(Off));
return true;
}
@@ -1896,8 +1899,10 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
const Pointer &Ptr = S.Stk.pop<Pointer>();
- if (Ptr.isDummy())
- return false;
+ if (Ptr.isDummy()) {
+ S.Stk.push<Pointer>(Ptr);
+ return true;
+ }
if (!Ptr.isUnknownSizeArray()) {
S.Stk.push<Pointer>(Ptr.atIndex(0));
diff --git a/clang/lib/AST/Interp/Pointer.cpp b/clang/lib/AST/Interp/Pointer.cpp
index 1eedbc360c1575..d68af7922af5aa 100644
--- a/clang/lib/AST/Interp/Pointer.cpp
+++ b/clang/lib/AST/Interp/Pointer.cpp
@@ -99,7 +99,7 @@ APValue Pointer::toAPValue() const {
else
llvm_unreachable("Invalid allocation type");
- if (isUnknownSizeArray() || Desc->asExpr())
+ if (isDummy() || isUnknownSizeArray() || Desc->asExpr())
return APValue(Base, CharUnits::Zero(), Path, false, false);
// TODO: compute the offset into the object.
diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c
index afbc518e2af600..392b682afd602b 100644
--- a/clang/test/AST/Interp/c.c
+++ b/clang/test/AST/Interp/c.c
@@ -112,3 +112,15 @@ _Static_assert(sizeof(name2) == 0, ""); // expected-error {{failed}} \
#ifdef __SIZEOF_INT128__
void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1]; // all-warning {{refers past the last possible element}}
#endif
+
+extern float global_float;
+struct XX { int a, *b; };
+struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
+ 0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
+ [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float,
+ 0, // all-note {{previous initialization is here}}
+ 0, // all-note {{previous initialization is here}}
+ [2].before = 0, // all-warning {{initializer overrides prior initialization of this subobject}}
+ 0, // all-warning {{initializer overrides prior initialization of this subobject}}
+ &xy[2].xx.a, &xy[2].xx, &global_float
+};
More information about the cfe-commits
mailing list