Skip to content

Commit 635dfd5

Browse files
committed
[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.
1 parent ea8de6e commit 635dfd5

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

clang/lib/AST/Interp/Interp.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,15 +1187,18 @@ inline bool GetPtrGlobal(InterpState &S, CodePtr OpPC, uint32_t I) {
11871187
/// 2) Pushes Pointer.atField(Off) on the stack
11881188
inline bool GetPtrField(InterpState &S, CodePtr OpPC, uint32_t Off) {
11891189
const Pointer &Ptr = S.Stk.pop<Pointer>();
1190+
11901191
if (S.inConstantContext() && !CheckNull(S, OpPC, Ptr, CSK_Field))
11911192
return false;
1192-
if (!CheckExtern(S, OpPC, Ptr))
1193-
return false;
1194-
if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1195-
return false;
1196-
if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1197-
return false;
11981193

1194+
if (CheckDummy(S, OpPC, Ptr)) {
1195+
if (!CheckExtern(S, OpPC, Ptr))
1196+
return false;
1197+
if (!CheckRange(S, OpPC, Ptr, CSK_Field))
1198+
return false;
1199+
if (!CheckSubobject(S, OpPC, Ptr, CSK_Field))
1200+
return false;
1201+
}
11991202
S.Stk.push<Pointer>(Ptr.atField(Off));
12001203
return true;
12011204
}
@@ -1896,8 +1899,10 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) {
18961899
inline bool ArrayDecay(InterpState &S, CodePtr OpPC) {
18971900
const Pointer &Ptr = S.Stk.pop<Pointer>();
18981901

1899-
if (Ptr.isDummy())
1900-
return false;
1902+
if (Ptr.isDummy()) {
1903+
S.Stk.push<Pointer>(Ptr);
1904+
return true;
1905+
}
19011906

19021907
if (!Ptr.isUnknownSizeArray()) {
19031908
S.Stk.push<Pointer>(Ptr.atIndex(0));

clang/lib/AST/Interp/Pointer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ APValue Pointer::toAPValue() const {
9999
else
100100
llvm_unreachable("Invalid allocation type");
101101

102-
if (isUnknownSizeArray() || Desc->asExpr())
102+
if (isDummy() || isUnknownSizeArray() || Desc->asExpr())
103103
return APValue(Base, CharUnits::Zero(), Path, false, false);
104104

105105
// TODO: compute the offset into the object.

clang/test/AST/Interp/c.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,15 @@ _Static_assert(sizeof(name2) == 0, ""); // expected-error {{failed}} \
112112
#ifdef __SIZEOF_INT128__
113113
void *PR28739d = &(&PR28739d)[(__int128)(unsigned long)-1]; // all-warning {{refers past the last possible element}}
114114
#endif
115+
116+
extern float global_float;
117+
struct XX { int a, *b; };
118+
struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
119+
0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
120+
[1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float,
121+
0, // all-note {{previous initialization is here}}
122+
0, // all-note {{previous initialization is here}}
123+
[2].before = 0, // all-warning {{initializer overrides prior initialization of this subobject}}
124+
0, // all-warning {{initializer overrides prior initialization of this subobject}}
125+
&xy[2].xx.a, &xy[2].xx, &global_float
126+
};

0 commit comments

Comments
 (0)