On 03/12/2015 11:37 AM, Marek Polacek wrote:
The PR shows that the compiler ICEs whenever it tries to expand an atomic
operation at the file scope.  That happens because it creates temporaries
via create_tmp_var, which also pushes the variable into the current binding,
but that can't work if current_function_decl is NULL.  The fix is I think to
only generate the temporaries during gimplification.  Turned out that the
TARGET_EXPRs are tailor-made for this, so I've used them along with changing
create_tmp_var calls to create_tmp_var_raw that does not push the variable
into the current binding.

But this wasn't enough to handle the following case:
_Atomic int i = 5;
void f (int a[i += 1]) {}
To make it work I had to tweak the artificial labels that build_atomic_assign
creates to not ICE in gimplification.  The comment in store_parm_decls sums
it up.  It uses walk_tree, but I think this will be only rarely exercised in
practice, if ever; I think programs using such a construction are thin on the
ground.

I tried comparing .gimple dumps with/without the patch on

_Atomic int q = 4;
void
f (void)
{
   q += 2;
}

and I see no code changes.

This is not a regression, so not sure if I shouldn't defer this patch to the
next stage1 at this juncture...

Comments?

Bootstrapped/regtested on x86_64-linux.

2015-03-12  Marek Polacek  <pola...@redhat.com>

        PR c/65345
        * c-decl.c (set_labels_context_r): New function.
        (store_parm_decls): Call it via walk_tree_without_duplicates.
        * c-typeck.c (convert_lvalue_to_rvalue): Use create_tmp_var_raw
        instead of create_tmp_var.  Build TARGET_EXPR instead of
        COMPOUND_EXPR.
        (build_atomic_assign): Use create_tmp_var_raw instead of
        create_tmp_var.  Build TARGET_EXPRs instead of MODIFY_EXPR.

        * gcc.dg/pr65345-1.c: New test.
        * gcc.dg/pr65345-2.c: New test.
My inclination is to defer unless it's painfully safe (like your removal of unused functions) or it's a regression of some sorts.

jeff

Reply via email to