From e26b95f64a0f450199b3a5f58db68dfd0fb585b5 Mon Sep 17 00:00:00 2001 From: antego Date: Wed, 13 Apr 2022 20:00:54 +1000 Subject: [PATCH] Following up on #1141. Implementing macro expansion or ComparisonExpr, LazyBooleanExpr, AssignmentExpr. --- gcc/rust/expand/rust-attribute-visitor.cc | 39 ++++++++++++++++--- .../rust/execute/torture/macros29.rs | 21 ++++++++++ .../rust/execute/torture/macros30.rs | 22 +++++++++++ .../rust/execute/torture/macros31.rs | 27 +++++++++++++ 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/rust/execute/torture/macros29.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros30.rs create mode 100644 gcc/testsuite/rust/execute/torture/macros31.rs diff --git a/gcc/rust/expand/rust-attribute-visitor.cc b/gcc/rust/expand/rust-attribute-visitor.cc index 859ae7e9708..e420d0932a5 100644 --- a/gcc/rust/expand/rust-attribute-visitor.cc +++ b/gcc/rust/expand/rust-attribute-visitor.cc @@ -643,10 +643,19 @@ AttrVisitor::visit (AST::ComparisonExpr &expr) /* should have no possibility for outer attrs as would be parsed * with outer expr */ - expr.get_left_expr ()->accept_vis (*this); + auto &l_expr = expr.get_left_expr (); + l_expr->accept_vis (*this); + auto l_fragment = expander.take_expanded_fragment (*this); + if (l_fragment.should_expand ()) + l_expr = l_fragment.take_expression_fragment (); + /* should syntactically not have outer attributes, though this may * not have worked in practice */ - expr.get_right_expr ()->accept_vis (*this); + auto &r_expr = expr.get_right_expr (); + r_expr->accept_vis (*this); + auto r_fragment = expander.take_expanded_fragment (*this); + if (r_fragment.should_expand ()) + r_expr = r_fragment.take_expression_fragment (); // ensure that they are not marked for strip if (expr.get_left_expr ()->is_marked_for_strip ()) @@ -667,10 +676,19 @@ AttrVisitor::visit (AST::LazyBooleanExpr &expr) /* should have no possibility for outer attrs as would be parsed * with outer expr */ - expr.get_left_expr ()->accept_vis (*this); + auto &l_expr = expr.get_left_expr (); + l_expr->accept_vis (*this); + auto l_fragment = expander.take_expanded_fragment (*this); + if (l_fragment.should_expand ()) + l_expr = l_fragment.take_expression_fragment (); + /* should syntactically not have outer attributes, though this may * not have worked in practice */ - expr.get_right_expr ()->accept_vis (*this); + auto &r_expr = expr.get_right_expr (); + r_expr->accept_vis (*this); + auto r_fragment = expander.take_expanded_fragment (*this); + if (r_fragment.should_expand ()) + r_expr = r_fragment.take_expression_fragment (); // ensure that they are not marked for strip if (expr.get_left_expr ()->is_marked_for_strip ()) @@ -718,10 +736,19 @@ AttrVisitor::visit (AST::AssignmentExpr &expr) /* should have no possibility for outer attrs as would be parsed * with outer expr */ - expr.get_left_expr ()->accept_vis (*this); + auto &l_expr = expr.get_left_expr (); + l_expr->accept_vis (*this); + auto l_fragment = expander.take_expanded_fragment (*this); + if (l_fragment.should_expand ()) + l_expr = l_fragment.take_expression_fragment (); + /* should syntactically not have outer attributes, though this may * not have worked in practice */ - expr.get_right_expr ()->accept_vis (*this); + auto &r_expr = expr.get_right_expr (); + r_expr->accept_vis (*this); + auto r_fragment = expander.take_expanded_fragment (*this); + if (r_fragment.should_expand ()) + r_expr = r_fragment.take_expression_fragment (); // ensure that they are not marked for strip if (expr.get_left_expr ()->is_marked_for_strip ()) diff --git a/gcc/testsuite/rust/execute/torture/macros29.rs b/gcc/testsuite/rust/execute/torture/macros29.rs new file mode 100644 index 00000000000..7bce29b5995 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros29.rs @@ -0,0 +1,21 @@ +// { dg-output "1\n" } +macro_rules! concat { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + printf("%u\n\0" as *const str as *const i8, s); +} + +fn main () -> i32 { + let res = concat!("test2") == "test3"; + if !res { + print(1); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros30.rs b/gcc/testsuite/rust/execute/torture/macros30.rs new file mode 100644 index 00000000000..09247e6dd7e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros30.rs @@ -0,0 +1,22 @@ +// { dg-output "1\n" } +macro_rules! concat { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: u32) { + printf("%u\n\0" as *const str as *const i8, s); +} + +fn main () -> i32 { + let mut x = concat!("x"); + x = concat!("y"); + if x == "y" { + print(1); + } + + 0 +} diff --git a/gcc/testsuite/rust/execute/torture/macros31.rs b/gcc/testsuite/rust/execute/torture/macros31.rs new file mode 100644 index 00000000000..1a67c473770 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/macros31.rs @@ -0,0 +1,27 @@ +// { dg-additional-options "-w -frust-cfg=A" } +// { dg-output "A\nB\n" } +macro_rules! cfg { + () => {{}}; +} + +extern "C" { + fn printf(fmt: *const i8, ...); +} + +fn print(s: &str) { + printf("%s\n" as *const str as *const i8, s as *const str as *const i8); +} + + +fn main() -> i32 { + let cfg = cfg!(A) || cfg!(B); + if cfg { + print("A"); + } + let cfg = cfg!(A) && cfg!(B); + if !cfg { + print("B"); + } + + 0 +}