From 73c22f831f335441714df9cc1ef88b627e991f6a Mon Sep 17 00:00:00 2001
From: Michael Matz <matz@suse.de>
Date: Fri, 1 Jul 2022 17:18:41 +0200
Subject: [PATCH] Fix fallthrough of non-entered stmt expressions

commit ec5d94291 made is to that the nocode_wanted state from
inside a statement expression is retained after it.  That is wrong
if the statement expression can't be entered to start with.  In the
latter case the state from before the stmt-expr is the one we need.
---
 tccgen.c                         |  9 ++++++---
 tests/tests2/87_dead_code.c      | 10 ++++++++++
 tests/tests2/87_dead_code.expect |  1 +
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/tccgen.c b/tccgen.c
index 93e4b346..c170ff3f 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5394,9 +5394,12 @@ ST_FUNC void unary(void)
 	       outside, so any reactivation of code emission (from labels
 	       or loop heads) can be disabled again after the end of it. */
             block(1);
-            /* or'ing to keep however possible CODE_OFF() from e.g. "return 0;"
-               in the statement expression */
-	    nocode_wanted |= saved_nocode_wanted;
+            /* If the statement expr can be entered, then we retain the current
+               nocode_wanted state (from e.g. a 'return 0;' in the stmt-expr).
+               If it can't be entered then the state is that from before the
+               statement expression.  */
+            if (saved_nocode_wanted)
+              nocode_wanted = saved_nocode_wanted;
             skip(')');
         } else {
             gexpr();
diff --git a/tests/tests2/87_dead_code.c b/tests/tests2/87_dead_code.c
index 0d5a64ce..369f4bab 100644
--- a/tests/tests2/87_dead_code.c
+++ b/tests/tests2/87_dead_code.c
@@ -56,6 +56,15 @@ static void dowhile(void)
   } while (check());
 }
 
+static void nondead_after_dead_return(void)
+{
+  /* This statement expr is not entered, and hence that fact that it
+     doesn't fall-through should not influence the surrounding code.  */
+  0 && ({ return; 0;});
+  printf ("nondead works\n");
+  return;
+}
+
 int main (void)
 {
   int i = 1;
@@ -150,6 +159,7 @@ enterloop3:
   }
 
   dowhile();
+  nondead_after_dead_return();
 
   return 0;
 }
diff --git a/tests/tests2/87_dead_code.expect b/tests/tests2/87_dead_code.expect
index a8c93bd0..781ff518 100644
--- a/tests/tests2/87_dead_code.expect
+++ b/tests/tests2/87_dead_code.expect
@@ -21,3 +21,4 @@ check 1
 g=2
 check 2
 g=3
+nondead works