From: Harishankar <[email protected]>

The compiler previously crashed with a segmentation fault when parsing
an arithmetic expression where the left-hand side was invalid (e.g.,
after a failed macro expansion). This occurred because the parser
attempted to access the location of the null 'left' pointer. This
patch adds a check to ensure the left operand is valid before proceeding.

Fixes Rust-GCC/gccrs#4414

gcc/rust/ChangeLog:

        * parse/rust-parse-impl-expr.hxx (parse_arithmetic_or_logical_expr):
        Check for null left operand to prevent segmentation fault.

gcc/testsuite/ChangeLog:

        * rust/compile/issue-4414.rs: New test.

Signed-off-by: Harishankar <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/9ed1331dee4b5a7cd43d61d869ef4f16b3011f51

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4417

 gcc/rust/parse/rust-parse-impl-expr.hxx  |  4 +++-
 gcc/testsuite/rust/compile/issue-4414.rs | 30 ++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/rust/compile/issue-4414.rs

diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index 2a2d844b7..713bcc8d0 100644
--- a/gcc/rust/parse/rust-parse-impl-expr.hxx
+++ b/gcc/rust/parse/rust-parse-impl-expr.hxx
@@ -1794,7 +1794,9 @@ Parser<ManagedTokenSource>::parse_expr (int 
right_binding_power,
     = null_denotation ({}, null_denotation_restrictions);
   if (!expr)
     return tl::unexpected<Parse::Error::Expr> 
(Parse::Error::Expr::CHILD_ERROR);
-
+  if (expr.value () == nullptr)
+    return tl::unexpected<Parse::Error::Expr> 
(Parse::Error::Expr::CHILD_ERROR);
+  
   return left_denotations (std::move (expr), right_binding_power,
                           std::move (outer_attrs), restrictions);
 }
diff --git a/gcc/testsuite/rust/compile/issue-4414.rs 
b/gcc/testsuite/rust/compile/issue-4414.rs
new file mode 100644
index 000000000..49f0ba8f8
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-4414.rs
@@ -0,0 +1,30 @@
+#![feature(no_core)]
+#![no_core]
+
+trait Speak : Sized {
+    fn say(&self, s:&str) -> String;
+    fn hi(&self) -> String { hello(self) }
+}
+
+fn hello<S:Speak>(s:&S) -> String{
+    s.say("hello")
+}
+
+impl Speak for assert_eq!(Some(3).hi(), "something!hello: 3".to_string()) { 
+    fn say(&self, s:&str) -> String {
+        format!("{}: {}", s, *self)
+    }
+}
+
+impl<T: Speak> Speak for Option<T> {
+    fn say(&self, s:&str) -> String {
+        match something!hello - none { // { dg-error "unexpected token 
'identifier'|failed to parse scrutinee" }
+            None => format!("{} - none", s),
+            Some(ref x) => { format!("something!{}", x.say(s)) }
+        }
+    } 
+} // { dg-error "could not parse definition" }
+
+fn hello<S:Speak>(s:&S) -> String{ // { dg-error "failed to parse trait impl 
item" }
+    s.say("hello")
+}
\ No newline at end of file

base-commit: 4c81795f42a0bcad435f832474badbfc8f8efd43
-- 
2.52.0

Reply via email to