HLSL: Track control-flow nesting and warn on aliasing under it.

This commit is contained in:
John Kessenich 2017-06-06 19:52:55 -06:00
parent 9b2531ba23
commit f6deacd579
2 changed files with 21 additions and 4 deletions

View File

@ -2594,6 +2594,8 @@ bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
if (node == nullptr)
return false;
++parseContext.controlFlowNestingLevel; // this only needs to work right if no errors
TIntermTyped* trueNode = nullptr;
if (! acceptExpression(trueNode)) {
expected("expression after ?");
@ -2612,6 +2614,8 @@ bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
return false;
}
--parseContext.controlFlowNestingLevel;
node = intermediate.addSelection(node, trueNode, falseNode, loc);
return true;
@ -3288,6 +3292,8 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
// create the child statements
TIntermNodePair thenElse = { nullptr, nullptr };
++parseContext.controlFlowNestingLevel; // this only needs to work right if no errors
// then statement
if (! acceptScopedStatement(thenElse.node1)) {
expected("then statement");
@ -3306,6 +3312,7 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement)
// Put the pieces together
statement = intermediate.addSelection(condition, thenElse, loc);
parseContext.popScope();
--parseContext.controlFlowNestingLevel;
return true;
}
@ -3330,7 +3337,11 @@ bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement)
// compound_statement
parseContext.pushSwitchSequence(new TIntermSequence);
++parseContext.controlFlowNestingLevel;
bool statementOkay = acceptCompoundStatement(statement);
--parseContext.controlFlowNestingLevel;
if (statementOkay)
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr);
@ -3363,8 +3374,9 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
case EHTokWhile:
// so that something declared in the condition is scoped to the lifetime
// of the while sub-statement
parseContext.pushScope();
parseContext.pushScope(); // this only needs to work right if no errors
parseContext.nestLooping();
++parseContext.controlFlowNestingLevel;
// LEFT_PAREN condition RIGHT_PAREN
if (! acceptParenExpression(condition))
@ -3381,13 +3393,15 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
parseContext.unnestLooping();
parseContext.popScope();
--parseContext.controlFlowNestingLevel;
statement = intermediate.addLoop(statement, condition, nullptr, true, loc, control);
return true;
case EHTokDo:
parseContext.nestLooping();
parseContext.nestLooping(); // this only needs to work right if no errors
++parseContext.controlFlowNestingLevel;
// statement
if (! acceptScopedStatement(statement)) {
@ -3413,6 +3427,7 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
expected(";");
parseContext.unnestLooping();
--parseContext.controlFlowNestingLevel;
statement = intermediate.addLoop(statement, condition, 0, false, loc, control);
@ -3433,7 +3448,8 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
if (! acceptSimpleStatement(initNode))
expected("for-loop initializer statement");
parseContext.nestLooping();
parseContext.nestLooping(); // this only needs to work right if no errors
++parseContext.controlFlowNestingLevel;
// condition SEMI_COLON
acceptExpression(condition);
@ -3461,6 +3477,7 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
parseContext.popScope();
parseContext.unnestLooping();
--parseContext.controlFlowNestingLevel;
return true;
}

View File

@ -518,7 +518,7 @@ TIntermTyped* HlslParseContext::handleSamplerLvalue(const TSourceLoc& loc, const
}
if (controlFlowNestingLevel > 0)
error(loc, "can't alias sampler in control flow", op, "");
warn(loc, "sampler or image aliased under control flow; consumption must be in same path", op, "");
// Best is if we are aliasing a flattened struct member "S.s1 = s2",
// in which case we want to update the flattening information with the alias,