Skip to content

Commit 01806dc

Browse files
committed
[llvm::transforms] Add overflow check in AllocaInst::getAllocationSize
1 parent cd0f891 commit 01806dc

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

llvm/lib/IR/Instructions.cpp

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/IR/Value.h"
3838
#include "llvm/Support/AtomicOrdering.h"
3939
#include "llvm/Support/Casting.h"
40+
#include "llvm/Support/CheckedArithmetic.h"
4041
#include "llvm/Support/ErrorHandling.h"
4142
#include "llvm/Support/MathExtras.h"
4243
#include "llvm/Support/ModRef.h"
@@ -60,22 +61,33 @@ static cl::opt<bool> DisableI2pP2iOpt(
6061
std::optional<TypeSize>
6162
AllocaInst::getAllocationSize(const DataLayout &DL) const {
6263
TypeSize Size = DL.getTypeAllocSize(getAllocatedType());
63-
if (isArrayAllocation()) {
64-
auto *C = dyn_cast<ConstantInt>(getArraySize());
65-
if (!C)
66-
return std::nullopt;
67-
assert(!Size.isScalable() && "Array elements cannot have a scalable size");
68-
Size *= C->getZExtValue();
64+
if (!isArrayAllocation()) {
65+
return Size;
6966
}
70-
return Size;
67+
auto *C = dyn_cast<ConstantInt>(getArraySize());
68+
if (!C)
69+
return std::nullopt;
70+
assert(!Size.isScalable() && "Array elements cannot have a scalable size");
71+
auto checkedProd =
72+
checkedMulUnsigned(Size.getKnownMinValue(), C->getZExtValue());
73+
if (!checkedProd) {
74+
return std::nullopt;
75+
}
76+
return TypeSize::getFixed(*checkedProd);
7177
}
7278

7379
std::optional<TypeSize>
7480
AllocaInst::getAllocationSizeInBits(const DataLayout &DL) const {
7581
std::optional<TypeSize> Size = getAllocationSize(DL);
76-
if (Size)
77-
return *Size * 8;
78-
return std::nullopt;
82+
if (!Size) {
83+
return std::nullopt;
84+
}
85+
auto CheckedProd = checkedMulUnsigned((*Size).getKnownMinValue(),
86+
static_cast<TypeSize::ScalarTy>(8));
87+
if (!CheckedProd) {
88+
return std::nullopt;
89+
}
90+
return TypeSize::get(*CheckedProd, (*Size).isScalable());
7991
}
8092

8193
//===----------------------------------------------------------------------===//

llvm/unittests/IR/InstructionsTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,6 +1750,7 @@ TEST(InstructionsTest, AllocaInst) {
17501750
%F = alloca [2 x half]
17511751
%G = alloca [2 x [3 x i128]]
17521752
%H = alloca %T
1753+
%I = alloca i32, i64 9223372036854775807
17531754
ret void
17541755
}
17551756
)");
@@ -1766,6 +1767,7 @@ TEST(InstructionsTest, AllocaInst) {
17661767
AllocaInst &F = cast<AllocaInst>(*It++);
17671768
AllocaInst &G = cast<AllocaInst>(*It++);
17681769
AllocaInst &H = cast<AllocaInst>(*It++);
1770+
AllocaInst &I = cast<AllocaInst>(*It++);
17691771
EXPECT_EQ(A.getAllocationSizeInBits(DL), TypeSize::getFixed(32));
17701772
EXPECT_EQ(B.getAllocationSizeInBits(DL), TypeSize::getFixed(128));
17711773
EXPECT_FALSE(C.getAllocationSizeInBits(DL));
@@ -1774,6 +1776,7 @@ TEST(InstructionsTest, AllocaInst) {
17741776
EXPECT_EQ(F.getAllocationSizeInBits(DL), TypeSize::getFixed(32));
17751777
EXPECT_EQ(G.getAllocationSizeInBits(DL), TypeSize::getFixed(768));
17761778
EXPECT_EQ(H.getAllocationSizeInBits(DL), TypeSize::getFixed(160));
1779+
EXPECT_FALSE(I.getAllocationSizeInBits(DL));
17771780
}
17781781

17791782
TEST(InstructionsTest, InsertAtBegin) {

0 commit comments

Comments
 (0)