From: Harishankar <[email protected]>

The compiler previously crashed with a segmentation fault when parsing
a struct or tuple expression that failed to parse correctly (e.g.,
returning nullptr). This occurred because the parser implicitly wrapped
the null pointer result in a successful tl::expected, causing a crash
later when the compiler attempted to use the invalid pointer. This
patch adds checks in null_denotation_path to ensure that failed struct
and tuple parsing results are returned as errors (tl::unexpected)
instead of null pointers.

Fixes Rust-GCC/gccrs#4426

gcc/rust/ChangeLog:

        * parse/rust-parse-impl-expr.hxx (null_denotation_path):
        Check for null struct and tuple expressions to prevent segmentation 
fault.

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/c4bc3153bffc32eced40a54a83fe8863729456c8

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

 gcc/rust/parse/rust-parse-impl-expr.hxx | 40 +++++++++++++++++--------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index 713bcc8d0..306a0958d 100644
--- a/gcc/rust/parse/rust-parse-impl-expr.hxx
+++ b/gcc/rust/parse/rust-parse-impl-expr.hxx
@@ -2001,20 +2001,36 @@ Parser<ManagedTokenSource>::null_denotation_path (
            return std::unique_ptr<AST::PathInExpression> (
              new AST::PathInExpression (std::move (path)));
          }
-       return parse_struct_expr_struct_partial (std::move (path),
-                                                std::move (outer_attrs));
+       auto struct_expr
+         = parse_struct_expr_struct_partial (std::move (path),
+                                             std::move (outer_attrs));
+       if (struct_expr == nullptr)
+         {
+           return tl::unexpected<Parse::Error::Expr> (
+             Parse::Error::Expr::CHILD_ERROR);
+         }
+       return struct_expr;
       }
     case LEFT_PAREN:
-      // struct/enum expr tuple
-      if (!restrictions.can_be_struct_expr)
-       {
-         // assume path is returned
-         // HACK: add outer attributes to path
-         path.set_outer_attrs (std::move (outer_attrs));
-         return std::make_unique<AST::PathInExpression> (std::move (path));
-       }
-      return parse_struct_expr_tuple_partial (std::move (path),
-                                             std::move (outer_attrs));
+      {
+       // struct/enum expr tuple
+       if (!restrictions.can_be_struct_expr)
+         {
+           // assume path is returned
+           // HACK: add outer attributes to path
+           path.set_outer_attrs (std::move (outer_attrs));
+           return std::make_unique<AST::PathInExpression> (std::move (path));
+         }
+       auto tuple_expr
+         = parse_struct_expr_tuple_partial (std::move (path),
+                                            std::move (outer_attrs));
+       if (tuple_expr == nullptr)
+         {
+           return tl::unexpected<Parse::Error::Expr> (
+             Parse::Error::Expr::CHILD_ERROR);
+         }
+       return tuple_expr;
+      }
     default:
       // assume path is returned if not single segment
       if (path.is_single_segment ())

base-commit: 9ed1331dee4b5a7cd43d61d869ef4f16b3011f51
-- 
2.52.0

Reply via email to