added error check for invalid 'in' variables

Bug: skia:
Change-Id: I0e767f322ad10a0ca4c6209c516b538ff36c9279
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/233986
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2019-08-13 10:21:38 -04:00 committed by Skia Commit-Bot
parent 0bbb3c1111
commit 33c59ed8df
2 changed files with 56 additions and 3 deletions

View File

@ -1181,6 +1181,29 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identi
}
#endif
}
if (fKind == Program::kFragmentProcessor_Kind &&
(var->fModifiers.fFlags & Modifiers::kIn_Flag) &&
!(var->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
!var->fModifiers.fLayout.fKey &&
var->fModifiers.fLayout.fBuiltin == -1 &&
var->fType.nonnullable() != *fContext.fFragmentProcessor_Type &&
var->fType.kind() != Type::kSampler_Kind) {
bool valid = false;
for (const auto& decl : fFile->root()) {
if (decl.fKind == ASTNode::Kind::kSection) {
ASTNode::SectionData section = decl.getSectionData();
if (section.fName == "setData") {
valid = true;
break;
}
}
}
if (!valid) {
fErrors.error(identifier.fOffset, "'in' variable must be either 'uniform' or "
"'layout(key)', or there must be a custom "
"@setData function");
}
}
// default to kRead_RefKind; this will be corrected later if the variable is written to
return std::unique_ptr<VariableReference>(new VariableReference(
identifier.fOffset,

View File

@ -58,6 +58,26 @@ static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& cap
}
}
static void test_failure(skiatest::Reporter* r, const char* src, const char* error) {
SkSL::Compiler compiler;
SkSL::Program::Settings settings;
sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
settings.fCaps = caps.get();
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
SkSL::Program::kFragmentProcessor_Kind,
SkSL::String(src),
settings);
if (!compiler.errorCount()) {
compiler.optimize(*program);
}
SkSL::String skError(error);
if (compiler.errorText() != skError) {
SkDebugf("SKSL ERROR:\n source: %s\n expected: %s received: %s", src, error,
compiler.errorText().c_str());
}
REPORTER_ASSERT(r, compiler.errorText() == skError);
}
DEF_TEST(SkSLFPHelloWorld, r) {
test(r,
"/* HEADER */"
@ -144,7 +164,7 @@ DEF_TEST(SkSLFPHelloWorld, r) {
DEF_TEST(SkSLFPInput, r) {
test(r,
"in half2 point;"
"layout(key) in half2 point;"
"void main() {"
"sk_OutColor = half4(point, point);"
"}",
@ -265,7 +285,7 @@ DEF_TEST(SkSLFPNonInlinedInUniform, r) {
// state tracking and custom ctypes to really put the code generation through its paces.
DEF_TEST(SkSLFPConditionalInUniform, r) {
test(r,
"in bool test;"
"layout(key) in bool test;"
"layout(ctype=SkPMColor4f, tracked, when=test) in uniform half4 color;"
"void main() {"
" if (test) {"
@ -394,7 +414,7 @@ DEF_TEST(SkSLFPSections, r) {
{});
test(r,
"uniform half calculated;"
"in half provided;"
"layout(key) in half provided;"
"@setData(varName) { varName.set1f(calculated, provided * 2); }"
"void main() {"
"sk_OutColor = half4(1);"
@ -655,3 +675,13 @@ DEF_TEST(SkSLFPNullableChildProcessor, r) {
});
}
DEF_TEST(SkSLFPBadIn, r) {
test_failure(r,
"in half4 c;"
"void main() {"
" sk_OutColor = c;"
"}",
"error: 1: 'in' variable must be either 'uniform' or 'layout(key)', or there must be a "
"custom @setData function\n1 error\n");
}