[gcc r14-7548] gccrs: Handle replacing stripped tail expressions

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:43:30 GMT 2024


https://gcc.gnu.org/g:b181ea7289b229b1e5971ccbbdd4f74dbdacefa9

commit r14-7548-gb181ea7289b229b1e5971ccbbdd4f74dbdacefa9
Author: Owen Avery <powerboat9.gamer@gmail.com>
Date:   Wed Apr 26 09:29:04 2023 -0400

    gccrs: Handle replacing stripped tail expressions
    
    gcc/rust/ChangeLog:
    
            * ast/rust-ast.cc
            (BlockExpr::strip_tail_expr):
            Try to take new tail expression from statements list.
            * ast/rust-expr.h
            (BlockExpr::strip_tail_expr):
            Replace definition with only declaration.
    
    gcc/testsuite/ChangeLog:
    
            * rust/execute/torture/cfg-tail.rs: New test.
    
    Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>

Diff:
---
 gcc/rust/ast/rust-ast.cc                       | 25 +++++++++++++++++++++++++
 gcc/rust/ast/rust-expr.h                       |  2 +-
 gcc/testsuite/rust/execute/torture/cfg-tail.rs |  9 +++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index a664a319513..7a9dc8a008b 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -4213,6 +4213,31 @@ Attribute::is_parsed_to_meta_item () const
   return has_attr_input () && attr_input->is_meta_item ();
 }
 
+void
+BlockExpr::strip_tail_expr ()
+{
+  if (expr)
+    {
+      expr = nullptr;
+
+      // HACK: try to turn the last statement into a tail expression
+      if (statements.size () && statements.back ()->is_expr ())
+	{
+	  auto &stmt = static_cast<ExprStmt &> (*statements.back ());
+
+	  if (stmt.get_type () == ExprStmt::ExprStmtType::WITH_BLOCK)
+	    {
+	      auto &stmt_block = static_cast<ExprStmtWithBlock &> (stmt);
+	      if (!stmt_block.is_semicolon_followed ())
+		{
+		  expr = std::move (stmt_block.get_expr ());
+		  statements.pop_back ();
+		}
+	    }
+	}
+    }
+}
+
 /* Visitor implementations - these are short but inlining can't happen anyway
  * due to virtual functions and I didn't want to make the ast header includes
  * any longer than they already are. */
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index abe6e03ce45..c43baf3cade 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -2446,7 +2446,7 @@ public:
   }
 
   // Removes the tail expression from the block.
-  void strip_tail_expr () { expr = nullptr; }
+  void strip_tail_expr ();
 
   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; }
   std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
diff --git a/gcc/testsuite/rust/execute/torture/cfg-tail.rs b/gcc/testsuite/rust/execute/torture/cfg-tail.rs
new file mode 100644
index 00000000000..69411a6cdbc
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/cfg-tail.rs
@@ -0,0 +1,9 @@
+fn foo() -> i32 {
+    {54}
+    #[cfg(all(A, not(A)))]
+    {45}
+}
+
+fn main() -> i32 {
+    return foo() - 54;
+}


More information about the Gcc-cvs mailing list