From: Filipe Cabecinhas Date: Wed, 22 Apr 2015 09:06:21 +0000 (+0000) Subject: Have more strict type checks when creating BinOp nodes in BitcodeReader X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e16cac587a3ad788fd3d87601ba824202b1a3803;p=llvm Have more strict type checks when creating BinOp nodes in BitcodeReader Summary: Bug found with AFL. Reviewers: rafael, bkramer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9015 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235489 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 77d4c6261fb..a16be24a5b5 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -607,27 +607,42 @@ static int GetDecodedCastOpcode(unsigned Val) { case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast; } } + static int GetDecodedBinaryOpcode(unsigned Val, Type *Ty) { + bool IsFP = Ty->isFPOrFPVectorTy(); + // BinOps are only valid for int/fp or vector of int/fp types + if (!IsFP && !Ty->isIntOrIntVectorTy()) + return -1; + switch (Val) { - default: return -1; + default: + return -1; case bitc::BINOP_ADD: - return Ty->isFPOrFPVectorTy() ? Instruction::FAdd : Instruction::Add; + return IsFP ? Instruction::FAdd : Instruction::Add; case bitc::BINOP_SUB: - return Ty->isFPOrFPVectorTy() ? Instruction::FSub : Instruction::Sub; + return IsFP ? Instruction::FSub : Instruction::Sub; case bitc::BINOP_MUL: - return Ty->isFPOrFPVectorTy() ? Instruction::FMul : Instruction::Mul; - case bitc::BINOP_UDIV: return Instruction::UDiv; + return IsFP ? Instruction::FMul : Instruction::Mul; + case bitc::BINOP_UDIV: + return IsFP ? -1 : Instruction::UDiv; case bitc::BINOP_SDIV: - return Ty->isFPOrFPVectorTy() ? Instruction::FDiv : Instruction::SDiv; - case bitc::BINOP_UREM: return Instruction::URem; + return IsFP ? Instruction::FDiv : Instruction::SDiv; + case bitc::BINOP_UREM: + return IsFP ? -1 : Instruction::URem; case bitc::BINOP_SREM: - return Ty->isFPOrFPVectorTy() ? Instruction::FRem : Instruction::SRem; - case bitc::BINOP_SHL: return Instruction::Shl; - case bitc::BINOP_LSHR: return Instruction::LShr; - case bitc::BINOP_ASHR: return Instruction::AShr; - case bitc::BINOP_AND: return Instruction::And; - case bitc::BINOP_OR: return Instruction::Or; - case bitc::BINOP_XOR: return Instruction::Xor; + return IsFP ? Instruction::FRem : Instruction::SRem; + case bitc::BINOP_SHL: + return IsFP ? -1 : Instruction::Shl; + case bitc::BINOP_LSHR: + return IsFP ? -1 : Instruction::LShr; + case bitc::BINOP_ASHR: + return IsFP ? -1 : Instruction::AShr; + case bitc::BINOP_AND: + return IsFP ? -1 : Instruction::And; + case bitc::BINOP_OR: + return IsFP ? -1 : Instruction::Or; + case bitc::BINOP_XOR: + return IsFP ? -1 : Instruction::Xor; } } diff --git a/test/Bitcode/Inputs/invalid-fp-shift.bc b/test/Bitcode/Inputs/invalid-fp-shift.bc new file mode 100644 index 00000000000..aeba1bff968 Binary files /dev/null and b/test/Bitcode/Inputs/invalid-fp-shift.bc differ diff --git a/test/Bitcode/invalid.test b/test/Bitcode/invalid.test index 5c6e280024c..5431368a0ad 100644 --- a/test/Bitcode/invalid.test +++ b/test/Bitcode/invalid.test @@ -61,3 +61,8 @@ RUN: not llvm-dis -disable-output %p/Inputs/invalid-no-proper-module.bc 2>&1 | \ RUN: FileCheck --check-prefix=NO-MODULE %s NO-MODULE: Malformed IR file + +RUN: not llvm-dis -disable-output %p/Inputs/invalid-fp-shift.bc 2>&1 | \ +RUN: FileCheck --check-prefix=FP-SHIFT %s + +FP-SHIFT: Invalid record