summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-parser.cpp33
-rw-r--r--tests/bugs/eroneous-generic-parse.slang15
-rw-r--r--tests/bugs/eroneous-generic-parse.slang.expected8
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 = {
+}