forked from OSchip/llvm-project
Harden IR and bitcode parsers against infinite size types.
If isSized is passed a SmallPtrSet, it uses that set to catch infinitely recursive types (for example, a struct that has itself as a member). Otherwise, it just crashes on such types.
This commit is contained in:
parent
accd9af838
commit
0ec5f50196
|
@ -7057,7 +7057,8 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
|
|||
if (Ty != cast<PointerType>(Val->getType())->getElementType())
|
||||
return Error(ExplicitTypeLoc,
|
||||
"explicit pointee type doesn't match operand's pointee type");
|
||||
if (!Alignment && !Ty->isSized())
|
||||
SmallPtrSet<Type *, 4> Visited;
|
||||
if (!Alignment && !Ty->isSized(&Visited))
|
||||
return Error(ExplicitTypeLoc, "loading unsized types is not allowed");
|
||||
if (!Alignment)
|
||||
Alignment = M->getDataLayout().getABITypeAlign(Ty);
|
||||
|
@ -7107,7 +7108,8 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) {
|
|||
if (Ordering == AtomicOrdering::Acquire ||
|
||||
Ordering == AtomicOrdering::AcquireRelease)
|
||||
return Error(Loc, "atomic store cannot use Acquire ordering");
|
||||
if (!Alignment && !Val->getType()->isSized())
|
||||
SmallPtrSet<Type *, 4> Visited;
|
||||
if (!Alignment && !Val->getType()->isSized(&Visited))
|
||||
return Error(Loc, "storing unsized types is not allowed");
|
||||
if (!Alignment)
|
||||
Alignment = M->getDataLayout().getABITypeAlign(Val->getType());
|
||||
|
|
|
@ -4857,7 +4857,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||
MaybeAlign Align;
|
||||
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
|
||||
return Err;
|
||||
if (!Align && !Ty->isSized())
|
||||
SmallPtrSet<Type *, 4> Visited;
|
||||
if (!Align && !Ty->isSized(&Visited))
|
||||
return error("load of unsized type");
|
||||
if (!Align)
|
||||
Align = TheModule->getDataLayout().getABITypeAlign(Ty);
|
||||
|
@ -4922,6 +4923,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
|
|||
MaybeAlign Align;
|
||||
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
|
||||
return Err;
|
||||
SmallPtrSet<Type *, 4> Visited;
|
||||
if (!Align && !Val->getType()->isSized(&Visited))
|
||||
return error("store of unsized type");
|
||||
if (!Align)
|
||||
Align = TheModule->getDataLayout().getABITypeAlign(Val->getType());
|
||||
I = new StoreInst(Val, Ptr, Record[OpNum + 1], *Align);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
|
||||
|
||||
define i32 @f(%rt2* %p) nounwind {
|
||||
entry:
|
||||
; Check that recursive types trigger an error instead of segfaulting, when
|
||||
; the recursion isn't through a pointer to the type.
|
||||
; CHECK: loading unsized types is not allowed
|
||||
%0 = load %rt2, %rt2* %p
|
||||
ret i32 %0
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
|
||||
|
||||
%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
|
||||
|
||||
define void @f(%rt2 %r, %rt2 *%p) nounwind {
|
||||
entry:
|
||||
; Check that recursive types trigger an error instead of segfaulting, when
|
||||
; the recursion isn't through a pointer to the type.
|
||||
; CHECK: storing unsized types is not allowed
|
||||
store %rt2 %r, %rt2 *%p
|
||||
ret void
|
||||
}
|
Loading…
Reference in New Issue