Explorer: Fuzzer issue around integer overflow (#2737)

Closes #2732
This commit is contained in:
Poorna Gunathilaka
2023-04-06 16:54:58 -07:00
committed by GitHub
parent 87df7f7c43
commit 0177764a03
5 changed files with 86 additions and 14 deletions
+26 -14
View File
@@ -28,6 +28,7 @@
#include "explorer/interpreter/action_stack.h"
#include "explorer/interpreter/stack.h"
#include "explorer/interpreter/stack_fragment.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
@@ -210,23 +211,34 @@ auto Interpreter::EvalPrim(Operator op, Nonnull<const Value*> /*static_type*/,
-> ErrorOr<Nonnull<const Value*>> {
switch (op) {
case Operator::Neg:
return arena_->New<IntValue>(-cast<IntValue>(*args[0]).value());
case Operator::Add:
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() +
cast<IntValue>(*args[1]).value());
case Operator::Sub:
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() -
cast<IntValue>(*args[1]).value());
case Operator::Mul:
return arena_->New<IntValue>(cast<IntValue>(*args[0]).value() *
cast<IntValue>(*args[1]).value());
case Operator::Div: {
const auto& lhs = cast<IntValue>(*args[0]).value();
const auto& rhs = cast<IntValue>(*args[1]).value();
if (rhs == 0) {
return ProgramError(source_loc) << "division by zero";
case Operator::Div:
case Operator::Mul: {
llvm::APInt op0(64, cast<IntValue>(*args[0]).value());
llvm::APInt result;
if (op == Operator::Neg) {
result = -op0;
} else {
llvm::APInt op1(64, cast<IntValue>(*args[1]).value());
if (op == Operator::Add) {
result = op0 + op1;
} else if (op == Operator::Sub) {
result = op0 - op1;
} else if (op == Operator::Mul) {
result = op0 * op1;
} else if (op == Operator::Div) {
if (op1.getSExtValue() == 0) {
return ProgramError(source_loc) << "division by zero";
}
result = op0.sdiv(op1);
}
}
if (result.isSignedIntN(32)) {
return arena_->New<IntValue>(result.getSExtValue());
} else {
return ProgramError(source_loc) << "integer overflow";
}
return arena_->New<IntValue>(lhs / rhs);
}
case Operator::Mod: {
const auto& lhs = cast<IntValue>(*args[0]).value();