diff options
-rw-r--r-- | gcc/rust/lex/rust-lex.cc | 32 | ||||
-rw-r--r-- | gcc/rust/lex/rust-lex.h | 1 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 3 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/check-doc-attr-string.rs | 13 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/very-broken-attr-string.rs | 3 |
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 |