Skip to content

Commit bd95a74

Browse files
authored
[clang][bytecode] Check for invalid record decls in IntPointer::atOffset (#169786)
We can't access the RecordLayout of an invalid decl, so return failure if that happens. Fixes #167076
1 parent d6be9fc commit bd95a74

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,8 +1435,12 @@ static bool getField(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
14351435
return false;
14361436

14371437
if (Ptr.isIntegralPointer()) {
1438-
S.Stk.push<Pointer>(Ptr.asIntPointer().atOffset(S.getASTContext(), Off));
1439-
return true;
1438+
if (std::optional<IntPointer> IntPtr =
1439+
Ptr.asIntPointer().atOffset(S.getASTContext(), Off)) {
1440+
S.Stk.push<Pointer>(std::move(*IntPtr));
1441+
return true;
1442+
}
1443+
return false;
14401444
}
14411445

14421446
if (!Ptr.isBlockPointer()) {

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
895895
return Result;
896896
}
897897

898-
IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
899-
unsigned Offset) const {
898+
std::optional<IntPointer> IntPointer::atOffset(const ASTContext &ASTCtx,
899+
unsigned Offset) const {
900900
if (!this->Desc)
901901
return *this;
902902
const Record *R = this->Desc->ElemRecord;
@@ -914,6 +914,9 @@ IntPointer IntPointer::atOffset(const ASTContext &ASTCtx,
914914
return *this;
915915

916916
const FieldDecl *FD = F->Decl;
917+
if (FD->getParent()->isInvalidDecl())
918+
return std::nullopt;
919+
917920
const ASTRecordLayout &Layout = ASTCtx.getASTRecordLayout(FD->getParent());
918921
unsigned FieldIndex = FD->getFieldIndex();
919922
uint64_t FieldOffset =

clang/lib/AST/ByteCode/Pointer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ struct IntPointer {
4747
const Descriptor *Desc;
4848
uint64_t Value;
4949

50-
IntPointer atOffset(const ASTContext &ASTCtx, unsigned Offset) const;
50+
std::optional<IntPointer> atOffset(const ASTContext &ASTCtx,
51+
unsigned Offset) const;
5152
IntPointer baseCast(const ASTContext &ASTCtx, unsigned BaseOffset) const;
5253
};
5354

clang/test/AST/ByteCode/invalid.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,15 @@ namespace InvalidBitCast {
111111
struct s myx;
112112
int *myy = ((struct s *)&myx.a)->b;
113113
}
114+
115+
namespace InvalidIntPtrRecord {
116+
typedef __SIZE_TYPE__ Size_t;
117+
118+
#define bufsize ((1LL << (8 * sizeof(Size_t) - 2)) - 256)
119+
120+
struct S {
121+
short buf[bufsize]; // both-error {{array is too large}}
122+
int a;
123+
};
124+
Size_t foo() { return (Size_t)(&((struct S *)0)->a); }
125+
}

0 commit comments

Comments
 (0)