Revert "Restored unsized array support to SkSL"

This reverts commit 9583759bbd.

Reason for revert: MSAN failure

Original change's description:
> Restored unsized array support to SkSL
>
> This is a prerequisite for compute shaders. As of this CL, there isn't
> yet a way to use unsized arrays, as it is a compute-only feature and
> compute shaders are coming in a followup CL, but this adds the basic
> framework and error tests.
>
> Change-Id: I390c0961e324dd474474563bf9a8f6b34c9552a9
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/538900
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

Change-Id: Id10b48ef24c0e6219b65b0a201d13fea9632620f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/546552
Auto-Submit: Brian Osman <brianosman@google.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
This commit is contained in:
Brian Osman 2022-06-03 15:55:34 +00:00 committed by SkCQ
parent 357958225d
commit 5270322b46
46 changed files with 34 additions and 268 deletions

View File

@ -20,29 +20,13 @@ sksl_error_tests = [
"/sksl/errors/ArraySplitDimensionsInFuncDecl.rts", "/sksl/errors/ArraySplitDimensionsInFuncDecl.rts",
"/sksl/errors/ArraySplitDimensionsInStruct.rts", "/sksl/errors/ArraySplitDimensionsInStruct.rts",
"/sksl/errors/ArrayTooManyDimensions.rts", "/sksl/errors/ArrayTooManyDimensions.rts",
"/sksl/errors/ArrayTooManyDimensionsUnsized1.rts",
"/sksl/errors/ArrayTooManyDimensionsUnsized2.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncBody.rts", "/sksl/errors/ArrayTooManyDimensionsInFuncBody.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncBodyUnsized1.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncBodyUnsized2.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncDecl.rts", "/sksl/errors/ArrayTooManyDimensionsInFuncDecl.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncDeclUnsized1.rts",
"/sksl/errors/ArrayTooManyDimensionsInFuncDeclUnsized2.rts",
"/sksl/errors/ArrayTooManyDimensionsInStruct.rts", "/sksl/errors/ArrayTooManyDimensionsInStruct.rts",
"/sksl/errors/ArrayTooManyDimensionsInStructUnsized1.rts",
"/sksl/errors/ArrayTooManyDimensionsInStructUnsized2.rts",
"/sksl/errors/ArrayTypeTooManyDimensions.rts", "/sksl/errors/ArrayTypeTooManyDimensions.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsUnsized1.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsUnsized2.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncBody.rts", "/sksl/errors/ArrayTypeTooManyDimensionsInFuncBody.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncBodyUnsized1.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncBodyUnsized2.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncDecl.rts", "/sksl/errors/ArrayTypeTooManyDimensionsInFuncDecl.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncDeclUnsized1.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInFuncDeclUnsized2.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInStruct.rts", "/sksl/errors/ArrayTypeTooManyDimensionsInStruct.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInStructUnsized1.rts",
"/sksl/errors/ArrayTypeTooManyDimensionsInStructUnsized2.rts",
"/sksl/errors/ArrayUnspecifiedDimensions.rts", "/sksl/errors/ArrayUnspecifiedDimensions.rts",
"/sksl/errors/AssignmentTypeMismatch.rts", "/sksl/errors/AssignmentTypeMismatch.rts",
"/sksl/errors/BadCaps.sksl", "/sksl/errors/BadCaps.sksl",

View File

@ -181,7 +181,6 @@ private:
friend DSLType Array(const DSLType& base, int count, Position pos); friend DSLType Array(const DSLType& base, int count, Position pos);
friend DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos); friend DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos);
friend DSLType UnsizedArray(const DSLType& base, Position pos);
friend class DSLCore; friend class DSLCore;
friend class DSLFunction; friend class DSLFunction;
friend class DSLVarBase; friend class DSLVarBase;
@ -229,8 +228,6 @@ MATRIX_TYPE(Half)
DSLType Array(const DSLType& base, int count, Position pos = {}); DSLType Array(const DSLType& base, int count, Position pos = {});
DSLType UnsizedArray(const DSLType& base, Position pos = {});
class DSLField { class DSLField {
public: public:
DSLField(const DSLType type, std::string_view name, DSLField(const DSLType type, std::string_view name,

View File

@ -43,7 +43,7 @@ array size out of bounds
array size must be an integer array size must be an integer
array size must be an integer array size must be an integer
array size must be an integer array size must be an integer
unsized arrays are not permitted here expected array dimension
integer is out of range for type 'int': 4000000000 integer is out of range for type 'int': 4000000000
integer is out of range for type 'int': 100000002004087734272 integer is out of range for type 'int': 100000002004087734272
*%%*/ *%%*/

View File

@ -1,5 +0,0 @@
void func() { float x[][2]; }
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func() { float x[2][]; }
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func(float x[][2]) {}
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func(float x[2][]) {}
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
struct S { float x[][2]; };
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
struct S { float x[2][]; };
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
float x[][2];
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
float x[2][];
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func() { float[][2] x; }
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func() { float[2][] x; }
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func(float[][2] x) {}
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
void func(float[2][] x) {}
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
struct S { float[][2] x; };
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
struct S { float[2][] x; };
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
float[][2] x;
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -1,5 +0,0 @@
float[2][] x;
/*%%*
unsized arrays are not permitted here
*%%*/

View File

@ -5,7 +5,7 @@ int arrBool[true];
int unsized_in_expression() { return int[](0)[0]; } int unsized_in_expression() { return int[](0)[0]; }
/*%%* /*%%*
unsized arrays are not permitted here expected array dimension
array size must be an integer array size must be an integer
array size must be an integer array size must be an integer
missing index in '[]' missing index in '[]'

View File

@ -28,7 +28,6 @@
#include "src/sksl/dsl/priv/DSL_priv.h" #include "src/sksl/dsl/priv/DSL_priv.h"
#include "src/sksl/ir/SkSLExpression.h" #include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLProgram.h" #include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLType.h"
#include <algorithm> #include <algorithm>
#include <initializer_list> #include <initializer_list>
@ -462,11 +461,6 @@ bool DSLParser::functionDeclarationEnd(Position start,
} }
bool DSLParser::arraySize(SKSL_INT* outResult) { bool DSLParser::arraySize(SKSL_INT* outResult) {
Token next = this->peek();
if (next.fKind == Token::Kind::TK_RBRACKET) {
this->error(this->position(next), "unsized arrays are not permitted here");
return true;
}
DSLExpression sizeExpr = this->expression(); DSLExpression sizeExpr = this->expression();
if (!sizeExpr.hasValue()) { if (!sizeExpr.hasValue()) {
return false; return false;
@ -498,7 +492,7 @@ bool DSLParser::parseArrayDimensions(Position pos, DSLType* type) {
Token next; Token next;
while (this->checkNext(Token::Kind::TK_LBRACKET, &next)) { while (this->checkNext(Token::Kind::TK_LBRACKET, &next)) {
if (this->checkNext(Token::Kind::TK_RBRACKET)) { if (this->checkNext(Token::Kind::TK_RBRACKET)) {
this->error(this->rangeFrom(pos), "unsized arrays are not permitted here"); this->error(this->rangeFrom(next), "expected array dimension");
} else { } else {
SKSL_INT size; SKSL_INT size;
if (!this->arraySize(&size)) { if (!this->arraySize(&size)) {
@ -973,17 +967,17 @@ DSLType DSLParser::type(DSLModifiers* modifiers) {
return DSLType(nullptr); return DSLType(nullptr);
} }
DSLType result(this->text(type), modifiers, this->position(type)); DSLType result(this->text(type), modifiers, this->position(type));
Token bracket; while (this->checkNext(Token::Kind::TK_LBRACKET)) {
while (this->checkNext(Token::Kind::TK_LBRACKET, &bracket)) { if (this->peek().fKind != Token::Kind::TK_RBRACKET) {
if (this->checkNext(Token::Kind::TK_RBRACKET)) {
this->error(this->rangeFrom(bracket), "unsized arrays are not permitted here");
} else {
SKSL_INT size; SKSL_INT size;
if (!this->arraySize(&size)) { if (!this->arraySize(&size)) {
return DSLType(nullptr); return DSLType(nullptr);
} }
this->expect(Token::Kind::TK_RBRACKET, "']'"); this->expect(Token::Kind::TK_RBRACKET, "']'");
result = Array(result, size, this->rangeFrom(type)); result = Array(result, size, this->rangeFrom(type));
} else {
this->error(this->peek(), "expected array dimension");
this->expect(Token::Kind::TK_RBRACKET, "']'");
} }
} }
return result; return result;
@ -1029,7 +1023,7 @@ bool DSLParser::interfaceBlock(const dsl::DSLModifiers& modifiers) {
} }
actualType = Array(std::move(actualType), size, this->position(typeName)); actualType = Array(std::move(actualType), size, this->position(typeName));
} else { } else {
this->error(sizeToken, "unsized arrays are not permitted here"); this->error(sizeToken, "unsized arrays are not permitted");
} }
this->expect(Token::Kind::TK_RBRACKET, "']'"); this->expect(Token::Kind::TK_RBRACKET, "']'");
} }

View File

@ -275,11 +275,6 @@ DSLType Array(const DSLType& base, int count, Position pos) {
return DSLType(ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(), count), pos); return DSLType(ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(), count), pos);
} }
DSLType UnsizedArray(const DSLType& base, Position pos) {
return ThreadContext::SymbolTable()->addArrayDimension(&base.skslType(),
SkSL::Type::kUnsizedArray);
}
DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos) { DSLType Struct(std::string_view name, SkSpan<DSLField> fields, Position pos) {
std::vector<SkSL::Type::Field> skslFields; std::vector<SkSL::Type::Field> skslFields;
skslFields.reserve(fields.size()); skslFields.reserve(fields.size());

View File

@ -20,13 +20,10 @@ namespace SkSL {
static bool index_out_of_range(const Context& context, Position pos, SKSL_INT index, static bool index_out_of_range(const Context& context, Position pos, SKSL_INT index,
const Expression& base) { const Expression& base) {
if (index >= 0) { if (index >= 0 && index < base.type().columns()) {
if (base.type().columns() == Type::kUnsizedArray) { return false;
return false;
} else if (index < base.type().columns()) {
return false;
}
} }
context.fErrors->error(pos, "index " + std::to_string(index) + " out of range for '" + context.fErrors->error(pos, "index " + std::to_string(index) + " out of range for '" +
base.type().displayName() + "'"); base.type().displayName() + "'");
return true; return true;

View File

@ -126,7 +126,8 @@ public:
: INHERITED(name, abbrev, kTypeKind) : INHERITED(name, abbrev, kTypeKind)
, fComponentType(componentType) , fComponentType(componentType)
, fCount(count) { , fCount(count) {
SkASSERT(count > 0 || count == kUnsizedArray); // Only allow explicitly-sized arrays.
SkASSERT(count > 0);
// Disallow multi-dimensional arrays. // Disallow multi-dimensional arrays.
SkASSERT(!componentType.is<ArrayType>()); SkASSERT(!componentType.is<ArrayType>());
} }
@ -156,7 +157,6 @@ public:
} }
size_t slotCount() const override { size_t slotCount() const override {
SkASSERT(fCount != kUnsizedArray);
SkASSERT(fCount > 0); SkASSERT(fCount > 0);
return fCount * fComponentType.slotCount(); return fCount * fComponentType.slotCount();
} }
@ -522,9 +522,6 @@ private:
std::string Type::getArrayName(int arraySize) const { std::string Type::getArrayName(int arraySize) const {
std::string_view name = this->name(); std::string_view name = this->name();
if (arraySize == kUnsizedArray) {
return String::printf("%.*s[]", (int)name.size(), name.data());
}
return String::printf("%.*s[%d]", (int)name.size(), name.data(), arraySize); return String::printf("%.*s[%d]", (int)name.size(), name.data(), arraySize);
} }
@ -968,30 +965,23 @@ bool Type::checkForOutOfRangeLiteral(const Context& context, double value, Posit
return false; return false;
} }
bool Type::checkIfUsableInArray(const Context& context, Position arrayPos) const {
if (this->isArray()) {
context.fErrors->error(arrayPos, "multi-dimensional arrays are not supported");
return false;
}
if (this->isVoid()) {
context.fErrors->error(arrayPos, "type 'void' may not be used in an array");
return false;
}
if (this->isOpaque()) {
context.fErrors->error(arrayPos, "opaque type '" + std::string(this->name()) +
"' may not be used in an array");
return false;
}
return true;
}
SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos, SKSL_INT Type::convertArraySize(const Context& context, Position arrayPos,
std::unique_ptr<Expression> size) const { std::unique_ptr<Expression> size) const {
size = context.fTypes.fInt->coerceExpression(std::move(size), context); size = context.fTypes.fInt->coerceExpression(std::move(size), context);
if (!size) { if (!size) {
return 0; return 0;
} }
if (!this->checkIfUsableInArray(context, arrayPos)) { if (this->isArray()) {
context.fErrors->error(arrayPos, "multi-dimensional arrays are not supported");
return 0;
}
if (this->isVoid()) {
context.fErrors->error(arrayPos, "type 'void' may not be used in an array");
return 0;
}
if (this->isOpaque()) {
context.fErrors->error(arrayPos, "opaque type '" + std::string(this->name()) +
"' may not be used in an array");
return 0; return 0;
} }
SKSL_INT count; SKSL_INT count;

View File

@ -58,8 +58,7 @@ class Type : public Symbol {
public: public:
inline static constexpr Kind kSymbolKind = Kind::kType; inline static constexpr Kind kSymbolKind = Kind::kType;
inline static constexpr int kMaxAbbrevLength = 3; inline static constexpr int kMaxAbbrevLength = 3;
// Represents unspecified array dimensions, as in `int[]`.
inline static constexpr int kUnsizedArray = -1;
struct Field { struct Field {
Field(Position pos, Modifiers modifiers, std::string_view name, const Type* type) Field(Position pos, Modifiers modifiers, std::string_view name, const Type* type)
: fPosition(pos) : fPosition(pos)
@ -107,7 +106,7 @@ public:
Type(const Type& other) = delete; Type(const Type& other) = delete;
/** Creates an array type. `columns` may be kUnsizedArray. */ /** Creates an array type. */
static std::unique_ptr<Type> MakeArrayType(std::string_view name, const Type& componentType, static std::unique_ptr<Type> MakeArrayType(std::string_view name, const Type& componentType,
int columns); int columns);
@ -527,14 +526,9 @@ public:
/** Checks if `value` can fit in this type. The type must be scalar. */ /** Checks if `value` can fit in this type. The type must be scalar. */
bool checkForOutOfRangeLiteral(const Context& context, double value, Position pos) const; bool checkForOutOfRangeLiteral(const Context& context, double value, Position pos) const;
/**
* Reports errors and returns false if this type cannot be used as the base type for an array.
*/
bool checkIfUsableInArray(const Context& context, Position arrayPos) const;
/** /**
* Verifies that the expression is a valid constant array size for this type. Returns the array * Verifies that the expression is a valid constant array size for this type. Returns the array
* size, or reports errors and returns zero if the expression isn't a valid literal value. * size, or zero if the expression isn't a valid literal value.
*/ */
SKSL_INT convertArraySize(const Context& context, Position arrayPos, SKSL_INT convertArraySize(const Context& context, Position arrayPos,
std::unique_ptr<Expression> size) const; std::unique_ptr<Expression> size) const;

View File

@ -42,9 +42,6 @@ std::unique_ptr<Variable> Variable::Convert(const Context& context, Position pos
if (!context.fConfig->fIsBuiltinCode && skstd::starts_with(name, '$')) { if (!context.fConfig->fIsBuiltinCode && skstd::starts_with(name, '$')) {
context.fErrors->error(namePos, "name '" + std::string(name) + "' is reserved"); context.fErrors->error(namePos, "name '" + std::string(name) + "' is reserved");
} }
if (baseType->isArray() && baseType->columns() == Type::kUnsizedArray) {
context.fErrors->error(pos, "unsized arrays are not permitted here");
}
return Make(context, pos, modifiersPos, modifiers, baseType, name, isArray, return Make(context, pos, modifiersPos, modifiers, baseType, name, isArray,
std::move(arraySize), storage); std::move(arraySize), storage);

View File

@ -60,9 +60,9 @@ void g2() { float x[false]; }
error: 20: array size must be an integer error: 20: array size must be an integer
void h2() { float x[int2(2, 2)]; } void h2() { float x[int2(2, 2)]; }
^^^^^^^^^^ ^^^^^^^^^^
error: 21: unsized arrays are not permitted here error: 21: expected array dimension
void i2() { float x[]; } void i2() { float x[]; }
^^^^^^^^^ ^^
error: 22: integer is out of range for type 'int': 4000000000 error: 22: integer is out of range for type 'int': 4000000000
void j2() { float x[int3(4000000000)]; } void j2() { float x[int3(4000000000)]; }
^^^^^^^^^^ ^^^^^^^^^^

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func() { float x[][2]; }
^^^^^^^^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func() { float x[2][]; }
^^^^^^^^^^^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func(float x[][2]) {}
^^^^^^^^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func(float x[2][]) {}
^^^^^^^^^^^^
1 error

View File

@ -1,9 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
struct S { float x[][2]; };
^
error: 1: multi-dimensional arrays are not supported
struct S { float x[][2]; };
^^^^^^^^^^^^
2 errors

View File

@ -1,9 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
struct S { float x[2][]; };
^
error: 1: multi-dimensional arrays are not supported
struct S { float x[2][]; };
^^^^^^^^^^^^
2 errors

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
float x[][2];
^^^^^^^^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
float x[2][];
^^^^^^^^^^^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func() { float[][2] x; }
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func() { float[2][] x; }
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func(float[][2] x) {}
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
void func(float[2][] x) {}
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
struct S { float[][2] x; };
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
struct S { float[2][] x; };
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
float[][2] x;
^^
1 error

View File

@ -1,6 +0,0 @@
### Compilation failed:
error: 1: unsized arrays are not permitted here
float[2][] x;
^^
1 error

View File

@ -1,8 +1,8 @@
### Compilation failed: ### Compilation failed:
error: 1: unsized arrays are not permitted here error: 1: expected array dimension
int arrUnsized[]; int arrUnsized[];
^^^^^^^^^^^^^^^^ ^^
error: 2: array size must be an integer error: 2: array size must be an integer
int arrFloat[1.]; int arrFloat[1.];
^^ ^^

View File

@ -1,6 +1,6 @@
### Compilation failed: ### Compilation failed:
error: 1: unsized arrays are not permitted here error: 1: expected expression, but found ']'
T { int x; } f[]; T { int x; } f[];
^ ^
1 error 1 error

View File

@ -1,6 +1,6 @@
### Compilation failed: ### Compilation failed:
error: 1: unsized arrays are not permitted here error: 1: expected expression, but found ']'
k{int z;}m[];void main(){} k{int z;}m[];void main(){}
^ ^
1 error 1 error