aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-08-14 22:22:15 +0000
committerGitHub <noreply@github.com>2021-08-14 22:22:15 +0000
commit52c1cdc9c63baeb090680daf6762c02362f2c6cd (patch)
tree8be58e078de992e2b2743557d747521b27b173ae /gcc
parente53f1acb282a226cd037fd21e587c83f09c2e4af (diff)
parentee3d0b09dc7777cd04587a83f5cfe785101f0dc9 (diff)
downloadgcc-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.h4
-rw-r--r--gcc/testsuite/rust/compile/torture/ifunaryexpr.rs22
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 (); } }
+}