Skip to content

Commit

Permalink
[clang][Interp] Fix a designated initializer testcase
Browse files Browse the repository at this point in the history
This protected GetPtrField and ArrayDecay ops from dummy pointers
which fixes the attached test case for designated initializers in C.
  • Loading branch information
tbaederr committed Feb 12, 2024
1 parent ea8de6e commit 635dfd5
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 9 deletions.
21 changes: 13 additions & 8 deletions clang/lib/AST/Interp/Interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
12 changes: 12 additions & 0 deletions clang/test/AST/Interp/c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

0 comments on commit 635dfd5

Please sign in to comment.