Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,8 +1435,12 @@ static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
return false;

if (Ptr.isIntegralPointer()) {
S.Stk.push<Pointer>(Ptr.asIntPointer().atOffset(S.getASTContext(), Off));
return true;
if (std::optional<IntPointer> IntPtr =
Ptr.asIntPointer().atOffset(S.getASTContext(), Off)) {
S.Stk.push<Pointer>(std::move(*IntPtr));
return true;
}
return false;
}

if (!Ptr.isBlockPointer()) {
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/AST/ByteCode/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -895,8 +895,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
return Result;
}

IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
unsigned Offset) const {
std::optional<IntPointer> IntPointer::atOffset(const ASTContext &ASTCtx,
unsigned Offset) const {
if (!this->Desc)
return *this;
const Record *R = this->Desc->ElemRecord;
Expand All @@ -914,6 +914,9 @@ IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
return *this;

const FieldDecl *FD = F->Decl;
if (FD->getParent()->isInvalidDecl())
return std::nullopt;

const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(FD->getParent());
unsigned FieldIndex = FD->getFieldIndex();
uint64_t FieldOffset =
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/ByteCode/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ struct IntPointer {
const Descriptor *Desc;
uint64_t Value;

IntPointer atOffset(const ASTContext &ASTCtx, unsigned Offset) const;
std::optional<IntPointer> atOffset(const ASTContext &ASTCtx,
unsigned Offset) const;
IntPointer baseCast(const ASTContext &ASTCtx, unsigned BaseOffset) const;
};

Expand Down
12 changes: 12 additions & 0 deletions clang/test/AST/ByteCode/invalid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,15 @@ namespace InvalidBitCast {
struct s myx;
int *myy = ((struct s *)&myx.a)->b;
}

namespace InvalidIntPtrRecord {
typedef __SIZE_TYPE__ Size_t;

#define bufsize ((1LL << (8 * sizeof(Size_t) - 2)) - 256)

struct S {
short buf[bufsize]; // both-error {{array is too large}}
int a;
};
Size_t foo() { return (Size_t)(&((struct S *)0)->a); }
}