tint: fix const eval of divide to emit errors on dbz and min/-1
Bug: tint:1581 Change-Id: I0459a7feb1be17f3570b68b54f1a0e0a1723880b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/112180 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
This commit is contained in:
parent
ec7a1d2a1b
commit
775dfbf7a8
|
@ -779,24 +779,22 @@ utils::Result<NumberT> ConstEval::Div(const Source& source, NumberT a, NumberT b
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
using T = UnwrapNumber<NumberT>;
|
using T = UnwrapNumber<NumberT>;
|
||||||
auto divide_values = [](T lhs, T rhs) {
|
auto lhs = a.value;
|
||||||
if constexpr (std::is_integral_v<T>) {
|
auto rhs = b.value;
|
||||||
// For integers, lhs / 0 returns lhs
|
if (rhs == 0) {
|
||||||
if (rhs == 0) {
|
// For integers (as for floats), lhs / 0 is an error
|
||||||
return lhs;
|
AddError(OverflowErrorMessage(a, "/", b), source);
|
||||||
}
|
return utils::Failure;
|
||||||
|
}
|
||||||
if constexpr (std::is_signed_v<T>) {
|
if constexpr (std::is_signed_v<T>) {
|
||||||
// For signed integers, for lhs / -1, return lhs if lhs is the
|
// For signed integers, lhs / -1 where lhs is the
|
||||||
// most negative value
|
// most negative value is an error
|
||||||
if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
|
if (rhs == -1 && lhs == std::numeric_limits<T>::min()) {
|
||||||
return lhs;
|
AddError(OverflowErrorMessage(a, "/", b), source);
|
||||||
}
|
return utils::Failure;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return lhs / rhs;
|
}
|
||||||
};
|
result = lhs / rhs;
|
||||||
result = divide_values(a.value, b.value);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,36 +419,31 @@ INSTANTIATE_TEST_SUITE_P(Mul,
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::vector<Case> OpDivIntCases() {
|
std::vector<Case> OpDivIntCases() {
|
||||||
std::vector<Case> r = {
|
|
||||||
C(Val(T{0}), Val(T{1}), Val(T{0})),
|
|
||||||
C(Val(T{1}), Val(T{1}), Val(T{1})),
|
|
||||||
C(Val(T{1}), Val(T{1}), Val(T{1})),
|
|
||||||
C(Val(T{2}), Val(T{1}), Val(T{2})),
|
|
||||||
C(Val(T{4}), Val(T{2}), Val(T{2})),
|
|
||||||
C(Val(T::Highest()), Val(T{1}), Val(T::Highest())),
|
|
||||||
C(Val(T::Lowest()), Val(T{1}), Val(T::Lowest())),
|
|
||||||
C(Val(T::Highest()), Val(T::Highest()), Val(T{1})),
|
|
||||||
C(Val(T{0}), Val(T::Highest()), Val(T{0})),
|
|
||||||
C(Val(T{0}), Val(T::Lowest()), Val(T{0})),
|
|
||||||
};
|
|
||||||
ConcatIntoIf<!IsAbstract<T> && IsIntegral<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
// e1, when e2 is zero.
|
|
||||||
C(T{123}, T{0}, T{123}),
|
|
||||||
});
|
|
||||||
ConcatIntoIf<!IsAbstract<T> && IsSignedIntegral<T>>( //
|
|
||||||
r, std::vector<Case>{
|
|
||||||
// e1, when e1 is the most negative value in T, and e2 is -1.
|
|
||||||
C(T::Smallest(), T{-1}, T::Smallest()),
|
|
||||||
});
|
|
||||||
|
|
||||||
auto error_msg = [](auto a, auto b) {
|
auto error_msg = [](auto a, auto b) {
|
||||||
return "12:34 error: " + OverflowErrorMessage(a, "/", b);
|
return "12:34 error: " + OverflowErrorMessage(a, "/", b);
|
||||||
};
|
};
|
||||||
ConcatIntoIf<IsAbstract<T>>( //
|
|
||||||
|
std::vector<Case> r = {
|
||||||
|
C(T{0}, T{1}, T{0}),
|
||||||
|
C(T{1}, T{1}, T{1}),
|
||||||
|
C(T{1}, T{1}, T{1}),
|
||||||
|
C(T{2}, T{1}, T{2}),
|
||||||
|
C(T{4}, T{2}, T{2}),
|
||||||
|
C(T::Highest(), T{1}, T::Highest()),
|
||||||
|
C(T::Lowest(), T{1}, T::Lowest()),
|
||||||
|
C(T::Highest(), T::Highest(), T{1}),
|
||||||
|
C(T{0}, T::Highest(), T{0}),
|
||||||
|
|
||||||
|
// Divide by zero
|
||||||
|
E(T{123}, T{0}, error_msg(T{123}, T{0})),
|
||||||
|
E(T::Highest(), T{0}, error_msg(T::Highest(), T{0})),
|
||||||
|
E(T::Lowest(), T{0}, error_msg(T::Lowest(), T{0})),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error on most negative divided by -1
|
||||||
|
ConcatIntoIf<IsSignedIntegral<T>>( //
|
||||||
r, std::vector<Case>{
|
r, std::vector<Case>{
|
||||||
// Most negative value divided by -1
|
E(T::Lowest(), T{-1}, error_msg(T::Lowest(), T{-1})),
|
||||||
E(AInt::Lowest(), -1_a, error_msg(AInt::Lowest(), -1_a)),
|
|
||||||
});
|
});
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue