diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-04-19 17:01:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-19 17:01:25 +0000 |
commit | f6e244dc0e736853f2ba74fc3e0da585285df191 (patch) | |
tree | 5ab0a7755139bf957cd6398a4c76716185442b80 | |
parent | 4152743451a73591fa60bc52f0b28447ef4a8878 (diff) | |
parent | 5528001eca60bb115e6afc94105ecc7b3820eb52 (diff) | |
download | gcc-f6e244dc0e736853f2ba74fc3e0da585285df191.zip gcc-f6e244dc0e736853f2ba74fc3e0da585285df191.tar.gz gcc-f6e244dc0e736853f2ba74fc3e0da585285df191.tar.bz2 |
Merge #1134
1134: Fix ICE during HIR lowering of ExprWithBlock MatchExpr r=philberty a=philberty
When we are lowering blocks using the visitor pattern we must use the
BaseClass of ExprWithBlock to abstract away the notion that this expr
has a block such that we can handle cases like a block expr vs expressions
with a block. This makes the usage of hir lowering of match expressions to
be recursive, if we had more fine grained visitors in the AST we could fix
these types of problems with compile time enforced interfaces.
Fixes #858
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-block.h | 2 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-expr.h | 47 | ||||
-rw-r--r-- | gcc/rust/hir/rust-ast-lower.cc | 51 | ||||
-rw-r--r-- | gcc/testsuite/rust/execute/torture/issue-858.rs | 32 |
4 files changed, 86 insertions, 46 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index b14668a..512f4709 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -191,6 +191,8 @@ public: void visit (AST::WhileLoopExpr &expr) override; + void visit (AST::MatchExpr &expr) override; + private: ASTLoweringExprWithBlock () : ASTLoweringBase (), translated (nullptr), terminated (false) diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index bb25070..022002e 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -674,52 +674,7 @@ public: void visit (AST::MatchExpr &expr) override { - HIR::Expr *branch_value - = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ()); - - std::vector<HIR::MatchCase> match_arms; - for (auto &match_case : expr.get_match_cases ()) - { - HIR::Expr *kase_expr - = ASTLoweringExpr::translate (match_case.get_expr ().get ()); - - HIR::Expr *kase_guard_expr = nullptr; - if (match_case.get_arm ().has_match_arm_guard ()) - { - kase_guard_expr = ASTLoweringExpr::translate ( - match_case.get_arm ().get_guard_expr ().get ()); - } - - std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns; - for (auto &pattern : match_case.get_arm ().get_patterns ()) - { - HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); - match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); - } - - HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), - std::unique_ptr<HIR::Expr> (kase_guard_expr), - match_case.get_arm ().get_outer_attrs ()); - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - HIR::MatchCase kase (std::move (mapping), std::move (arm), - std::unique_ptr<HIR::Expr> (kase_expr)); - match_arms.push_back (std::move (kase)); - } - - auto crate_num = mappings->get_current_crate (); - Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), - mappings->get_next_hir_id (crate_num), - UNKNOWN_LOCAL_DEFID); - - translated - = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value), - std::move (match_arms), expr.get_inner_attrs (), - expr.get_outer_attrs (), expr.get_locus ()); + translated = ASTLoweringExprWithBlock::translate (&expr, &terminated); } void visit (AST::RangeFromToExpr &expr) override diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index 4a344c9..64c8f36 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -299,6 +299,57 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr) expr.get_outer_attrs ()); } +void +ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr) +{ + HIR::Expr *branch_value + = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ()); + + std::vector<HIR::MatchCase> match_arms; + for (auto &match_case : expr.get_match_cases ()) + { + HIR::Expr *kase_expr + = ASTLoweringExpr::translate (match_case.get_expr ().get ()); + + HIR::Expr *kase_guard_expr = nullptr; + if (match_case.get_arm ().has_match_arm_guard ()) + { + kase_guard_expr = ASTLoweringExpr::translate ( + match_case.get_arm ().get_guard_expr ().get ()); + } + + std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns; + for (auto &pattern : match_case.get_arm ().get_patterns ()) + { + HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ()); + match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn)); + } + + HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), + std::unique_ptr<HIR::Expr> (kase_guard_expr), + match_case.get_arm ().get_outer_attrs ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + HIR::MatchCase kase (std::move (mapping), std::move (arm), + std::unique_ptr<HIR::Expr> (kase_expr)); + match_arms.push_back (std::move (kase)); + } + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value), + std::move (match_arms), expr.get_inner_attrs (), + expr.get_outer_attrs (), expr.get_locus ()); +} + // rust-ast-lower-expr.h void diff --git a/gcc/testsuite/rust/execute/torture/issue-858.rs b/gcc/testsuite/rust/execute/torture/issue-858.rs new file mode 100644 index 0000000..5a43f3e --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/issue-858.rs @@ -0,0 +1,32 @@ +/* { dg-output "Result: 123\n" } */ +extern "C" { + fn printf(s: *const i8, ...); +} + +enum Foo<T> { + A, + B(T), +} + +fn main() -> i32 { + let result = Foo::B(123); + + match result { + Foo::A => unsafe { + let a = "A\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c); + }, + Foo::B(x) => unsafe { + let a = "Result: %i\n\0"; + let b = a as *const str; + let c = b as *const i8; + + printf(c, x); + }, + } + + 0 +} |