aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/sksl/SkSLIRGenerator.cpp13
-rw-r--r--src/sksl/ir/SkSLSymbol.h2
-rw-r--r--src/sksl/ir/SkSLVariable.h10
-rw-r--r--src/sksl/ir/SkSLVariableReference.h3
-rw-r--r--tests/SkSLErrorTest.cpp8
-rw-r--r--tests/SkSLSPIRVTest.cpp6
6 files changed, 35 insertions, 7 deletions
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 719dca9416..38c45f70ee 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -286,6 +286,9 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVa
return nullptr;
}
value = this->coerce(std::move(value), *type);
+ if (!value) {
+ return nullptr;
+ }
var->fWriteCount = 1;
var->fInitialValue = value.get();
}
@@ -761,7 +764,8 @@ void IRGenerator::convertFunction(const ASTFunction& f) {
std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInterfaceBlock& intf) {
std::shared_ptr<SymbolTable> old = fSymbolTable;
- AutoSymbolTable table(this);
+ this->pushSymbolTable();
+ std::shared_ptr<SymbolTable> symbols = fSymbolTable;
std::vector<Type::Field> fields;
bool haveRuntimeArray = false;
bool foundRTAdjust = false;
@@ -804,6 +808,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
}
}
}
+ this->popSymbolTable();
Type* type = new Type(intf.fOffset, intf.fTypeName, fields);
old->takeOwnership(type);
std::vector<std::unique_ptr<Expression>> sizes;
@@ -826,11 +831,11 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
name += "[]";
}
type = new Type(name, Type::kArray_Kind, *type, (int) count);
- fSymbolTable->takeOwnership((Type*) type);
+ symbols->takeOwnership((Type*) type);
sizes.push_back(std::move(converted));
} else {
type = new Type(type->name() + "[]", Type::kArray_Kind, *type, -1);
- fSymbolTable->takeOwnership((Type*) type);
+ symbols->takeOwnership((Type*) type);
sizes.push_back(nullptr);
}
}
@@ -858,7 +863,7 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
intf.fTypeName,
intf.fInstanceName,
std::move(sizes),
- fSymbolTable));
+ symbols));
}
void IRGenerator::getConstantInt(const Expression& value, int64_t* out) {
diff --git a/src/sksl/ir/SkSLSymbol.h b/src/sksl/ir/SkSLSymbol.h
index 4ec8f156cc..43fb742d4f 100644
--- a/src/sksl/ir/SkSLSymbol.h
+++ b/src/sksl/ir/SkSLSymbol.h
@@ -29,6 +29,8 @@ struct Symbol : public IRNode {
, fKind(kind)
, fName(name) {}
+ virtual ~Symbol() {}
+
Kind fKind;
StringFragment fName;
diff --git a/src/sksl/ir/SkSLVariable.h b/src/sksl/ir/SkSLVariable.h
index f16bf4b515..b7cef10535 100644
--- a/src/sksl/ir/SkSLVariable.h
+++ b/src/sksl/ir/SkSLVariable.h
@@ -37,7 +37,15 @@ struct Variable : public Symbol {
, fStorage(storage)
, fInitialValue(initialValue)
, fReadCount(0)
- , fWriteCount(0) {}
+ , fWriteCount(initialValue ? 1 : 0) {}
+
+ ~Variable() override {
+ // can't destroy a variable while there are remaining references to it
+ if (fInitialValue) {
+ --fWriteCount;
+ }
+ ASSERT(!fReadCount && !fWriteCount);
+ }
virtual String description() const override {
return fModifiers.description() + fType.fName + " " + fName;
diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h
index ad54d43515..e1f19ac742 100644
--- a/src/sksl/ir/SkSLVariableReference.h
+++ b/src/sksl/ir/SkSLVariableReference.h
@@ -45,6 +45,9 @@ struct VariableReference : public Expression {
}
~VariableReference() override {
+ if (fRefKind != kRead_RefKind) {
+ fVariable.fWriteCount--;
+ }
if (fRefKind != kWrite_RefKind) {
fVariable.fReadCount--;
}
diff --git a/tests/SkSLErrorTest.cpp b/tests/SkSLErrorTest.cpp
index 575fd74917..b8de004051 100644
--- a/tests/SkSLErrorTest.cpp
+++ b/tests/SkSLErrorTest.cpp
@@ -489,4 +489,12 @@ DEF_TEST(SkSLStaticSwitch, r) {
"error: 1: static switch contains non-static conditional break\n1 error\n");
}
+DEF_TEST(SkSLInterfaceBlockScope, r) {
+ test_failure(r,
+ "uniform testBlock {"
+ "float x;"
+ "} test[x];",
+ "error: 1: unknown identifier 'x'\n1 error\n");
+}
+
#endif
diff --git a/tests/SkSLSPIRVTest.cpp b/tests/SkSLSPIRVTest.cpp
index ba4697d191..f688d50baa 100644
--- a/tests/SkSLSPIRVTest.cpp
+++ b/tests/SkSLSPIRVTest.cpp
@@ -32,10 +32,12 @@ static void test_failure(skiatest::Reporter* r, const char* src, const char* err
DEF_TEST(SkSLBadOffset, r) {
test_failure(r,
- "struct Bad { layout (offset = 5) int x; } bad; void main() { bad.x = 5; }",
+ "struct Bad { layout (offset = 5) int x; } bad; void main() { bad.x = 5; "
+ "sk_FragColor.r = float(bad.x); }",
"error: 1: offset of field 'x' must be a multiple of 4\n1 error\n");
test_failure(r,
- "struct Bad { int x; layout (offset = 0) int y; } bad; void main() { bad.x = 5; }",
+ "struct Bad { int x; layout (offset = 0) int y; } bad; void main() { bad.x = 5; "
+ "sk_FragColor.r = float(bad.x); }",
"error: 1: offset of field 'y' must be at least 4\n1 error\n");
}