diff options
| -rw-r--r-- | source/slang/slang-parser.cpp | 33 | ||||
| -rw-r--r-- | tests/bugs/eroneous-generic-parse.slang | 15 | ||||
| -rw-r--r-- | tests/bugs/eroneous-generic-parse.slang.expected | 8 |
3 files changed, 51 insertions, 5 deletions
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index bca493780..6d2abef49 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -147,9 +147,14 @@ namespace Slang Token ReadToken(); Token ReadToken(TokenType type); - Token ReadToken(const char * string); - bool LookAheadToken(TokenType type, int offset = 0); - bool LookAheadToken(const char * string, int offset = 0); + Token ReadToken(const char* string); + + bool LookAheadToken(TokenType type); + bool LookAheadToken(const char* string); + + bool LookAheadToken(TokenType type, int offset); + bool LookAheadToken(const char* string, int offset); + void parseSourceFile(ModuleDecl* program); Decl* ParseStruct(); ClassDecl* ParseClass(); @@ -537,7 +542,7 @@ namespace Slang } } - bool Parser::LookAheadToken(const char * string, int offset) + bool Parser::LookAheadToken(const char* string, int offset) { TokenReader r = tokenReader; for (int ii = 0; ii < offset; ++ii) @@ -556,6 +561,17 @@ namespace Slang return r.peekTokenType() == type; } + bool Parser::LookAheadToken(TokenType type) + { + return tokenReader.peekTokenType() == type; + } + + bool Parser::LookAheadToken(const char* string) + { + const auto& token = tokenReader.peekToken(); + return token.type == TokenType::Identifier && token.getContent() == string; + } + // Consume a token and return true it if matches, otherwise false bool AdvanceIf(Parser* parser, TokenType tokenType) { @@ -1291,8 +1307,15 @@ namespace Slang { parser->ReadToken(TokenType::OpLess); parser->genericDepth++; - while (!parser->LookAheadToken(TokenType::OpGreater)) + for (;;) { + const TokenType tokenType = parser->tokenReader.peekTokenType(); + if (tokenType == TokenType::OpGreater || + tokenType == TokenType::EndOfFile) + { + break; + } + AddMember(decl, ParseGenericParamDecl(parser, decl)); if (parser->LookAheadToken(TokenType::OpGreater)) diff --git a/tests/bugs/eroneous-generic-parse.slang b/tests/bugs/eroneous-generic-parse.slang new file mode 100644 index 000000000..80a693456 --- /dev/null +++ b/tests/bugs/eroneous-generic-parse.slang @@ -0,0 +1,15 @@ +//DIAGNOSTIC_TEST:SIMPLE: -target hlsl -entry computeMain -stage compute + +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], stride=16):out +RWStructuredBuffer<int> outputBuffer; + +// Previously this definition would lead to an infinite loop in parsing. +int doThing<1>() { return 2; } + +[numthreads(4, 4, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + int index = dispatchThreadID.x; + + outputBuffer[index] = index; +}
\ No newline at end of file diff --git a/tests/bugs/eroneous-generic-parse.slang.expected b/tests/bugs/eroneous-generic-parse.slang.expected new file mode 100644 index 000000000..a6ee73d88 --- /dev/null +++ b/tests/bugs/eroneous-generic-parse.slang.expected @@ -0,0 +1,8 @@ +result code = -1 +standard error = { +tests/bugs/eroneous-generic-parse.slang(7): error 20001: unexpected integer literal, expected identifier +int doThing<1>() { return 2; } + ^ +} +standard output = { +} |
