Commit 0e07119a by John Kessenich

HLSL: Fix #919: for-init-statement is arbitrary declaration or expression.

Unlike "if (XXX)" and "while (XXX)", with "for (YYY...", the YYY can be more kinds of statements than the XXX.
parent e00e8f45
...@@ -5,9 +5,13 @@ float4 PixelShaderFunction(float4 input) : COLOR0 ...@@ -5,9 +5,13 @@ float4 PixelShaderFunction(float4 input) : COLOR0
[unroll] for (; any(input != input); ) {} [unroll] for (; any(input != input); ) {}
for (; any(input != input); ) { return -input; } for (; any(input != input); ) { return -input; }
for (--input; any(input != input); input += 2) { return -input; } for (--input; any(input != input); input += 2) { return -input; }
for (;;) if (input.x > 2.0) break; for (;;) if (input.x > 2.0) break;
for (;;) if (input.x > 2.0) continue; for (;;) if (input.x > 2.0) continue;
float ii; float ii;
for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue; for (int ii = -1; ii < 3; ++ii) if (ii == 2) continue;
--ii; --ii;
for (int first = 0, second = 1; ;) first + second;
for ( int i = 0, count = int(ii); i < count; i++ );
for (float first = 0, second[2], third; first < second[0]; ++second[1]) first + second[1] + third;
for (--ii, --ii, --ii;;) ii;
} }
...@@ -1735,8 +1735,13 @@ TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* init ...@@ -1735,8 +1735,13 @@ TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* init
node->setLoc(loc); node->setLoc(loc);
node->setLoopControl(control); node->setLoopControl(control);
// make a sequence of the initializer and statement // make a sequence of the initializer and statement, but try to reuse the
TIntermAggregate* loopSequence = makeAggregate(initializer, loc); // aggregate already created for whatever is in the initializer, if there is one
TIntermAggregate* loopSequence = (initializer == nullptr ||
initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc)
: initializer->getAsAggregate();
if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence)
loopSequence->setOp(EOpNull);
loopSequence = growAggregate(loopSequence, node); loopSequence = growAggregate(loopSequence, node);
loopSequence->setOperator(EOpSequence); loopSequence->setOperator(EOpSequence);
......
...@@ -3039,6 +3039,37 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node) ...@@ -3039,6 +3039,37 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
return true; return true;
} }
// simple_statement
// : SEMICOLON
// | declaration_statement
// | expression SEMICOLON
//
bool HlslGrammar::acceptSimpleStatement(TIntermNode*& statement)
{
// SEMICOLON
if (acceptTokenClass(EHTokSemicolon))
return true;
// declaration
if (acceptDeclaration(statement))
return true;
// expression
TIntermTyped* node;
if (acceptExpression(node))
statement = node;
else
return false;
// SEMICOLON (following an expression)
if (acceptTokenClass(EHTokSemicolon))
return true;
else {
expected(";");
return false;
}
}
// compound_statement // compound_statement
// : LEFT_CURLY statement statement ... RIGHT_CURLY // : LEFT_CURLY statement statement ... RIGHT_CURLY
// //
...@@ -3096,12 +3127,11 @@ bool HlslGrammar::acceptScopedCompoundStatement(TIntermNode*& statement) ...@@ -3096,12 +3127,11 @@ bool HlslGrammar::acceptScopedCompoundStatement(TIntermNode*& statement)
// //
// attributed_statement // attributed_statement
// : compound_statement // : compound_statement
// | SEMICOLON // | simple_statement
// | expression SEMICOLON
// | declaration_statement
// | selection_statement // | selection_statement
// | switch_statement // | switch_statement
// | case_label // | case_label
// | default_label
// | iteration_statement // | iteration_statement
// | jump_statement // | jump_statement
// //
...@@ -3140,33 +3170,13 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement) ...@@ -3140,33 +3170,13 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
case EHTokDefault: case EHTokDefault:
return acceptDefaultLabel(statement); return acceptDefaultLabel(statement);
case EHTokSemicolon:
return acceptTokenClass(EHTokSemicolon);
case EHTokRightBrace: case EHTokRightBrace:
// Performance: not strictly necessary, but stops a bunch of hunting early, // Performance: not strictly necessary, but stops a bunch of hunting early,
// and is how sequences of statements end. // and is how sequences of statements end.
return false; return false;
default: default:
{ return acceptSimpleStatement(statement);
// declaration
if (acceptDeclaration(statement))
return true;
// expression
TIntermTyped* node;
if (acceptExpression(node))
statement = node;
else
return false;
// SEMICOLON (following an expression)
if (! acceptTokenClass(EHTokSemicolon)) {
expected(";");
return false;
}
}
} }
return true; return true;
...@@ -3420,14 +3430,8 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri ...@@ -3420,14 +3430,8 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
// initializer // initializer
TIntermNode* initNode = nullptr; TIntermNode* initNode = nullptr;
if (! acceptControlDeclaration(initNode)) { if (! acceptSimpleStatement(initNode))
TIntermTyped* initExpr = nullptr; expected("for-loop initializer statement");
acceptExpression(initExpr);
initNode = initExpr;
}
// SEMI_COLON
if (! acceptTokenClass(EHTokSemicolon))
expected(";");
parseContext.nestLooping(); parseContext.nestLooping();
......
...@@ -108,10 +108,11 @@ namespace glslang { ...@@ -108,10 +108,11 @@ namespace glslang {
bool acceptFunctionCall(const TSourceLoc&, TString& name, TIntermTyped*&, TIntermTyped* objectBase); bool acceptFunctionCall(const TSourceLoc&, TString& name, TIntermTyped*&, TIntermTyped* objectBase);
bool acceptArguments(TFunction*, TIntermTyped*&); bool acceptArguments(TFunction*, TIntermTyped*&);
bool acceptLiteral(TIntermTyped*&); bool acceptLiteral(TIntermTyped*&);
bool acceptSimpleStatement(TIntermNode*&);
bool acceptCompoundStatement(TIntermNode*&); bool acceptCompoundStatement(TIntermNode*&);
bool acceptStatement(TIntermNode*&);
bool acceptScopedStatement(TIntermNode*&); bool acceptScopedStatement(TIntermNode*&);
bool acceptScopedCompoundStatement(TIntermNode*&); bool acceptScopedCompoundStatement(TIntermNode*&);
bool acceptStatement(TIntermNode*&);
bool acceptNestedStatement(TIntermNode*&); bool acceptNestedStatement(TIntermNode*&);
void acceptAttributes(TAttributeMap&); void acceptAttributes(TAttributeMap&);
bool acceptSelectionStatement(TIntermNode*&); bool acceptSelectionStatement(TIntermNode*&);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment