Bug 28418 - [4.0/4.1 regression] ICE incrementing compound literal expression
Summary: [4.0/4.1 regression] ICE incrementing compound literal expression
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.2.0
: P2 normal
Target Milestone: 4.0.4
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, monitored
Depends on:
Blocks:
 
Reported: 2006-07-18 10:29 UTC by Volker Reichelt
Modified: 2006-08-26 02:34 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.4.0 4.2.0
Known to fail: 4.0.0 4.1.0
Last reconfirmed: 2006-07-18 10:39:24


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Volker Reichelt 2006-07-18 10:29:20 UTC
The following valid code snippet triggers an ICE since GCC 4.0.0
(only with the C frontend):

========================================
struct A { int i; };

void foo()
{
    ((struct A) { 0 }).i += 1;
}
========================================

bug.c: In function 'foo':
bug.c:5: internal compiler error: in gimple_add_tmp_var, at gimplify.c:720
Please submit a full bug report, [etc.]
Comment 1 Andrew Pinski 2006-07-18 10:33:45 UTC
First off this "((struct A) { 0 })" is not a temporary variable but instead an anonymous C99 variable.
Comment 2 Andrew Pinski 2006-07-18 10:39:24 UTC
Confirmed, we are gimplifying the compound literal expression twice which in turn calls gimple_add_tmp_var twice on the decl.
Comment 3 Fariborz Jahanian 2006-07-24 23:16:09 UTC
gcc generates two separate trees for compound literals in c and c++. As in this test case:

struct S {
        int i,j;
};
void foo (struct S);

int main ()
{
        foo((struct S){1,1});
}


In c it generates compound_literal_expr and in c++ it generates target_expr. But gimplifier treats them differently in the following areas:

1) in routine mostly_copy_tree_v we don;t copy target_expr but we do copy compound_literal_expr. I see the following comment there:

    / * Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
   These nodes model computations that should only be done once.  If we
   were to unshare something like SAVE_EXPR(i++), the gimplification
   process would create wrong code.  */

Shouldn't compound_literal_expr be treated same as target_expr here?

2) gimplify_target_expr can be called more than once on the same target_expr node because first time around its TARGET_EXPR_INITIAL is set to NULL.
    This works as a guard and prevents its temporary to be added to the temporary list more than once (when call is made to gimple_add_tmp_var).

    On the other hand, such a guard does not exist for a compound_literal_expr and when gimple_add_tmp_var is called, it asserts. So, I added check for
    !DECL_SEEN_IN_BIND_EXPR_P (decl) in gimplify_compound_literal_expr before call to gimple_add_tmp_var is made. As in the following diff:

% svn diff c-gimplify.c
Index: c-gimplify.c
===================================================================
--- c-gimplify.c        (revision 116462)
+++ c-gimplify.c        (working copy)
@@ -538,7 +538,7 @@
   /* This decl isn't mentioned in the enclosing block, so add it to the
      list of temps.  FIXME it seems a bit of a kludge to say that
      anonymous artificial vars aren't pushed, but everything else is.  */
-  if (DECL_NAME (decl) == NULL_TREE)
+  if (DECL_NAME (decl) == NULL_TREE && !DECL_SEEN_IN_BIND_EXPR_P (decl))
     gimple_add_tmp_var (decl);

This fixes the problem I am encouterring as well as the test case in this PR.
Comment 4 Andrew Pinski 2006-08-18 03:20:10 UTC
Wait a minute the C front-end produces for this testcase:
  <<< Unknown tree: compound_literal_expr
    struct A D.1524 = {.i=0}; >>>
.i = <<< Unknown tree: compound_literal_expr
    struct A D.1524 = {.i=0}; >>>
.i + 1;


so obviously we are going to gimplify the compound_literal_expr twice.
Comment 5 Andrew Pinski 2006-08-18 03:42:23 UTC
for +=/-= we could use PREINCREMENT_EXPR/PREDECREMENT_EXPR trees but for *=, /=, |=, ^=, we cannot use any of the above.

I wonder if a SAVE_EXPR make this work?
Comment 6 Joseph S. Myers 2006-08-23 11:23:11 UTC
The patch in comment#3 is OK if the testcase is added to gcc.c-torture/compile.  Please post the final patch to gcc-patches.
Comment 7 Joseph S. Myers 2006-08-25 21:14:32 UTC
Subject: Bug 28418

Author: jsm28
Date: Fri Aug 25 21:14:24 2006
New Revision: 116436

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116436
Log:
2006-08-25  Fariborz Jahanian  <fjahanian@apple.com>

	PR c/28418
	* c-gimplify.c (gimplify_compound_literal_expr): Don't add
	variable again if DECL_SEEN_IN_BIND_EXPR_P.

2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>

	* gcc.c-torture/compile/compound-literal-1.c: New test.

Added:
    trunk/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-gimplify.c
    trunk/gcc/testsuite/ChangeLog

Comment 8 Fariborz Jahanian 2006-08-25 21:36:19 UTC
I was about to sub mit the patch. Thank you for this patch.

- Fariborz

> Subject: Bug 28418
> 
> Author: jsm28
> Date: Fri Aug 25 21:14:24 2006
> New Revision: 116436
> 
> URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116436
> Log:
> 2006-08-25  Fariborz Jahanian  <fjahanian@apple.com>
> 
>         PR c/28418
>         * c-gimplify.c (gimplify_compound_literal_expr): Don't add
>         variable again if DECL_SEEN_IN_BIND_EXPR_P.
> 
> 2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>
> 
>         * gcc.c-torture/compile/compound-literal-1.c: New test.
> 
> Added:
>     trunk/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
> Modified:
>     trunk/gcc/ChangeLog
>     trunk/gcc/c-gimplify.c
>     trunk/gcc/testsuite/ChangeLog
> 

Comment 9 Joseph S. Myers 2006-08-25 22:52:47 UTC
Subject: Bug 28418

Author: jsm28
Date: Fri Aug 25 22:52:40 2006
New Revision: 116446

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116446
Log:
2006-08-25  Fariborz Jahanian  <fjahanian@apple.com>

	PR c/28418
	* c-gimplify.c (gimplify_compound_literal_expr): Don't add
	variable again if DECL_SEEN_IN_BIND_EXPR_P.

2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>

	* gcc.c-torture/compile/compound-literal-1.c: New test.

Added:
    branches/gcc-4_1-branch/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
      - copied unchanged from r116436, trunk/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/c-gimplify.c
    branches/gcc-4_1-branch/gcc/testsuite/ChangeLog

Comment 10 Joseph S. Myers 2006-08-26 00:25:51 UTC
Subject: Bug 28418

Author: jsm28
Date: Sat Aug 26 00:24:31 2006
New Revision: 116461

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116461
Log:
2006-08-25  Fariborz Jahanian  <fjahanian@apple.com>

	PR c/28418
	* c-gimplify.c (gimplify_compound_literal_expr): Don't add
	variable again if DECL_SEEN_IN_BIND_EXPR_P.

testsuite:
2006-08-25  Joseph S. Myers  <joseph@codesourcery.com>

	* gcc.c-torture/compile/compound-literal-1.c: New test.

Added:
    branches/gcc-4_0-branch/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
      - copied unchanged from r116436, trunk/gcc/testsuite/gcc.c-torture/compile/compound-literal-1.c
Modified:
    branches/gcc-4_0-branch/gcc/ChangeLog
    branches/gcc-4_0-branch/gcc/c-gimplify.c
    branches/gcc-4_0-branch/gcc/testsuite/ChangeLog

Comment 11 Andrew Pinski 2006-08-26 02:34:54 UTC
Fixed.