Skip to content

Commit 48bdf6d

Browse files
johnstiles-googleSkia Commit-Bot
authored andcommitted
Use a scoped block for inlined return statements.
Inlined return statements emit two statements--an assignment, then a break. If scope braces are otherwise missing, the break statement will end up in the wrong place. i.e.: Mistranslated: if (foo) return bar; --> if (foo) out = bar; break; Translated properly: if (foo) return bar; --> if (foo) { out = bar; break; } Change-Id: Id992abf64ad09e6752f64c71cb556f05c868a453 Bug: skia:10607 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/310177 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Auto-Submit: John Stiles <johnstiles@google.com>
1 parent 70743df commit 48bdf6d

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

src/sksl/SkSLIRGenerator.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,7 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
20392039
};
20402040
switch (statement.fKind) {
20412041
case Statement::kBlock_Kind: {
2042-
const Block& b = (const Block&) statement;
2042+
const Block& b = static_cast<const Block&>(statement);
20432043
return std::make_unique<Block>(offset, stmts(b.fStatements), b.fSymbols, b.fIsScope);
20442044
}
20452045

@@ -2049,32 +2049,32 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
20492049
return statement.clone();
20502050

20512051
case Statement::kDo_Kind: {
2052-
const DoStatement& d = (const DoStatement&) statement;
2052+
const DoStatement& d = static_cast<const DoStatement&>(statement);
20532053
return std::make_unique<DoStatement>(offset, stmt(d.fStatement), expr(d.fTest));
20542054
}
20552055
case Statement::kExpression_Kind: {
2056-
const ExpressionStatement& e = (const ExpressionStatement&) statement;
2056+
const ExpressionStatement& e = static_cast<const ExpressionStatement&>(statement);
20572057
return std::make_unique<ExpressionStatement>(expr(e.fExpression));
20582058
}
20592059
case Statement::kFor_Kind: {
2060-
const ForStatement& f = (const ForStatement&) statement;
2060+
const ForStatement& f = static_cast<const ForStatement&>(statement);
20612061
// need to ensure initializer is evaluated first so that we've already remapped its
20622062
// declarations by the time we evaluate test & next
20632063
std::unique_ptr<Statement> initializer = stmt(f.fInitializer);
20642064
return std::make_unique<ForStatement>(offset, std::move(initializer), expr(f.fTest),
20652065
expr(f.fNext), stmt(f.fStatement), f.fSymbols);
20662066
}
20672067
case Statement::kIf_Kind: {
2068-
const IfStatement& i = (const IfStatement&) statement;
2068+
const IfStatement& i = static_cast<const IfStatement&>(statement);
20692069
return std::make_unique<IfStatement>(offset, i.fIsStatic, expr(i.fTest),
20702070
stmt(i.fIfTrue), stmt(i.fIfFalse));
20712071
}
20722072
case Statement::kNop_Kind:
20732073
return statement.clone();
20742074
case Statement::kReturn_Kind: {
2075-
const ReturnStatement& r = (const ReturnStatement&) statement;
2075+
const ReturnStatement& r = static_cast<const ReturnStatement&>(statement);
20762076
if (r.fExpression) {
2077-
std::unique_ptr<Statement> assignment = std::make_unique<ExpressionStatement>(
2077+
auto assignment = std::make_unique<ExpressionStatement>(
20782078
std::make_unique<BinaryExpression>(
20792079
offset,
20802080
std::make_unique<VariableReference>(offset, *returnVar,
@@ -2086,9 +2086,10 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
20862086
std::vector<std::unique_ptr<Statement>> block;
20872087
block.push_back(std::move(assignment));
20882088
block.emplace_back(new BreakStatement(offset));
2089-
return std::make_unique<Block>(offset, std::move(block), nullptr, false);
2089+
return std::make_unique<Block>(offset, std::move(block), /*symbols=*/nullptr,
2090+
/*isScope=*/true);
20902091
} else {
2091-
return assignment;
2092+
return std::move(assignment);
20922093
}
20932094
} else {
20942095
if (haveEarlyReturns) {
@@ -2099,7 +2100,7 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
20992100
}
21002101
}
21012102
case Statement::kSwitch_Kind: {
2102-
const SwitchStatement& ss = (const SwitchStatement&) statement;
2103+
const SwitchStatement& ss = static_cast<const SwitchStatement&>(statement);
21032104
std::vector<std::unique_ptr<SwitchCase>> cases;
21042105
for (const auto& sc : ss.fCases) {
21052106
cases.emplace_back(new SwitchCase(offset, expr(sc->fValue),
@@ -2109,7 +2110,7 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
21092110
std::move(cases), ss.fSymbols);
21102111
}
21112112
case Statement::kVarDeclaration_Kind: {
2112-
const VarDeclaration& decl = (const VarDeclaration&) statement;
2113+
const VarDeclaration& decl = static_cast<const VarDeclaration&>(statement);
21132114
std::vector<std::unique_ptr<Expression>> sizes;
21142115
for (const auto& size : decl.fSizes) {
21152116
sizes.push_back(expr(size));
@@ -2133,7 +2134,8 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
21332134
std::move(initialValue));
21342135
}
21352136
case Statement::kVarDeclarations_Kind: {
2136-
const VarDeclarations& decls = *((VarDeclarationsStatement&) statement).fDeclaration;
2137+
const VarDeclarations& decls =
2138+
*static_cast<const VarDeclarationsStatement&>(statement).fDeclaration;
21372139
std::vector<std::unique_ptr<VarDeclaration>> vars;
21382140
for (const auto& var : decls.fVars) {
21392141
vars.emplace_back((VarDeclaration*) stmt(var).release());
@@ -2143,7 +2145,7 @@ std::unique_ptr<Statement> IRGenerator::inlineStatement(
21432145
std::make_unique<VarDeclarations>(offset, typePtr, std::move(vars))));
21442146
}
21452147
case Statement::kWhile_Kind: {
2146-
const WhileStatement& w = (const WhileStatement&) statement;
2148+
const WhileStatement& w = static_cast<const WhileStatement&>(statement);
21472149
return std::make_unique<WhileStatement>(offset, expr(w.fTest), stmt(w.fStatement));
21482150
}
21492151
default:

tests/SkSLFPTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,39 @@ half4 _inlineArghalf4loopyhalf41_0 = %s;
11181118
});
11191119
}
11201120

1121+
DEF_TEST(SkSLFPIfStatementWithReturnInsideCanBeInlined, r) {
1122+
test(r,
1123+
*SkSL::ShaderCapsFactory::Default(),
1124+
R"__SkSL__(
1125+
half4 branchy(half4 c) {
1126+
if (c.z == c.w) return c.yyyy; else return c.zzzz;
1127+
}
1128+
void main() {
1129+
sk_OutColor = branchy(sk_InColor);
1130+
}
1131+
)__SkSL__",
1132+
/*expectedH=*/{},
1133+
/*expectedCPP=*/{
1134+
R"__Cpp__(fragBuilder->codeAppendf(
1135+
R"SkSL(half4 _inlineResulthalf4branchyhalf40;
1136+
half4 _inlineArghalf4branchyhalf41_0 = %s;
1137+
do {
1138+
if (_inlineArghalf4branchyhalf41_0.z == _inlineArghalf4branchyhalf41_0.w) {
1139+
_inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.yyyy;
1140+
break;
1141+
} else {
1142+
_inlineResulthalf4branchyhalf40 = _inlineArghalf4branchyhalf41_0.zzzz;
1143+
break;
1144+
}
1145+
} while (false);
1146+
%s = _inlineResulthalf4branchyhalf40;
1147+
1148+
)SkSL"
1149+
, args.fInputColor, args.fOutputColor);
1150+
)__Cpp__",
1151+
});
1152+
}
1153+
11211154
DEF_TEST(SkSLFPMatrixSampleConstant, r) {
11221155
test(r,
11231156
*SkSL::ShaderCapsFactory::Default(),

0 commit comments

Comments
 (0)