public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] rust/lex: skip broken string expression ...
@ 2022-06-09  6:16 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-09  6:16 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:46e248fb7fe7af696f5bd331f1b981cfe2ffca76

commit 46e248fb7fe7af696f5bd331f1b981cfe2ffca76
Author: liushuyu <liushuyu011@gmail.com>
Date:   Tue Jun 7 00:57:43 2022 -0600

    rust/lex: skip broken string expression ...
    
    ... when the matching quote is not found on the same line
    
    this could unstuck the string parser when the parser could not advance
    the parsing position

Diff:
---
 gcc/rust/lex/rust-lex.cc                           | 32 ++++++++++++++++++++++
 gcc/rust/lex/rust-lex.h                            |  1 +
 gcc/rust/parse/rust-parse-impl.h                   |  3 +-
 .../rust/compile/torture/check-doc-attr-string.rs  | 13 +++++++++
 .../compile/torture/very-broken-attr-string.rs     |  3 ++
 5 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/lex/rust-lex.cc b/gcc/rust/lex/rust-lex.cc
index ea09ac22c22..023b67651b7 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 e01d86d56a0..429b9e129c1 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 dfd393e6a2d..0fc1c1fe3ac 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 00000000000..33001c01fd0
--- /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 00000000000..832ba7b8ec9
--- /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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-09  6:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-09  6:16 [gcc/devel/rust/master] rust/lex: skip broken string expression Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).