Skip to content

Commit e1bbd5c

Browse files
johnstiles-googleSkia Commit-Bot
authored andcommitted
Disallow unsized array dimensions on size fields past the frontmost.
This was slightly complicated by the fact that this syntax indicates an array with a known size: float[] x = float[](1, 2, 3, 4); Of course, the size is 4; it's just never explicitly stated in the code. (The SkSL parser never actually deduces the size, but it doesn't apparently have a need to; we don't do much in the way of optimization for arrays.) However, this prevents us from simply failing whenever we parse "[]" in non-builtin code; we need to keep scanning and see if the variable is initialized. We already check this in the ArrayConstructors.sksl test file. Change-Id: I5b86958e81bd9bf5edf28a617cecf95c1875583e Bug: skia:10957 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/335240 Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
1 parent 08070f6 commit e1bbd5c

6 files changed

Lines changed: 58 additions & 15 deletions

File tree

gn/sksl_tests.gni

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ sksl_error_tests = [
7373
"$_tests/sksl/errors/ArgumentMismatch.sksl",
7474
"$_tests/sksl/errors/ArgumentModifiers.sksl",
7575
"$_tests/sksl/errors/ArrayTooManyDimensions.sksl",
76+
"$_tests/sksl/errors/ArrayUnspecifiedDimensions.sksl",
7677
"$_tests/sksl/errors/AssignmentTypeMismatch.sksl",
7778
"$_tests/sksl/errors/BadCaps.sksl",
7879
"$_tests/sksl/errors/BadFieldAccess.sksl",

src/sksl/SkSLIRGenerator.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -395,24 +395,26 @@ StatementArray IRGenerator::convertVarDeclarations(const ASTNode& decls,
395395
}
396396
String name(type->name());
397397
int64_t count;
398-
if (size->is<IntLiteral>()) {
399-
count = size->as<IntLiteral>().value();
400-
if (count <= 0) {
401-
fErrors.error(size->fOffset, "array size must be positive");
402-
return {};
403-
}
404-
name += "[" + to_string(count) + "]";
405-
} else {
406-
fErrors.error(size->fOffset, "array size must be specified");
398+
if (!size->is<IntLiteral>()) {
399+
fErrors.error(size->fOffset, "array size must be an integer");
400+
return {};
401+
}
402+
count = size->as<IntLiteral>().value();
403+
if (count <= 0) {
404+
fErrors.error(size->fOffset, "array size must be positive");
407405
return {};
408406
}
407+
name += "[" + to_string(count) + "]";
409408
type = fSymbolTable->takeOwnershipOfSymbol(
410409
std::make_unique<Type>(name, Type::TypeKind::kArray, *type, (int)count));
411410
sizes.push_back(std::move(size));
412-
} else {
411+
} else if (i == 0) {
413412
type = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Type>(
414413
type->name() + "[]", Type::TypeKind::kArray, *type, Type::kUnsizedArray));
415414
sizes.push_back(nullptr);
415+
} else {
416+
fErrors.error(varDecl.fOffset, "array size must be specified");
417+
return {};
416418
}
417419
}
418420
auto var = std::make_unique<Variable>(varDecl.fOffset, fModifiers->addToPool(modifiers),
@@ -423,7 +425,13 @@ StatementArray IRGenerator::convertVarDeclarations(const ASTNode& decls,
423425
fRTAdjust = var.get();
424426
}
425427
std::unique_ptr<Expression> value;
426-
if (iter != varDecl.end()) {
428+
if (iter == varDecl.end()) {
429+
if (varData.fSizeCount > 0 && sizes.front() == nullptr) {
430+
fErrors.error(varDecl.fOffset,
431+
"arrays without an explicit size must use an initializer expression");
432+
return {};
433+
}
434+
} else {
427435
value = this->convertExpression(*iter);
428436
if (!value) {
429437
return {};
@@ -1258,7 +1266,7 @@ void IRGenerator::convertEnum(const ASTNode& e) {
12581266
return;
12591267
}
12601268
}
1261-
value = std::unique_ptr<Expression>(new IntLiteral(fContext, e.fOffset, currentValue));
1269+
value = std::make_unique<IntLiteral>(fContext, e.fOffset, currentValue);
12621270
++currentValue;
12631271
fSymbolTable->add(std::make_unique<Variable>(e.fOffset, fModifiers->addToPool(modifiers),
12641272
child.getString(), type, fIsBuiltinCode,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
in int arr1[][2][3][4][5][6][7][8];
2+
in int arr2[1][][3][4][5][6][7][8];
3+
in int arr3[1][2][][4][5][6][7][8];
4+
in int arr4[1][2][3][][5][6][7][8];
5+
in int arr5[1][2][3][4][][6][7][8];
6+
in int arr6[1][2][3][4][5][][7][8];
7+
in int arr7[1][2][3][4][5][6][][8];
8+
in int arr8[1][2][3][4][5][6][7][];
9+
in int arrEven[1][][3][][5][][7][];
10+
in int arrOdd[][2][][4][][6][][8];
11+
in int arrNone[][][][][][][][];
12+
in int arrFloat[1.];
13+
in int arrBool[true];
14+
in int arrNull[null];
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
buffer broken { float x[]; float y; };
1+
buffer brokenA { float x[]; float y; };
2+
buffer brokenB { float x[] = float[](0); float y; };
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
### Compilation failed:
2+
3+
error: 1: arrays without an explicit size must use an initializer expression
4+
error: 2: array size must be specified
5+
error: 3: array size must be specified
6+
error: 4: array size must be specified
7+
error: 5: array size must be specified
8+
error: 6: array size must be specified
9+
error: 7: array size must be specified
10+
error: 8: array size must be specified
11+
error: 9: array size must be specified
12+
error: 10: array size must be specified
13+
error: 11: array size must be specified
14+
error: 12: expected 'int', but found 'float'
15+
error: 13: expected 'int', but found 'bool'
16+
error: 14: arrays without an explicit size must use an initializer expression
17+
14 errors
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
### Compilation failed:
22

3-
error: 1: only the last entry in an interface block may be a runtime-sized array
4-
1 error
3+
error: 1: arrays without an explicit size must use an initializer expression
4+
error: 2: initializers are not permitted on interface block fields
5+
error: 2: only the last entry in an interface block may be a runtime-sized array
6+
3 errors

0 commit comments

Comments
 (0)