[mlir:PDLL] Fix error handling of eof within a string literal
authorRiver Riddle <riddleriver@gmail.com>
Tue, 26 Apr 2022 20:27:03 +0000 (13:27 -0700)
committerRiver Riddle <riddleriver@gmail.com>
Thu, 28 Apr 2022 19:58:00 +0000 (12:58 -0700)
We currently aren't handling this properly, and in the case
of a string block just crash. This commit adds proper error handling
and detection for eof.

Differential Revision: https://reviews.llvm.org/D124585

mlir/lib/Tools/PDLL/Parser/Lexer.cpp
mlir/lib/Tools/PDLL/Parser/Parser.cpp
mlir/test/mlir-pdll/Parser/string-eof.pdll [new file with mode: 0644]

index 6b338f1..250b21d 100644 (file)
@@ -355,19 +355,28 @@ Token Lexer::lexString(const char *tokStart, bool isStringBlock) {
       case '"':
         // If this is a string block, we only end the string when we encounter a
         // `}]`.
-        if (!isStringBlock) return formToken(Token::string, tokStart);
+        if (!isStringBlock)
+          return formToken(Token::string, tokStart);
         continue;
       case '}':
         // If this is a string block, we only end the string when we encounter a
         // `}]`.
-        if (!isStringBlock || *curPtr != ']') continue;
+        if (!isStringBlock || *curPtr != ']')
+          continue;
         ++curPtr;
         return formToken(Token::string_block, tokStart);
-      case 0:
+      case 0: {
         // If this is a random nul character in the middle of a string, just
-        // include it.  If it is the end of file, then it is an error.
-        if (curPtr - 1 != curBuffer.end()) continue;
-        LLVM_FALLTHROUGH;
+        // include it. If it is the end of file, then it is an error.
+        if (curPtr - 1 != curBuffer.end())
+          continue;
+        --curPtr;
+
+        StringRef expectedEndStr = isStringBlock ? "}]" : "\"";
+        return emitError(curPtr - 1,
+                         "expected '" + expectedEndStr + "' in string literal");
+      }
+
       case '\n':
       case '\v':
       case '\f':
index 3397b30..53d5417 100644 (file)
@@ -1245,6 +1245,8 @@ FailureOr<T *> Parser::parseUserNativeConstraintOrRewriteDecl(
   } else if (isInline) {
     return emitError(name.getLoc(),
                      "external declarations must be declared in global scope");
+  } else if (curToken.is(Token::error)) {
+    return failure();
   }
   if (failed(parseToken(Token::semicolon,
                         "expected `;` after native declaration")))
diff --git a/mlir/test/mlir-pdll/Parser/string-eof.pdll b/mlir/test/mlir-pdll/Parser/string-eof.pdll
new file mode 100644 (file)
index 0000000..5265d33
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: not mlir-pdll %s -I %S -split-input-file 2>&1 | FileCheck %s
+
+// CHECK: expected '}]' in string literal
+Constraint Cst() [{
+
+// -----
+
+// CHECK: expected '"' in string literal
+Constraint Cst() "
\ No newline at end of file