aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/lex/rust-lex.cc32
-rw-r--r--gcc/rust/lex/rust-lex.h1
-rw-r--r--gcc/rust/parse/rust-parse-impl.h3
-rw-r--r--gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs13
-rw-r--r--gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs3
5 files changed, 51 insertions, 1 deletions
diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index ea09ac2..023b676 100644
--- a/gcc/rust/lex/rust-lex.cc
+++ b/gcc/rust/lex/rust-lex.cc
@@ -1856,6 +1856,35 @@ Lexer::parse_raw_identifier (Location loc)
}
}
+// skip broken string input (unterminated strings)
+void
+Lexer::skip_broken_string_input (int current_char)
+{
+ while (current_char != '"' && current_char != EOF)
+ {
+ if (current_char == '\n')
+ {
+ current_line++;
+ current_column = 1;
+ }
+ else
+ {
+ current_column++;
+ }
+ skip_input ();
+ current_char = peek_input ();
+ }
+ if (current_char == '"')
+ {
+ current_column++;
+
+ skip_input ();
+ current_char = peek_input ();
+ }
+ rust_debug ("skipped to %d:%d due to bad quotes", current_line,
+ current_column);
+}
+
// Parses a unicode string.
TokenPtr
Lexer::parse_string (Location loc)
@@ -1903,6 +1932,9 @@ Lexer::parse_string (Location loc)
if (current_char32.value == '\n')
{
rust_error_at (get_current_location (), "unended string literal");
+ // by this point, the parser will stuck at this position due to
+ // undetermined string termination. we now need to unstuck the parser
+ skip_broken_string_input (current_char32.value);
}
else if (current_char32.value == '"')
{
diff --git a/gcc/rust/lex/rust-lex.h b/gcc/rust/lex/rust-lex.h
index e01d86d..429b9e1 100644
--- a/gcc/rust/lex/rust-lex.h
+++ b/gcc/rust/lex/rust-lex.h
@@ -114,6 +114,7 @@ private:
Codepoint peek_codepoint_input ();
Codepoint test_peek_codepoint_input (int n);
void skip_codepoint_input ();
+ void skip_broken_string_input (int current_char);
TokenPtr parse_byte_char (Location loc);
TokenPtr parse_byte_string (Location loc);
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index dfd393e..0fc1c1f 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -914,7 +914,8 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
// repeat loop until finding the matching delimiter
t = lexer.peek_token ();
- while (!token_id_matches_delims (t->get_id (), delim_type))
+ while (!token_id_matches_delims (t->get_id (), delim_type)
+ && t->get_id () != END_OF_FILE)
{
std::unique_ptr<AST::TokenTree> tok_tree = parse_token_tree ();
diff --git a/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs b/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs
new file mode 100644
index 0000000..33001c0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs
@@ -0,0 +1,13 @@
+#![crate_type = "lib"]
+
+#[doc(alias = "foo")] // ok!
+#[doc(alias("bar", "baz"))] // ok!
+pub struct Bar;
+
+#[doc(alias = "
+")] // { dg-error "unended string literal" "" { target *-*-* } .-1 }
+pub struct Foo;
+
+#[doc(alias("
+"))] // { dg-error "unended string literal" "" { target *-*-* } .-1 }
+pub struct Foo2;
diff --git a/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs b/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs
new file mode 100644
index 0000000..832ba7b
--- /dev/null
+++ b/gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs
@@ -0,0 +1,3 @@
+// { dg-excess-errors "...." }
+// { dg-error "unended string literal" "" { target *-*-* } .+1 }
+#[doc(alias = "123