[gcc/devel/rust/master] expand: correctly handles non-macro nodes ...

Thomas Schwinge tschwinge@gcc.gnu.org
Sat Aug 6 12:09:10 GMT 2022


https://gcc.gnu.org/g:9fc6a27b5c6ea2c775646c4474b9084da76b1764

commit 9fc6a27b5c6ea2c775646c4474b9084da76b1764
Author: liushuyu <liushuyu011@gmail.com>
Date:   Tue Aug 2 02:17:48 2022 -0600

    expand: correctly handles non-macro nodes ...
    
    ... when expanding macros recursively to avoid improperly stripping them
    
    Signed-off-by: Zixing Liu <liushuyu011@gmail.com>

Diff:
---
 gcc/rust/expand/rust-macro-expand.h           | 16 ++++++++++++++
 gcc/testsuite/rust/compile/macro-issue1403.rs | 31 +++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h
index 341c5a4ad63..94d6702ecb8 100644
--- a/gcc/rust/expand/rust-macro-expand.h
+++ b/gcc/rust/expand/rust-macro-expand.h
@@ -321,12 +321,28 @@ struct MacroExpander
   AST::ASTFragment take_expanded_fragment (AST::ASTVisitor &vis)
   {
     AST::ASTFragment old_fragment = std::move (expanded_fragment);
+    auto accumulator = std::vector<AST::SingleASTNode> ();
     expanded_fragment = AST::ASTFragment::create_error ();
 
     for (auto &node : old_fragment.get_nodes ())
       {
 	expansion_depth++;
 	node.accept_vis (vis);
+	// we'll decide the next move according to the outcome of the macro
+	// expansion
+	if (expanded_fragment.is_error ())
+	  accumulator.push_back (node); // if expansion fails, there might be a
+					// non-macro expression we need to keep
+	else
+	  {
+	    // if expansion succeeded, then we need to merge the fragment with
+	    // the contents in the accumulator, so that our final expansion
+	    // result will contain non-macro nodes as it should
+	    auto new_nodes = expanded_fragment.get_nodes ();
+	    std::move (new_nodes.begin (), new_nodes.end (),
+		       std::back_inserter (accumulator));
+	    expanded_fragment = AST::ASTFragment (accumulator);
+	  }
 	expansion_depth--;
       }
 
diff --git a/gcc/testsuite/rust/compile/macro-issue1403.rs b/gcc/testsuite/rust/compile/macro-issue1403.rs
new file mode 100644
index 00000000000..756d374e25c
--- /dev/null
+++ b/gcc/testsuite/rust/compile/macro-issue1403.rs
@@ -0,0 +1,31 @@
+// { dg-do compile }
+// { dg-options "-O1 -gdwarf-5 -dA -w" }
+macro_rules! stmt {
+    ($s:stmt) => {
+        $s
+    };
+    ($s:stmt, $($ss:stmt),*) => {
+        $s;
+        stmt!($($ss),*);
+    };
+}
+
+pub fn test() -> i32 {
+    stmt!(
+        let a = 1
+    );
+    stmt!(
+        let b = 2,
+        let c = 3,
+        let d = 4,
+        let e = 5,
+        let f = b + c + d + e
+    );
+    // { dg-final { scan-assembler "14" } }
+    f
+}
+
+fn main() {
+    let _ = test();
+}
+


More information about the Gcc-cvs mailing list