diff options
-rw-r--r-- | src/sksl/SkSLIRGenerator.cpp | 13 | ||||
-rw-r--r-- | src/sksl/ir/SkSLSymbol.h | 2 | ||||
-rw-r--r-- | src/sksl/ir/SkSLVariable.h | 10 | ||||
-rw-r--r-- | src/sksl/ir/SkSLVariableReference.h | 3 | ||||
-rw-r--r-- | tests/SkSLErrorTest.cpp | 8 | ||||
-rw-r--r-- | tests/SkSLSPIRVTest.cpp | 6 |
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"); } |