Avoid error cascades when casting out-of-range scalar values.
Previously, when attempting to cast a huge value to an int, SkSL would report an error, then return the IR for `ScalarCast(Int, FloatLiteral(huge-value))` . Now, to minimize the blast radius of the error, we report the error but return `IntLiteral(0)`. We've already reported an error, so there's no need to preserve the value, and zero is less likely to produce follow-up errors. (A similar approach is used here and worked well: https://osscs.corp.google.com/skia/skia/+/main:src/sksl/ir/SkSLConstructorCompoundCast.cpp;l=57-59) Change-Id: Ie8e8d48380cb963466d1f47d123d64e3301cf87c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/499563 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
de7193cd81
commit
4d1a935835
@ -70,12 +70,15 @@ std::unique_ptr<Expression> ConstructorScalarCast::Make(const Context& context,
|
||||
arg = ConstantFolder::MakeConstantValueForVariable(std::move(arg));
|
||||
|
||||
// We can cast scalar literals at compile-time when possible. (If the resulting literal would be
|
||||
// out of range for its type, we report an error and return the constructor. This can occur when
|
||||
// code is inlined, so we can't necessarily catch it during Convert. As such, it's not safe to
|
||||
// return null or assert.)
|
||||
if (arg->is<Literal>() &&
|
||||
!type.checkForOutOfRangeLiteral(context, arg->as<Literal>().value(), arg->fLine)) {
|
||||
return Literal::Make(line, arg->as<Literal>().value(), &type);
|
||||
// out of range for its type, we report an error and return zero to minimize error cascading.
|
||||
// This can occur when code is inlined, so we can't necessarily catch it during Convert. As
|
||||
// such, it's not safe to return null or assert.)
|
||||
if (arg->is<Literal>()) {
|
||||
double value = arg->as<Literal>().value();
|
||||
if (type.checkForOutOfRangeLiteral(context, value, arg->fLine)) {
|
||||
value = 0.0;
|
||||
}
|
||||
return Literal::Make(line, value, &type);
|
||||
}
|
||||
return std::make_unique<ConstructorScalarCast>(line, type, std::move(arg));
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ error: 2: array size must be positive
|
||||
error: 3: array size must be positive
|
||||
error: 4: expected 'int', but found 'float'
|
||||
error: 5: integer is out of range for type 'int': 4000000000
|
||||
error: 5: array size must be an integer
|
||||
error: 5: array size must be positive
|
||||
error: 6: expected 'int', but found 'bool'
|
||||
error: 7: expected 'int', but found 'bool'
|
||||
error: 8: expected 'int', but found 'int2'
|
||||
|
@ -4,7 +4,6 @@ error: 1: unknown identifier 'f'
|
||||
error: 1: expected ')' to complete function arguments, but found '`'
|
||||
error: 1: expected ')' to complete expression, but found '`'
|
||||
error: 1: integer is out of range for type 'int': 3689348940
|
||||
error: 1: integer is out of range for type 'int': 3689348940
|
||||
error: 2: expected ']' to complete array access expression, but found ''
|
||||
error: 2: expected ';', but found ''
|
||||
7 errors
|
||||
6 errors
|
||||
|
@ -1,6 +1,5 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 1: integer is out of range for type 'int': 3976000000
|
||||
error: 1: integer is out of range for type 'int': 3976000000
|
||||
error: 1: array size must be an integer
|
||||
3 errors
|
||||
error: 1: array size must be positive
|
||||
2 errors
|
||||
|
Loading…
Reference in New Issue
Block a user