diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-14 22:22:15 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-14 22:22:15 +0000 |
commit | 52c1cdc9c63baeb090680daf6762c02362f2c6cd (patch) | |
tree | 8be58e078de992e2b2743557d747521b27b173ae /gcc | |
parent | e53f1acb282a226cd037fd21e587c83f09c2e4af (diff) | |
parent | ee3d0b09dc7777cd04587a83f5cfe785101f0dc9 (diff) | |
download | gcc-52c1cdc9c63baeb090680daf6762c02362f2c6cd.zip gcc-52c1cdc9c63baeb090680daf6762c02362f2c6cd.tar.gz gcc-52c1cdc9c63baeb090680daf6762c02362f2c6cd.tar.bz2 |
Merge #630
630: parse if expression with unary minus or not expression r=philberty a=dkm
From Mark Wielaard : https://gcc.gnu.org/pipermail/gcc-rust/2021-August/000140.html
> An if conditional expression doesn't need brackets, but that means
> that it doesn't accept struct expressions. Those are not easy to
> distinquish from the block that follows. What isn't immediately clear
> from the grammar is that unary conditions like minus '-' or not '!'
> also shouldn't accept struct expressions (when part of an if
> conditional expression) because those also cannot be easily
> distinquished from the block that follows.
>
> Add a testcase "ifunaryexpr.rs" that shows a couple of contructs that
> should be accepted as if conditional expressions and fix the parser to
> pass the restriction of not accepting struct expressions after a unary
> expression.
Co-authored-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/ifunaryexpr.rs | 22 |
2 files changed, 26 insertions, 0 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 731e0b3..fa6d409 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -12547,6 +12547,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, case MINUS: { // unary minus ParseRestrictions entered_from_unary; entered_from_unary.entered_from_unary = true; + if (!restrictions.can_be_struct_expr) + entered_from_unary.can_be_struct_expr = false; std::unique_ptr<AST::Expr> expr = parse_expr (LBP_UNARY_MINUS, {}, entered_from_unary); @@ -12571,6 +12573,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok, case EXCLAM: { // logical or bitwise not ParseRestrictions entered_from_unary; entered_from_unary.entered_from_unary = true; + if (!restrictions.can_be_struct_expr) + entered_from_unary.can_be_struct_expr = false; std::unique_ptr<AST::Expr> expr = parse_expr (LBP_UNARY_EXCLAM, {}, entered_from_unary); diff --git a/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs b/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs new file mode 100644 index 0000000..8f0bb87 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/ifunaryexpr.rs @@ -0,0 +1,22 @@ +extern "C" +{ + pub fn abort (); +} + +struct B { b: bool } + +pub fn main () +{ + let n = 1; + if 0 > -n { } else { unsafe { abort (); } } + + let b = true; + if !b { unsafe { abort (); } } + if !!b { } else { unsafe { abort (); } } + + let bb = B { b: false }; + + if !bb.b && !b { unsafe { abort (); } } + + if (B { b: true }).b { } else { unsafe { abort (); } } +} |