https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65345

--- Comment #5 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
(In reply to jos...@codesourcery.com from comment #4)
> Or e.g.
> 
> _Atomic int i = 5;
> int j = sizeof (i + 1);
> 
> which is valid code not involving _Generic.  And, similarly:
> 
> _Atomic int i = 5;
> int j = sizeof (i = 0);
> 
> or
> 
> _Atomic int i = 5;
> int j = sizeof (++i);
> 
> or
> 
> _Atomic int i = 5;
> int j = sizeof (i--);
> 
> This at first suggests (but see below) that the special-case handling of 
> atomics on lvalue-to-rvalue conversion, and on assignment / increment / 
> decrement / any other cases where creation of temporaries is involved, 
> should be disabled when at file scope - either the expression in question 
> is in a context such as sizeof or _Generic where its side effects do not 
> occur so the special handling is not needed, or an error will occur for 
> the expression being non-constant even without the special handling.

Yeah, I had an idea of using create_tmp_var_raw that doesn't push the variable
into function's local vars vector.  My thinking was that we don't need such
variables to survive into ME anyway in the valid cases, and in invalid cases,
the FE just rejects the code...

--- gcc/c/c-typeck.c
+++ gcc/c/c-typeck.c
@@ -2039,7 +2039,12 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr
exp,
       /* Remove the qualifiers for the rest of the expressions and 
         create the VAL temp variable to hold the RHS.  */  
       nonatomic_type = build_qualified_type (expr_type, TYPE_UNQUALIFIED);
-      tmp = create_tmp_var (nonatomic_type);
+      /* If we are outside a function, avoid pushing the variable into the
+        current binding.  */
+      if (current_function_decl)
+        tmp = create_tmp_var (nonatomic_type);
+      else
+        tmp = create_tmp_var_raw (nonatomic_type);
       tmp_addr = build_unary_op (loc, ADDR_EXPR, tmp, 0); 
       TREE_ADDRESSABLE (tmp) = 1;
       TREE_NO_WARNING (tmp) = 1;


> Much the same applies at function prototype scope, e.g.:
> 
> _Atomic int i = 5;
> void f (int a[i + 1]);
> 
> (where [i + 1] means the same as [*]).  But in the case of
> 
> _Atomic int i = 5;
> void f (int a[i = 1]) {}
> 
> you have a valid program, where the atomic assignment must be executed on 
> function entry (see the pending_sizes handling in c-decl.c).  So to handle 
> such cases, maybe the special handling of atomics needs to be partly 
> deferred, so that parsing "i = 1" generates some tree for atomic 
> assignment and the temporaries only get added at gimplification time.

... but my patch wouldn't handle this case.  Oh well.

Reply via email to