public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var
@ 2005-02-20 17:37 falk at debian dot org
  2005-02-20 17:52 ` [Bug c++/20103] " falk at debian dot org
                   ` (45 more replies)
  0 siblings, 46 replies; 55+ messages in thread
From: falk at debian dot org @ 2005-02-20 17:37 UTC (permalink / raw)
  To: gcc-bugs

GNU C++ version 4.0.0 20050219 (experimental) (alphaev68-unknown-linux-gnu)
bug.cc: In function 'void g()':
bug.cc:28: internal compiler error: in create_tmp_var, at gimplify.c:368
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

Works fine with 3.4. No options required.

-- 
           Summary: [4.0 regression] ICE in create_tmp_var
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: falk at debian dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: alphaev68-unknown-linux-gnu
  GCC host triplet: alphaev68-unknown-linux-gnu
GCC target triplet: alphaev68-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
@ 2005-02-20 17:52 ` falk at debian dot org
  2005-02-20 19:02 ` pinskia at gcc dot gnu dot org
                   ` (44 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: falk at debian dot org @ 2005-02-20 17:52 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From falk at debian dot org  2005-02-20 11:13 -------
Created an attachment (id=8238)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=8238&action=view)
test case (compile with no options)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
  2005-02-20 17:52 ` [Bug c++/20103] " falk at debian dot org
@ 2005-02-20 19:02 ` pinskia at gcc dot gnu dot org
  2005-02-20 19:25 ` pinskia at gcc dot gnu dot org
                   ` (43 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-02-20 19:02 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|---                         |4.0.0


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
  2005-02-20 17:52 ` [Bug c++/20103] " falk at debian dot org
  2005-02-20 19:02 ` pinskia at gcc dot gnu dot org
@ 2005-02-20 19:25 ` pinskia at gcc dot gnu dot org
  2005-02-20 19:27 ` pinskia at gcc dot gnu dot org
                   ` (42 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-02-20 19:25 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-02-20 13:48 -------
Target independent.
Confirmed reduced a little further (removed the templates) testcase:
struct mpz_class
{
  mpz_class (const mpz_class &);
  mpz_class();
};
inline mpz_class operator*(int, const mpz_class &expr) { }
struct state { mpz_class q; };
void f(state);
void g() {
    mpz_class y;
    f((state) { -10 * y });
}


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
  GCC build triplet|alphaev68-unknown-linux-gnu |
   GCC host triplet|alphaev68-unknown-linux-gnu |
 GCC target triplet|alphaev68-unknown-linux-gnu |
   Last reconfirmed|0000-00-00 00:00:00         |2005-02-20 13:48:10
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (2 preceding siblings ...)
  2005-02-20 19:25 ` pinskia at gcc dot gnu dot org
@ 2005-02-20 19:27 ` pinskia at gcc dot gnu dot org
  2005-02-21 21:49 ` pinskia at gcc dot gnu dot org
                   ` (41 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-02-20 19:27 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-02-20 13:52 -------
This has been failing since 20040909.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (3 preceding siblings ...)
  2005-02-20 19:27 ` pinskia at gcc dot gnu dot org
@ 2005-02-21 21:49 ` pinskia at gcc dot gnu dot org
  2005-02-23 11:10 ` [Bug c++/20103] [4.0 regression] ICE in create_tmp_var with C99 style struct initializer pinskia at gcc dot gnu dot org
                   ` (40 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-02-21 21:49 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-02-21 15:45 -------
Why is the front-end producing a CONSTRUTOR when the variable needs to constructed.

The front-end should have produced its own temporary variable instead of producing a CONSTRUCTOR.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (4 preceding siblings ...)
  2005-02-21 21:49 ` pinskia at gcc dot gnu dot org
@ 2005-02-23 11:10 ` pinskia at gcc dot gnu dot org
  2005-03-02 13:48 ` [Bug c++/20103] [4.0/4.1 " reichelt at gcc dot gnu dot org
                   ` (39 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-02-23 11:10 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2005-02-23 00:01 -------
: Search converges between 2004-05-11-trunk (#454) and 2004-05-14-trunk (#455).

This has been failing on the tree-ssa branch since at least 2003-05-30.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (5 preceding siblings ...)
  2005-02-23 11:10 ` [Bug c++/20103] [4.0 regression] ICE in create_tmp_var with C99 style struct initializer pinskia at gcc dot gnu dot org
@ 2005-03-02 13:48 ` reichelt at gcc dot gnu dot org
  2005-03-03  7:01 ` aoliva at gcc dot gnu dot org
                   ` (38 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: reichelt at gcc dot gnu dot org @ 2005-03-02 13:48 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From reichelt at gcc dot gnu dot org  2005-03-02 13:48 -------
Even shorter testcase:

======================
struct A
{
    A(const A&);
};

struct B
{
    A a;
};

void foo(B);

void bar(A &x)
{
    foo((B){x});
}
======================


-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |reichelt at gcc dot gnu dot
                   |                            |org
           Keywords|                            |monitored


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (6 preceding siblings ...)
  2005-03-02 13:48 ` [Bug c++/20103] [4.0/4.1 " reichelt at gcc dot gnu dot org
@ 2005-03-03  7:01 ` aoliva at gcc dot gnu dot org
  2005-03-03  7:42 ` aoliva at redhat dot com
                   ` (37 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at gcc dot gnu dot org @ 2005-03-03  7:01 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
         AssignedTo|unassigned at gcc dot gnu   |aoliva at gcc dot gnu dot
                   |dot org                     |org
             Status|NEW                         |ASSIGNED
   Last reconfirmed|2005-02-20 13:48:10         |2005-03-03 07:01:35
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (7 preceding siblings ...)
  2005-03-03  7:01 ` aoliva at gcc dot gnu dot org
@ 2005-03-03  7:42 ` aoliva at redhat dot com
  2005-03-04 23:22 ` aoliva at redhat dot com
                   ` (36 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-03  7:42 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-03 07:42 -------
Subject: [PR c++/20103] failure to gimplify constructors for addressable types

In the reduced testcase from the bug report, included in the patch
file below, we fail to gimplify the CONSTRUCTOR created for the
compound-literal expression.  When we attempt to create_tmp_var to
hold the B-typed value, it fails because B is addressable.

This patch introduces an alternate entry point for create_tmp_var that
accepts addressable types, and uses that in the relevant caller when
the value is a CONSTRUCTOR.

Bootstrapping on x86_64-linux-gnu, after successful C++ regression
testing on make all.  Ok to install if full bootstrap and regression
testing completes?

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.113
diff -u -p -r2.113 gimplify.c
--- gcc/gimplify.c 18 Feb 2005 19:35:37 -0000 2.113
+++ gcc/gimplify.c 3 Mar 2005 07:40:02 -0000
@@ -356,15 +356,13 @@ create_tmp_var_raw (tree type, const cha
    only from gimplification or optimization, at which point the creation of
    certain types are bugs.  */
 
-tree
-create_tmp_var (tree type, const char *prefix)
+static tree
+create_tmp_var_maybe_addressable (tree type, const char *prefix)
 {
   tree tmp_var;
 
-  /* We don't allow types that are addressable (meaning we can't make copies),
-     incomplete, or of variable size.  */
-  gcc_assert (!TREE_ADDRESSABLE (type)
-	      && COMPLETE_TYPE_P (type)
+  /* We don't allow types that are incomplete, or of variable size.  */
+  gcc_assert (COMPLETE_TYPE_P (type)
 	      && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST);
 
   tmp_var = create_tmp_var_raw (type, prefix);
@@ -372,6 +370,18 @@ create_tmp_var (tree type, const char *p
   return tmp_var;
 }
 
+
+/* Like create_tmp_var_maybe_addressable, but make sure the given type
+   is NOT addressable.  */
+
+tree
+create_tmp_var (tree type, const char *prefix)
+{
+  gcc_assert (!TREE_ADDRESSABLE (type));
+
+  return create_tmp_var_maybe_addressable (type, prefix);
+}
+
 /*  Given a tree, try to return a useful variable name that we can use
     to prefix a temporary that is being assigned the value of the tree.
     I.E. given  <temp> = &A, return A.  */
@@ -404,6 +414,9 @@ get_name (tree t)
 static inline tree
 create_tmp_from_val (tree val)
 {
+  if (TREE_CODE (val) == CONSTRUCTOR)
+    return create_tmp_var_maybe_addressable (TREE_TYPE (val), get_name (val));
+
   return create_tmp_var (TREE_TYPE (val), get_name (val));
 }
 
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.dg/tree-ssa/pr20103.C: New.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 3 Mar 2005 07:40:16 -0000
@@ -0,0 +1,25 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+
+void bar(A &x)
+{
+    foo((B){x});
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (8 preceding siblings ...)
  2005-03-03  7:42 ` aoliva at redhat dot com
@ 2005-03-04 23:22 ` aoliva at redhat dot com
  2005-03-04 23:30 ` mark at codesourcery dot com
                   ` (35 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-04 23:22 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-04 23:22 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  3, 2005, Andrew Pinski <pinskia@physics.uc.edu> wrote:

> I think this is the wrong approach.  The front-end and not
> the gimplifier should be creating these temporaries, I mentioned
> this already in the bug.

How about this?

I tried with the TARGET_EXPR by itself, but it failed to be recognized
as an lvalue, so I introduced the compound expr.

Testing on x86_64-linux-gnu.  Ok to install if it passes?

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* semantics.c (finish_compound_literal): Ensure the result is an
	lvalue, by creating a compound-expr with a target-expr and its
	decl.

Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463
diff -u -p -r1.463 semantics.c
--- gcc/cp/semantics.c 23 Feb 2005 05:30:48 -0000 1.463
+++ gcc/cp/semantics.c 4 Mar 2005 23:17:50 -0000
@@ -1996,7 +1996,11 @@ finish_compound_literal (tree type, tree
 	complete_array_type (type, compound_literal, 1);
     }
 
-  return compound_literal;
+  /* A compound-literal is an lvalue in C, so make it so in C++ as
+     well.  */
+  compound_literal = get_target_expr (compound_literal);
+  return build2 (COMPOUND_EXPR, TREE_TYPE (compound_literal),
+		 compound_literal, TARGET_EXPR_SLOT (compound_literal));
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.dg/tree-ssa/pr20103.C: New.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 4 Mar 2005 23:18:05 -0000
@@ -0,0 +1,34 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's taken as an lvalue.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&);
+void bap(B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x});
+    bap (&(B){x});
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x});
+    bap (&(B&)(B){x});
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (9 preceding siblings ...)
  2005-03-04 23:22 ` aoliva at redhat dot com
@ 2005-03-04 23:30 ` mark at codesourcery dot com
  2005-03-05 11:41 ` giovannibajo at libero dot it
                   ` (34 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-04 23:30 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-04 23:29 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:
> On Mar  3, 2005, Andrew Pinski <pinskia@physics.uc.edu> wrote:
> 
> 
>>I think this is the wrong approach.  The front-end and not
>>the gimplifier should be creating these temporaries, I mentioned
>>this already in the bug.
> 
> 
> How about this?
> 
> I tried with the TARGET_EXPR by itself, but it failed to be recognized
> as an lvalue, so I introduced the compound expr.

Introducing a TARGET_EXPR makes sense to me.

> Testing on x86_64-linux-gnu.  Ok to install if it passes?

> +    foo ((B){x});

I don't think (B){x} should be an lvalue, C99 notwithstanding.  B(3) is 
not be an lavalue; I don't see why "(B){x}" should be.  Conceptually, 
the compound-literal syntax is just a way of invoking an imaginary 
constuctor that has an argument corresponding to each non-static data 
member.

Has there been any discussion of this in the ISO committee?  Or prior 
are in other compilers?  Including previous versions of G++?

(These are not rhetorical questions; I really don't know.)



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (10 preceding siblings ...)
  2005-03-04 23:30 ` mark at codesourcery dot com
@ 2005-03-05 11:41 ` giovannibajo at libero dot it
  2005-03-05 12:16 ` joseph at codesourcery dot com
                   ` (33 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: giovannibajo at libero dot it @ 2005-03-05 11:41 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From giovannibajo at libero dot it  2005-03-05 11:41 -------
It would probably also help to know why compound literals are lvalues in C99. 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jsm28 at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (11 preceding siblings ...)
  2005-03-05 11:41 ` giovannibajo at libero dot it
@ 2005-03-05 12:16 ` joseph at codesourcery dot com
  2005-03-05 13:37 ` aoliva at redhat dot com
                   ` (32 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: joseph at codesourcery dot com @ 2005-03-05 12:16 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From joseph at codesourcery dot com  2005-03-05 12:15 -------
Subject: Re:  [4.0/4.1 regression] ICE in create_tmp_var with
 C99 style struct initializer

On Sat, 5 Mar 2005, giovannibajo at libero dot it wrote:

> It would probably also help to know why compound literals are lvalues in C99. 

A compound literal is an unnamed variable (with automatic storage duration 
associated with the enclosing block if within a function).  That is,

    (TYPE){ init }

effectively declares

    TYPE var = { init };

with the initialization done when (each time) the literal is executed and 
the literal then acting like var was named in the expression in which the 
literal occurs.  I'd guess this was the most natural model for permitting 
in C

    foo((int[]){ a, b, c, d, e });

with the array object living into and being usable in foo.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (12 preceding siblings ...)
  2005-03-05 12:16 ` joseph at codesourcery dot com
@ 2005-03-05 13:37 ` aoliva at redhat dot com
  2005-03-05 14:03 ` aoliva at redhat dot com
                   ` (31 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-05 13:37 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-05 13:36 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  4, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

>> +    foo ((B){x});

> I don't think (B){x} should be an lvalue, C99 notwithstanding.  B(3)
> is not be an lavalue; I don't see why "(B){x}" should be.

Works for me.  We can always extend it later, should the ISO C++
committee make a decision different from ours.

Patch will follow hopefully later today.

> Has there been any discussion of this in the ISO committee?  Or prior
> are in other compilers?  Including previous versions of G++?

Not that I know.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (13 preceding siblings ...)
  2005-03-05 13:37 ` aoliva at redhat dot com
@ 2005-03-05 14:03 ` aoliva at redhat dot com
  2005-03-05 21:47 ` mark at codesourcery dot com
                   ` (30 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-05 14:03 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-05 14:03 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  5, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar  4, 2005, Mark Mitchell <mark@codesourcery.com> wrote:
>>> +    foo ((B){x});

>> I don't think (B){x} should be an lvalue, C99 notwithstanding.  B(3)
>> is not be an lavalue; I don't see why "(B){x}" should be.

> Works for me.  We can always extend it later, should the ISO C++
> committee make a decision different from ours.

> Patch will follow hopefully later today.

For small values of later :-)

Testing now.  I was a bit surprised that the casts to (const B&)
weren't reported as faulty, but didn't check the standard on it.  Ok
to install if testing passes?

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* semantics.c (finish_compound_literal): Wrap it in a
	target_expr.

Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463
diff -u -p -r1.463 semantics.c
--- gcc/cp/semantics.c 23 Feb 2005 05:30:48 -0000 1.463
+++ gcc/cp/semantics.c 5 Mar 2005 13:56:17 -0000
@@ -1996,7 +1996,9 @@ finish_compound_literal (tree type, tree
 	complete_array_type (type, compound_literal, 1);
     }
 
-  return compound_literal;
+  /* A compound-literal is an lvalue in C, but is it going to be in
+     ISO C++?  Assume it's an rvalue for now.  */
+  return get_target_expr (compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.dg/tree-ssa/pr20103.C: New.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 5 Mar 2005 13:56:31 -0000
@@ -0,0 +1,41 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (14 preceding siblings ...)
  2005-03-05 14:03 ` aoliva at redhat dot com
@ 2005-03-05 21:47 ` mark at codesourcery dot com
  2005-03-06  7:30 ` aoliva at redhat dot com
                   ` (29 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-05 21:47 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-05 21:47 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:

> Testing now.  I was a bit surprised that the casts to (const B&)
> weren't reported as faulty, but didn't check the standard on it.  

I'd have to check the rules -- but I'm sure it's not a problem with your 
patch.  Either its correct, or an already-present bug.

 > Ok
> to install if testing passes?

Yes.

Thanks!



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (15 preceding siblings ...)
  2005-03-05 21:47 ` mark at codesourcery dot com
@ 2005-03-06  7:30 ` aoliva at redhat dot com
  2005-03-06 18:02 ` mark at codesourcery dot com
                   ` (28 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-06  7:30 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-06 07:29 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  5, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Alexandre Oliva wrote:
>> Testing now.  I was a bit surprised that the casts to (const B&)
>> weren't reported as faulty, but didn't check the standard on it.

> I'd have to check the rules -- but I'm sure it's not a problem with
> your patch.  Either its correct, or an already-present bug.

>> Ok
>> to install if testing passes?

> Yes.

Unfortunately, g++.dg/template/ctor1.C and g++.dg/template/complit1.C
regressed.  As it turned out, complit1.C was in error, and had to be
adjusted to match g++.dg/ext/complit1.C, since the only significant
difference between them was that one of them had the compound-literal
within a ctor of a template class.

ctor1.C, however, exposed a failure to handle TARGET_EXPRs while
instantiating templates.  So I extended the tsubst machinery to do it,
and now ctor1.C passes again.

I also noticed that the patch fixes g++.old-deja/g++.oliva/expr2.C,
yay!

Here's the latest version of the patch, that so far passed make -C gcc
all check-g++.  Full bootstrap and regtest on x86_64-linux-gnu still
pending.  Ok to install if it passes?

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* semantics.c (finish_compound_literal): Wrap it in a
	target_expr.
	* pt.c (tsubst_copy_and_build): Handle TARGET_EXPR.

Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463
diff -u -p -r1.463 semantics.c
--- gcc/cp/semantics.c 23 Feb 2005 05:30:48 -0000 1.463
+++ gcc/cp/semantics.c 6 Mar 2005 07:12:11 -0000
@@ -1996,7 +1996,9 @@ finish_compound_literal (tree type, tree
 	complete_array_type (type, compound_literal, 1);
     }
 
-  return compound_literal;
+  /* A compound-literal is an lvalue in C, but is it going to be
+     in ISO C++?  Assume it's an rvalue for now.  */
+  return get_target_expr (compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.978
diff -u -p -r1.978 pt.c
--- gcc/cp/pt.c 21 Feb 2005 23:12:26 -0000 1.978
+++ gcc/cp/pt.c 6 Mar 2005 07:12:19 -0000
@@ -8744,6 +8744,26 @@ tsubst_copy_and_build (tree t, 
       return build_throw
 	(RECUR (TREE_OPERAND (t, 0)));
 
+    case TARGET_EXPR:
+      {
+	tree r = tsubst_copy (t, args, complain, in_decl);
+
+	TREE_TYPE (r) = RECUR (TREE_TYPE (t));
+	TARGET_EXPR_SLOT (r) = RECUR (TARGET_EXPR_SLOT (t));
+	TARGET_EXPR_INITIAL (r) = RECUR (TARGET_EXPR_INITIAL (t));
+	TARGET_EXPR_CLEANUP (r) = RECUR (TARGET_EXPR_CLEANUP (t));
+
+	if (TREE_TYPE (TARGET_EXPR_SLOT (t))
+	    == TREE_TYPE (TARGET_EXPR_INITIAL (t)))
+	  TREE_TYPE (TARGET_EXPR_SLOT (r)) =
+	    TREE_TYPE (TARGET_EXPR_INITIAL (r));
+
+	if (TREE_TYPE (t) == TREE_TYPE (TARGET_EXPR_SLOT (t)))
+	  TREE_TYPE (r) = TREE_TYPE (TARGET_EXPR_SLOT (r));
+
+	return r;
+      }
+
     case CONSTRUCTOR:
       {
 	tree r;
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* g++.dg/tree-ssa/pr20103.C: New.
	* g++.dg/template/complit1.C: Expect error like ext/complit1.C.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 6 Mar 2005 07:12:35 -0000
@@ -0,0 +1,59 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}
+
+template <typename T, typename U>
+void baz(T &x)
+{
+    foo ((U){x});
+    bar ((U){x}); // { dg-error "non-const reference" }
+    bac ((U){x});
+    bap (&(U){x}); // { dg-error "address of temporary" }
+
+    foo ((const U&)(U){x});
+    bar ((U&)(U){x}); // { dg-error "invalid cast" }
+    bac ((const U&)(U){x});
+    bap (&(const U&)(U){x});
+}
+
+void bazT(A &x) {
+  baz<A,B>(x);
+}
Index: gcc/testsuite/g++.dg/template/complit1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/complit1.C,v
retrieving revision 1.3
diff -u -p -r1.3 complit1.C
--- gcc/testsuite/g++.dg/template/complit1.C 28 Dec 2002 07:48:08 -0000 1.3
+++ gcc/testsuite/g++.dg/template/complit1.C 6 Mar 2005 07:12:35 -0000
@@ -6,6 +6,6 @@ template <int D> struct C {
 };
 
 template<int D>
-C<D>::C() : d((int[]){1,2,3}) {}
+C<D>::C() : d((int[]){1,2,3}) {}  // { dg-error "assignment of arrays" }
 
-template class C<1>;
+template class C<1>; // { dg-error "instantiated from" }
Index: gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* expr2.C: Fixed.

Index: gcc/testsuite/g++.old-deja/g++.oliva/expr2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.oliva/expr2.C,v
retrieving revision 1.5
diff -u -p -r1.5 expr2.C
--- gcc/testsuite/g++.old-deja/g++.oliva/expr2.C 1 May 2003 02:02:47 -0000 1.5
+++ gcc/testsuite/g++.old-deja/g++.oliva/expr2.C 6 Mar 2005 07:12:35 -0000
@@ -1,4 +1,4 @@
-// { dg-do run { xfail *-*-* } }
+// { dg-do run }
 
 // Copyright (C) 2000 Free Software Foundation
 

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (16 preceding siblings ...)
  2005-03-06  7:30 ` aoliva at redhat dot com
@ 2005-03-06 18:02 ` mark at codesourcery dot com
  2005-03-07  3:26 ` aoliva at redhat dot com
                   ` (27 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-06 18:02 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-06 18:02 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:

> +    case TARGET_EXPR:
> +      {
> +	tree r = tsubst_copy (t, args, complain, in_decl);
> +
> +	TREE_TYPE (r) = RECUR (TREE_TYPE (t));
> +	TARGET_EXPR_SLOT (r) = RECUR (TARGET_EXPR_SLOT (t));
> +	TARGET_EXPR_INITIAL (r) = RECUR (TARGET_EXPR_INITIAL (t));
> +	TARGET_EXPR_CLEANUP (r) = RECUR (TARGET_EXPR_CLEANUP (t));
> +
> +	if (TREE_TYPE (TARGET_EXPR_SLOT (t))
> +	    == TREE_TYPE (TARGET_EXPR_INITIAL (t)))
> +	  TREE_TYPE (TARGET_EXPR_SLOT (r)) =
> +	    TREE_TYPE (TARGET_EXPR_INITIAL (r));
> +
> +	if (TREE_TYPE (t) == TREE_TYPE (TARGET_EXPR_SLOT (t)))
> +	  TREE_TYPE (r) = TREE_TYPE (TARGET_EXPR_SLOT (r));
> +
> +	return r;

This doesn't look quite right.  First, we're trying to get rid of 
tsubst_copy; we should not add new calls.  You should do the RECURs 
here, and then build up the new node.  And, the manipulations of 
TREE_TYPE don't make sense: (a) using "==" to compare types is almost 
always wrong, and (b) the RECURs should already maintain the invariant 
you're trying to maintain.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (17 preceding siblings ...)
  2005-03-06 18:02 ` mark at codesourcery dot com
@ 2005-03-07  3:26 ` aoliva at redhat dot com
  2005-03-07  4:44 ` mark at codesourcery dot com
                   ` (26 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-07  3:26 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-07 03:26 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  6, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Alexandre Oliva wrote:
>> +    case TARGET_EXPR:
>> +      {
>> +	tree r = tsubst_copy (t, args, complain, in_decl);
>> +
>> +	TREE_TYPE (r) = RECUR (TREE_TYPE (t));
>> +	TARGET_EXPR_SLOT (r) = RECUR (TARGET_EXPR_SLOT (t));
>> +	TARGET_EXPR_INITIAL (r) = RECUR (TARGET_EXPR_INITIAL (t));
>> +	TARGET_EXPR_CLEANUP (r) = RECUR (TARGET_EXPR_CLEANUP (t));
>> +
>> +	if (TREE_TYPE (TARGET_EXPR_SLOT (t))
>> +	    == TREE_TYPE (TARGET_EXPR_INITIAL (t)))
>> +	  TREE_TYPE (TARGET_EXPR_SLOT (r)) =
>> +	    TREE_TYPE (TARGET_EXPR_INITIAL (r));
>> +
>> +	if (TREE_TYPE (t) == TREE_TYPE (TARGET_EXPR_SLOT (t)))
>> +	  TREE_TYPE (r) = TREE_TYPE (TARGET_EXPR_SLOT (r));
>> +
>> +	return r;

> This doesn't look quite right.  First, we're trying to get rid of
> tsubst_copy; we should not add new calls.  You should do the RECURs
> here, and then build up the new node.

I'd have to use build3 (TARGET_EXPR...) or introduce a new call to
create a target_expr with given slot, initial and cleanup, because
AFAICT there isn't any that takes a cleanup.

> And, the manipulations of TREE_TYPE don't make sense: (a) using "=="
> to compare types is almost always wrong,

It's right in the very case I care about, see below.

> and (b) the RECURs should already maintain the invariant you're
> trying to maintain.

They don't, and they can't without this piece of code.  When we tsubst
INITIAL, an incomplete array type (T[]), that had been used as the
type of the slot and the target_expr itself in
finish_compound_literal(), called while processing a template,
digest_init() (or something else; I no longer remember exactly)
completes the array type with the number of entries in the INITIAL
CONSTRUCTOR.  So what I'm doing here is propagating the completed type
to the SLOT and the TARGET_EXPR itself, otherwise their types would
remain incomplete, and errors would ensue.  This ensures that we get
the same result as that of finish_compound_literal() when not
compiling a template.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (18 preceding siblings ...)
  2005-03-07  3:26 ` aoliva at redhat dot com
@ 2005-03-07  4:44 ` mark at codesourcery dot com
  2005-03-07  8:51 ` giovannibajo at libero dot it
                   ` (25 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-07  4:44 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-07 04:44 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:
>>This doesn't look quite right.  First, we're trying to get rid of
>>tsubst_copy; we should not add new calls.  You should do the RECURs
>>here, and then build up the new node.
> 
> 
> I'd have to use build3 (TARGET_EXPR...) or introduce a new call to
> create a target_expr with given slot, initial and cleanup, because
> AFAICT there isn't any that takes a cleanup.

Yes, you should use build3.

> They don't, and they can't without this piece of code.  When we tsubst
> INITIAL, an incomplete array type (T[]), that had been used as the
> type of the slot and the target_expr itself in
> finish_compound_literal(), called while processing a template,
> digest_init() (or something else; I no longer remember exactly)
> completes the array type with the number of entries in the INITIAL
> CONSTRUCTOR.  

Then you should tsubst the INITIAL first, and unconditionally copy the 
type to the TARGET_EXPR when you use build3.  Or, even better, call the 
same functions in semantics.c that the parser would call if not in a 
template.  In other words, call finish_compound_literal again, from 
pt.c.  That's the overall design: we try to reuse the same semantic 
routines again at template instantiation time.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (19 preceding siblings ...)
  2005-03-07  4:44 ` mark at codesourcery dot com
@ 2005-03-07  8:51 ` giovannibajo at libero dot it
  2005-03-07 14:44 ` aoliva at redhat dot com
                   ` (24 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: giovannibajo at libero dot it @ 2005-03-07  8:51 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From giovannibajo at libero dot it  2005-03-07 08:51 -------
(In reply to comment #15)

> +    case TARGET_EXPR:
> +      {
> +	tree r = tsubst_copy (t, args, complain, in_decl);
> +
> +	TREE_TYPE (r) = RECUR (TREE_TYPE (t));
> +	TARGET_EXPR_SLOT (r) = RECUR (TARGET_EXPR_SLOT (t));
> +	TARGET_EXPR_INITIAL (r) = RECUR (TARGET_EXPR_INITIAL (t));
> +	TARGET_EXPR_CLEANUP (r) = RECUR (TARGET_EXPR_CLEANUP (t));
> +
> +	if (TREE_TYPE (TARGET_EXPR_SLOT (t))
> +	    == TREE_TYPE (TARGET_EXPR_INITIAL (t)))
> +	  TREE_TYPE (TARGET_EXPR_SLOT (r)) =
> +	    TREE_TYPE (TARGET_EXPR_INITIAL (r));
> +
> +	if (TREE_TYPE (t) == TREE_TYPE (TARGET_EXPR_SLOT (t)))
> +	  TREE_TYPE (r) = TREE_TYPE (TARGET_EXPR_SLOT (r));
> +
> +	return r;
> +      }
> +

Can you add a comment that TARGET_EXPR is being used to represent C99 compound 
literals?


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (20 preceding siblings ...)
  2005-03-07  8:51 ` giovannibajo at libero dot it
@ 2005-03-07 14:44 ` aoliva at redhat dot com
  2005-03-07 16:05 ` mark at codesourcery dot com
                   ` (23 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-07 14:44 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-07 14:44 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Alexandre Oliva wrote:
>>> This doesn't look quite right.  First, we're trying to get rid of
>>> tsubst_copy; we should not add new calls.  You should do the RECURs
>>> here, and then build up the new node.
>> I'd have to use build3 (TARGET_EXPR...) or introduce a new call to
>> create a target_expr with given slot, initial and cleanup, because
>> AFAICT there isn't any that takes a cleanup.

> Yes, you should use build3.

Ok.

>> They don't, and they can't without this piece of code.  When we tsubst
>> INITIAL, an incomplete array type (T[]), that had been used as the
>> type of the slot and the target_expr itself in
>> finish_compound_literal(), called while processing a template,
>> digest_init() (or something else; I no longer remember exactly)
>> completes the array type with the number of entries in the INITIAL
>> CONSTRUCTOR.

> Then you should tsubst the INITIAL first, and unconditionally copy the
> type to the TARGET_EXPR when you use build3.

But what if the TARGET_EXPR had been created for different purposes,
and did have a different type than that of the initializer?  Say, a
Base& being bound to a Derived TARGET_EXPR?  That's why I'm performing
the tests the way I am.

> Or, even better, call
> the same functions in semantics.c that the parser would call if not in
> a template.  In other words, call finish_compound_literal again, from
> pt.c.  That's the overall design: we try to reuse the same semantic
> routines again at template instantiation time.

Yeah, I know we'd like to do that, but we can't.  At that point we
have no clue what that TARGET_EXPR or the CONSTRUCTOR in its initial
came from.  We'd have to create a new tree node type for compound
literals to be able to call finish_compound_literal at that point.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (21 preceding siblings ...)
  2005-03-07 14:44 ` aoliva at redhat dot com
@ 2005-03-07 16:05 ` mark at codesourcery dot com
  2005-03-07 17:05 ` aoliva at redhat dot com
                   ` (22 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-07 16:05 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-07 16:05 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:

>>Then you should tsubst the INITIAL first, and unconditionally copy the
>>type to the TARGET_EXPR when you use build3.
> 
> 
> But what if the TARGET_EXPR had been created for different purposes,
> and did have a different type than that of the initializer?  Say, a
> Base& being bound to a Derived TARGET_EXPR?  That's why I'm performing
> the tests the way I am.

Are you sure that we can use TARGET_EXPR as a type-conversion node?  I 
would think in that case that the INITIAL for the TARGET_EXPR would be a 
call to the derived class constructor.  Hmm.  I suppose the type of such 
  a constructor is "void", so it may indeed be the case that there's 
really no relationship between the types.  Good point.

> Yeah, I know we'd like to do that, but we can't.  At that point we
> have no clue what that TARGET_EXPR or the CONSTRUCTOR in its initial
> came from.  We'd have to create a new tree node type for compound
> literals to be able to call finish_compound_literal at that point.

Then we really should do that.  We could have COMPOUND_LITERAL_EXPR 
whose type would be the type in the (syntactic) cast, and whose argument 
would be the CONSTRUCTOR for the brace-enclosed initializer.  We'd 
create one of these things if the TYPE, or any of the initializers, was 
dependent.

The games that you want to play with type-equality are just too fragile.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (22 preceding siblings ...)
  2005-03-07 16:05 ` mark at codesourcery dot com
@ 2005-03-07 17:05 ` aoliva at redhat dot com
  2005-03-07 18:05 ` mark at codesourcery dot com
                   ` (21 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-07 17:05 UTC (permalink / raw)
  To: gcc-bugs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1892 bytes --]


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-07 17:05 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Are you sure that we can use TARGET_EXPR as a type-conversion node?

Actually, no.  I was led to believe so because there is a function
that creates a TARGET_EXPR given an initializer and a type, in
addition to the one that takes the type from the initializer.

> I would think in that case that the INITIAL for the TARGET_EXPR
> would be a call to the derived class constructor.

I was thinking references, actually, so there wouldn't be a
constructor involved.  I.e., I was trying to preserve the earlier
behavior of TARGET_EXPRs (i.e., mostly do nothing with them), while
adjusting the behavior only as much as needed for this new use.

>> We'd have to create a new tree node type for compound literals to
>> be able to call finish_compound_literal at that point.

> Then we really should do that.

Eek.  What for?  All we need to do is adjust its type.  A new tree
node scattered all over the place feels like way too much overhead for
this.

> The games that you want to play with type-equality are just too fragile.

I still don't see why.  All I am doing is ensuring the equality is
maintained if it existed.  If they weren't equal in the first place, I
just don't change anything.  As a result, in the case in which I know
the equality is important and present, it will be preserved.  In other
cases, we get the behavior we had before.

Why are you so uncomfortable with it?  Is it just the general thought
that `pointer equality between type tree nodes is bad´, before
actually looking into the problem it's trying to address, or other
reasons pertaining to this particular issue?



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (23 preceding siblings ...)
  2005-03-07 17:05 ` aoliva at redhat dot com
@ 2005-03-07 18:05 ` mark at codesourcery dot com
  2005-03-07 21:58 ` aoliva at redhat dot com
                   ` (20 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-07 18:05 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-07 18:05 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:
> On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:
> 
> 
>>Are you sure that we can use TARGET_EXPR as a type-conversion node?
> 
> 
> Actually, no.  I was led to believe so because there is a function
> that creates a TARGET_EXPR given an initializer and a type, in
> addition to the one that takes the type from the initializer.

OK, so if there's no conversion, then my suggestion (i.e., copy the type 
from the substituted initializer) should work fine.

> I was thinking references, actually, so there wouldn't be a
> constructor involved.  I.e., I was trying to preserve the earlier
> behavior of TARGET_EXPRs (i.e., mostly do nothing with them), while
> adjusting the behavior only as much as needed for this new use.

TARGET_EXPRs create objects.  I'm not sure if we ever create 
TARGET_EXPRs with REFERENCE_TYPE, but if so, there initializers should 
have the same type.

>>Then we really should do that. 
> 
> Eek.  What for?  All we need to do is adjust its type.  A new tree
> node scattered all over the place feels like way too much overhead for
> this.

There are two situations:

1. The type is derivable from the operands.

In that case, you can do that, as I've suggested above, by creating the 
operands, and then applying a *uniform, unconditional* operation to the 
type of the operands to determine the type of the TARGET_EXPR.

2. The type is not derivable from the operands.

In that case, you should be going through the same semantics.c routines 
that we do at parse time.

The truth is that (2) is a better choice no matter what, because we 
really want dependent expressions to have a representation that is very 
nearly isomorphic to the source code.  We have to introduce nodes 
corresponding to G++ extensions in other places (like 
statement-expressions); this is no different.  However, I can live with 
(1), for expediency sake.

>>The games that you want to play with type-equality are just too fragile.
> 
> I still don't see why.

First, you're using "==".  As I've told you, that's incredibly fragile. 
  You're depending on a very non-local property that in the case that 
you're interested in, the types will always be ==.  But, minor changes 
elsewhere might make them same_type_p, but not ==, in some cases.  Then, 
your code breaks, probably undetectably.  To a first approximation, the 
only place == should be used for types is in same_type_p itself.

Second, you're applying a non-uniform manipulation on the types of the 
TARGET_EXPR, based on a non-local property about how TARGET_EXPRs are 
created, without actually checking that the condition you're interested 
in (incomplete array types) applies.

This is not an approach that's going to be robust over time.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (24 preceding siblings ...)
  2005-03-07 18:05 ` mark at codesourcery dot com
@ 2005-03-07 21:58 ` aoliva at redhat dot com
  2005-03-07 22:39 ` mark at codesourcery dot com
                   ` (19 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-07 21:58 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-07 21:58 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

>>> The games that you want to play with type-equality are just too fragile.
>> I still don't see why.

> First, you're using "==".  As I've told you, that's incredibly
> fragile.

Not for the purpose I've been trying to describe.

The condition I want to maintain is that, if the TARGET_EXPR had the
type of its INITIAL before template substitution, then it must have
the type of its INITIAL after template substitution, because whatever
transformations the INITIAL type might undergo won't be applied to the
TARGET_EXPR.  It's that simple, so it should be quite obvious that
`==' is what I'm looking for.  It's not just same_type_p; if the types
of the TARGET_EXPR was not taken from the INITIAL, then I don't care
how it evolves.

> You're depending on a very non-local property that in the
> case that you're interested in, the types will always be ==.

No, I'm only guaranteeing that, if this property held before template
substitution, it still holds afterwards.  If it didn't hold before, it
still won't hold afterwards.  It's much simpler than what you
describe.

> But, minor changes elsewhere might make them same_type_p, but not
> ==, in some cases.

If that's fine for those cases, it will remain so after template
substitution.  Sounds *exactly* like what I want.

> Second, you're applying a non-uniform manipulation on the types of the
> TARGET_EXPR, based on a non-local property about how TARGET_EXPRs are
> created, without actually checking that the condition you're
> interested in (incomplete array types) applies.

Huh?!?  No, I'm not.  Read the code again.  It goes like this:

  if the decl type and the initializer type were the same before,
    make them the same after

  if the target_expr type and the decl type were the same before,
    make them the same after

and that's it.  It's that simple.  Nothing non-uniform about it.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (25 preceding siblings ...)
  2005-03-07 21:58 ` aoliva at redhat dot com
@ 2005-03-07 22:39 ` mark at codesourcery dot com
  2005-03-08  7:25 ` aoliva at redhat dot com
                   ` (18 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-07 22:39 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-07 22:39 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:
> On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:
> 
> 
>>>>The games that you want to play with type-equality are just too fragile.
>>>
>>>I still don't see why.
> 
> 
>>First, you're using "==".  As I've told you, that's incredibly
>>fragile.
> 
> 
> Not for the purpose I've been trying to describe.

We're at risk of descending into "Yes. No. Yes. No."

I think it's fragile.  Now, reasonable people can disagree about 
software engineering -- it's an art form, not a science -- but my 
opinion is that this is fragile.

I've explained why:

(a) we should never use "==" to compare types, because there's no 
guarantee that the compiler will continue to use "==" types in places 
where it does at present; it might instead switch one of them to be 
same_type_p.  Think about it this way: == has no semantic meaning in 
C++; the only relationship the language knows about is same_type_p.  So, 
using == means that you're doing something with types that doesn't have 
semantics grounded in the language, which doesn't make sense, except in 
places that are trying to get debugging information correct, etc.

(b) you're applying a non-uniform transformation depending on non-local 
knowledge.  What I mean by "non-uniform" is that the assignment to the 
type of the TARGET_EXPR is conditional.  If it were an unconditional 
assignment, I'd be less nervous; then, you'd be asserting that the type 
of the TARGET_EXPR should always be the type of its initializer, which 
might make sense.  What I mean by "non-local" is that your 
transformation only works because of some far-off logic that determins 
how TARGET_EXPRs are created.  It doesn't depend on any documented 
property of TARGET_EXPRs that is enforced throughout the compiler.

Consider the comments you should write for your code:

/* Code in <some function> creates TARGET_EXPRs with "==" types, and 
that must be preserved here.  If you change that code, don't forget to 
update this code!  */

And, then, you should add something to the TARGET_EXPR documentation 
along the lines of:

/* Some TARGET_EXPRs have the same TREE_TYPE as their initializers; some 
don't.  The kinds that do are ...; the kinds that don't are ...  When 
instantiating templates, we preserve equality for types that "==", but 
not necessarily those that are same_type_p.  */

Finally, I've explained that the entire approach is contrary to the way 
we want to do things in templates, which is that you keep a syntactic 
form for dependent expressions until instantiation time, and then run 
through the same exact routines you would have in the parser.  That's 
really the only way we can be sure that the semantics match up.

I'm sorry you're frustruated, but I don't think that your approach is 
the right way to go.

>>But, minor changes elsewhere might make them same_type_p, but not
>>==, in some cases.
>  
> If that's fine for those cases, it will remain so after template
> substitution.  Sounds *exactly* like what I want.

Why would you want that?  If before substitution, the operand had a 
typedef type for the incomplete array, and the TARGET_EXPR had a 
different typedef type for the same incomplete array, wouldn't you want 
to update the type of the TARGET_EXPR?

In the context of a 4.0 patch, I'd be willing to consider a patch like 
yours, using same_type_p instead of "==", and with suitable comments 
explaining what's going on.  For 4.1, we should do better.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (26 preceding siblings ...)
  2005-03-07 22:39 ` mark at codesourcery dot com
@ 2005-03-08  7:25 ` aoliva at redhat dot com
  2005-03-08  7:46 ` mark at codesourcery dot com
                   ` (17 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-08  7:25 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-08 07:24 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  7, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> (a) we should never use "==" to compare types, because there's no
> guarantee that the compiler will continue to use "==" types in places
> where it does at present;

The guarantee is the code in get_target_expr.  That's also the only
case in which type equality preserving matters, and even then, only
when INITIAL is a CONSTRUCTOR.  For all other cases, if preserving
such equality mattered, we'd have had to handle those cases before at
the point I'm handling them now.

> Think about it this way: == has no semantic meaning in C++

Indeed, it's a front-end implementation detail.  It should be fine to
take advantage of it in the front-end.  It's not about the language.
The TARGET_EXPR itself is just working around a constraint imposed by
the gimplifier.

> So, using == means that you're doing something with types that doesn't
> have semantics grounded in the language, which doesn't make sense,
> except in places that are trying to get debugging information correct,
> etc.

So think of it this way: if we adopted COMPOUND_LITERAL_EXPR like
you're inclined to do, we'd have to do the very same kind of type
propagation after resolving the complete type of the initializer.
This is no different from what I'm proposing to do here.

And there's more: since there's no compiler-enforced equality AFAICT
between the type of the COMPOUND_LITERAL_EXPR and that of the VAR_DECL
enclosed in it, we'd have o make the propagation conditional in just
the same way.

> (b) you're applying a non-uniform transformation depending on
> non-local knowledge.  What I mean by "non-uniform" is that the
> assignment to the type of the TARGET_EXPR is conditional.

Conditional as in, if a condition held before, make sure it holds
after.  It really doesn't sound non-uniform to me.

Note that we never needed this condition to hold before; TARGET_EXPRs
just were not handled at all: we never emitted TARGET_EXPRs whose
types were arrays of unknown bounds, to be inferred from the
initializer length, before this change.

> If it were an unconditional assignment, I'd be less nervous;

Can't you just think of it as if we had, instead of TARGET_EXPR, a
TARGET_EXPR_WITH_INITIALIZER_TYPE and TARGET_EXPR_WITH_DIFFERENT_TYPE,
and the statement was unconditional for the former, and not present
for the latter?  This is a precise description of the properties at
hand.

Now what if, instead of using up two separate tree nodes, we use a
single tree node for them, and use a comparison between the type of
the initializer and the type of the target_expr to tell which case we
have?  Hey!, but this is *exactly* what the patch does!

> then, you'd be asserting that the type of the TARGET_EXPR should
> always be the type of its initializer, which might make sense.

Further investigation has shown that TARGET_EXPR's SLOTs always have
the same type as the enclosing TARGET_EXPR.  Whether SLOTs and
INITIALs always have the same type is not as obvious, but it appears
to hold as well.  How about making the assignments unconditional,
then, with an assertion that the equality holds?

> What I mean by "non-local" is that your transformation only works
> because of some far-off logic that determins how TARGET_EXPRs are
> created.

No, because of some local preservation of a property.  Not preserving
it when it was present does break code.  Introducing it when it wasn't
there before might break code.  So the right thing to do is,
obviously, to test for the property, and preserve it if it was
present.  There isn't any non-local property here: the decision is
entirely local, and there's no hidden dependency on anything
elsewhere.  It's as simple as: if both entities pointed to the same
thing, make sure they still do afterwards.  How can this possibly not
be a reasonable thing to do?

> It doesn't depend on any documented property of TARGET_EXPRs that is
> enforced throughout the compiler.

It's precisely because the property is not documented that it's tested
locally.  Perhaps the property is guaranteed by the current
implementation, I can't quite tell for sure.  But testing for the
property and propagating it into the substed template feels like the
very right thing to do for some property that isn't necessarily
guaranteed.

> Consider the comments you should write for your code:

How about:

/* If the type of the initializer was used to create the original
   TARGET_EXPR, make sure we adjust the type of the tsubsted
   TARGET_EXPR, should the type of the initializer change in
   unpredictable ways during tsubsting (e.g., the range of an array is
   inferred from a CONSTRUCTOR length).  */

See?  No need to change any other piece of code anywhere else.  It's
really that simple.

> I'm sorry you're frustruated, but I don't think that your approach is
> the right way to go.

>>> But, minor changes elsewhere might make them same_type_p, but not
>>> ==, in some cases.
>> If that's fine for those cases, it will remain so after template
>> substitution.  Sounds *exactly* like what I want.

> Why would you want that?  If before substitution, the operand had a
> typedef type for the incomplete array,

Err, no.  Before substitution, the TARGET_EXPR was created using the
type obtained from the initializer.  That's the only case we care
about preserving.  Other cases weren't preserved before, so I don't
care about preserving them.

> and the TARGET_EXPR had a different typedef type for the same
> incomplete array, wouldn't you want to update the type of the
> TARGET_EXPR?

No, that's the point you're missing.  TARGET_EXPRs are not a C++
language concept.  They're an implementation detail of the compiler.
We even have COMPOUND_LITERAL_EXPR in the tree docs, but I don't see
that they're going to get destructors called at the right time, and
we'd still have to maintain the same equality, probably in the very
same conditional way, except that it's trickier because the
CONSTRUCTOR will be hiding deeper down in the tree.

> In the context of a 4.0 patch, I'd be willing to consider a patch like
> yours, using same_type_p instead of "==", and with suitable comments
> explaining what's going on.  For 4.1, we should do better.

same_type_p doesn't make sense for this purpose precisely because it's
a language concept, but what I'm dealing with here is an
implementation concept.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (27 preceding siblings ...)
  2005-03-08  7:25 ` aoliva at redhat dot com
@ 2005-03-08  7:46 ` mark at codesourcery dot com
  2005-03-08 20:44 ` aoliva at redhat dot com
                   ` (16 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-03-08  7:46 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-03-08 07:45 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:

> So think of it this way: if we adopted COMPOUND_LITERAL_EXPR like
> you're inclined to do, we'd have to do the very same kind of type
> propagation after resolving the complete type of the initializer.
> This is no different from what I'm proposing to do here.

Except that (a) we'd have no change of doing it when we don't want to do 
it (which we do with your patch, because if the two things just happen 
to have the same type before substitution, we'll preserve that, even if 
we shouldn't, perhaps for some case/language feature/extension that 
hasn't even been invented yet), and (b) we'd be guaranteed to keep doing 
it when we do want it to happen (which we won't, with your patch, if 
something changes in get_target_expr).

> And there's more: since there's no compiler-enforced equality AFAICT
> between the type of the COMPOUND_LITERAL_EXPR and that of the VAR_DECL
> enclosed in it, we'd have o make the propagation conditional in just
> the same way.

No, because there would be no TARGET_EXPR.  In a template, you would 
just have a COMPOUND_LITERAL_EXPR, with no TARGET_EXPR, because we want 
a syntactic representation of the input program.

> Note that we never needed this condition to hold before; TARGET_EXPRs
> just were not handled at all: we never emitted TARGET_EXPRs whose
> types were arrays of unknown bounds, to be inferred from the
> initializer length, before this change.

Yes, and introducing TARGET_EXPRs into templates *is a bug* because in 
templates we want a syntactic representation.  The closest thing we have 
to a syntactic representation of a compound literal is a CONSTRUCTOR; 
it's certainly not a TARGET_EXPR wrapped around a CONSTRUCTOR.  It may 
be just fine to use CONSTRUCTOR, instead of introducing 
COMPOUND_LITERAL_EXPR, but TARGET_EXPRs should not be appearing here at all.

> Further investigation has shown that TARGET_EXPR's SLOTs always have
> the same type as the enclosing TARGET_EXPR.  Whether SLOTs and
> INITIALs always have the same type is not as obvious, but it appears
> to hold as well.  How about making the assignments unconditional,
> then, with an assertion that the equality holds?

Copying the SLOT type to the EXPR type would make a lot more sense. 
That's along the lines of what I originally suggested: substitute into 
the operands, and then form the TARGET_EXPR with an appropriate type. 
You've just demonstrated a way to do that, in a uniform way.

Unfortunately, you've also caused me to think about this long enough to 
realize that having the TARGET_EXPR here is wrong in the first place, as 
per above.

> /* If the type of the initializer was used to create the original
>    TARGET_EXPR, make sure we adjust the type of the tsubsted
>    TARGET_EXPR, should the type of the initializer change in
>    unpredictable ways during tsubsting (e.g., the range of an array is
>    inferred from a CONSTRUCTOR length).  */
> 
> See?  No need to change any other piece of code anywhere else.  It's
> really that simple.

That's not a justification; that's just a statement of what the code 
does.  Why would we copy this type sometimes and not others?

Fundamentally, what your patch says is that the semantics of TARGET_EXPR 
depend on whether or not the type of INITIAL matches the type of the 
TARGET_EXPR.  If that weren't true, then we wouldn't have to check that 
condition before doing whatever we do.  But, there's nothing about the 
actual semantics of TARGET_EXPR that depend on this type equality; ergo, 
the patch does not make sense.

But, as I've said above, I think this is all moot; TARGET_EXPRs should 
not appear in template bodies at all.  I think you've confirmed that by 
saying that you had to add this code.  If you look at the other code 
that handles expressions in templates, you'll see how we preserve the 
syntactic form, precisely so that we can reuse the appropriate 
semantics.c routines at the time of instantiation.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (28 preceding siblings ...)
  2005-03-08  7:46 ` mark at codesourcery dot com
@ 2005-03-08 20:44 ` aoliva at redhat dot com
  2005-03-08 21:55 ` aoliva at redhat dot com
                   ` (15 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-08 20:44 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-08 20:44 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  8, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> No, because there would be no TARGET_EXPR.  In a template, you would
> just have a COMPOUND_LITERAL_EXPR, with no TARGET_EXPR, because we
> want a syntactic representation of the input program.

> Yes, and introducing TARGET_EXPRs into templates *is a bug* because in
> templates we want a syntactic representation.  The closest thing we
> have to a syntactic representation of a compound literal is a
> CONSTRUCTOR; it's certainly not a TARGET_EXPR wrapped around a
> CONSTRUCTOR.  It may be just fine to use CONSTRUCTOR, instead of
> introducing COMPOUND_LITERAL_EXPR, but TARGET_EXPRs should not be
> appearing here at all.

> Unfortunately, you've also caused me to think about this long enough
> to realize that having the TARGET_EXPR here is wrong in the first
> place, as per above.

Okie dokie, how about this?

The change to the gimplify.c is needed to avoid having
gimple_add_tmp_var twice for the variable, once while expanding the
declaration/initialization, once while expanding the clean-ups.

Ok to install?  Passed check-g++ (except for the already-broken
eh/cleanup1.C) on x86_64-linux-gnu; just started bootstrap and full
reg-testing.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* gimplify.c (gimplify_decl_expr): Don't add temp variable if it
	was already seen in a bind expr.

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.115
diff -u -p -r2.115 gimplify.c
--- gcc/gimplify.c 8 Mar 2005 13:56:57 -0000 2.115
+++ gcc/gimplify.c 8 Mar 2005 20:33:03 -0000
@@ -1047,7 +1047,8 @@ gimplify_decl_expr (tree *stmt_p)
       /* 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_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+      if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE
+	  && !DECL_SEEN_IN_BIND_EXPR_P (decl))
 	gimple_add_tmp_var (decl);
     }
 
@@ -2123,7 +2124,8 @@ gimple_boolify (tree expr)
      *EXPR_P should be stored.  */
 
 static enum gimplify_status
-gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target)
+gimplify_cond_expr (tree *expr_p, tree *pre_p, tree *post_p, tree target,
+		    fallback_t fallback)
 {
   tree expr = *expr_p;
   tree tmp, tmp2, type;
@@ -2137,18 +2139,40 @@ gimplify_cond_expr (tree *expr_p, tree *
      the arms.  */
   else if (! VOID_TYPE_P (type))
     {
+      tree result;
+
       if (target)
 	{
 	  ret = gimplify_expr (&target, pre_p, post_p,
 			       is_gimple_min_lval, fb_lvalue);
 	  if (ret != GS_ERROR)
 	    ret = GS_OK;
-	  tmp = target;
+	  result = tmp = target;
 	  tmp2 = unshare_expr (target);
 	}
+      else if ((fallback & fb_lvalue) == 0)
+	{
+	  result = tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
+	  ret = GS_ALL_DONE;
+	}
       else
 	{
-	  tmp2 = tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
+	  tree type = build_pointer_type (TREE_TYPE (expr));
+
+	  if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
+	    TREE_OPERAND (expr, 1) =
+	      build_fold_addr_expr (TREE_OPERAND (expr, 1));
+
+	  if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
+	    TREE_OPERAND (expr, 2) =
+	      build_fold_addr_expr (TREE_OPERAND (expr, 2));
+	  
+	  tmp2 = tmp = create_tmp_var (type, "iftmp");
+
+	  expr = build (COND_EXPR, void_type_node, TREE_OPERAND (expr, 0),
+			TREE_OPERAND (expr, 1), TREE_OPERAND (expr, 2));
+
+	  result = build_fold_indirect_ref (tmp);
 	  ret = GS_ALL_DONE;
 	}
 
@@ -2169,7 +2193,7 @@ gimplify_cond_expr (tree *expr_p, tree *
       /* Move the COND_EXPR to the prequeue.  */
       gimplify_and_add (expr, pre_p);
 
-      *expr_p = tmp;
+      *expr_p = result;
       return ret;
     }
 
@@ -2907,7 +2931,8 @@ gimplify_modify_expr_rhs (tree *expr_p, 
 	if (!is_gimple_reg_type (TREE_TYPE (*from_p)))
 	  {
 	    *expr_p = *from_p;
-	    return gimplify_cond_expr (expr_p, pre_p, post_p, *to_p);
+	    return gimplify_cond_expr (expr_p, pre_p, post_p, *to_p,
+				       fb_rvalue);
 	  }
 	else
 	  ret = GS_UNHANDLED;
@@ -3721,7 +3746,8 @@ gimplify_expr (tree *expr_p, tree *pre_p
 	  break;
 
 	case COND_EXPR:
-	  ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE);
+	  ret = gimplify_cond_expr (expr_p, pre_p, post_p, NULL_TREE,
+				    fallback);
 	  break;
 
 	case CALL_EXPR:
Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* cp-tree.h (build_compound_literal): Declare.
	* semantics.c (finish_compound_literal): Move most of the code...
	* tree.c (build_compound_literal): ... here.  New function.
	(lvalue_p_1): Handle COMPOUND_LITERAL_EXPR.
	(stabilize_init): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* call.c (build_over_call): Likewise.
	* class.c (fixed_type_or_null): Likewise.
	* cp-gimplify.c (cp_gimplify_init_expr): Likewise.
	* cvt.c (force_rvalue, ocp_convert): Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1107
diff -u -p -r1.1107 cp-tree.h
--- gcc/cp/cp-tree.h 1 Mar 2005 09:57:38 -0000 1.1107
+++ gcc/cp/cp-tree.h 8 Mar 2005 20:33:12 -0000
@@ -4218,6 +4218,7 @@ extern tree build_min_nt			(enum tree_co
 extern tree build_min_non_dep			(enum tree_code, tree, ...);
 extern tree build_cplus_new			(tree, tree);
 extern tree get_target_expr			(tree);
+extern tree build_compound_literal		(tree, tree);
 extern tree build_cplus_array_type		(tree, tree);
 extern tree hash_tree_cons			(tree, tree, tree);
 extern tree hash_tree_chain			(tree, tree);
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463
diff -u -p -r1.463 semantics.c
--- gcc/cp/semantics.c 23 Feb 2005 05:30:48 -0000 1.463
+++ gcc/cp/semantics.c 8 Mar 2005 20:33:13 -0000
@@ -1980,23 +1980,8 @@ finish_compound_literal (tree type, tree
   compound_literal = build_constructor (NULL_TREE, initializer_list);
   /* Mark it as a compound-literal.  */
   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
-  if (processing_template_decl)
-    TREE_TYPE (compound_literal) = type;
-  else
-    {
-      /* Check the initialization.  */
-      compound_literal = digest_init (type, compound_literal, NULL);
-      /* If the TYPE was an array type with an unknown bound, then we can
-	 figure out the dimension now.  For example, something like:
-
-	   `(int []) { 2, 3 }'
-
-	 implies that the array has two elements.  */
-      if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
-	complete_array_type (type, compound_literal, 1);
-    }
 
-  return compound_literal;
+  return build_compound_literal (type, compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.427
diff -u -p -r1.427 tree.c
--- gcc/cp/tree.c 21 Feb 2005 23:12:27 -0000 1.427
+++ gcc/cp/tree.c 8 Mar 2005 20:33:15 -0000
@@ -154,6 +154,7 @@ lvalue_p_1 (tree ref,
 			 treat_class_rvalues_as_lvalues);
 
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
 
     case CALL_EXPR:
@@ -365,6 +366,47 @@ get_target_expr (tree init)
   return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the
+   compound literal, which may be an incomplete array type completed
+   by the initializer; COMPOUND_LITERAL is a CONSTRUCTOR that
+   initializes the compound literal.  */
+
+tree
+build_compound_literal (tree type, tree compound_literal)
+{
+  /* We do not use start_decl here because we have a type, not a declarator;
+     and do not use finish_decl because the decl should be stored inside
+     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
+  tree decl;
+  tree complit;
+  tree stmt;
+
+  if (type == error_mark_node || compound_literal == error_mark_node)
+    return error_mark_node;
+
+  if (!processing_template_decl)
+    {
+      /* Check the initialization.  */
+      compound_literal = digest_init (type, compound_literal, NULL);
+      /* If the TYPE was an array type with an unknown bound, then we can
+	 figure out the dimension now.  For example, something like:
+
+	   `(int []) { 2, 3 }'
+
+	 implies that the array has two elements.  */
+      if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+	complete_array_type (type, compound_literal, 1);
+    }
+
+  decl = build_local_temp (type);
+  DECL_INITIAL (decl) = compound_literal;
+
+  stmt = build_stmt (DECL_EXPR, decl);
+  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  TREE_SIDE_EFFECTS (complit) = 1;
+
+  return complit;
+}
 \f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
@@ -2241,6 +2283,8 @@ stabilize_init (tree init, tree *initp)
 	t = TREE_OPERAND (t, 1);
       if (TREE_CODE (t) == TARGET_EXPR)
 	t = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (t) == COMPOUND_LITERAL_EXPR)
+	t = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t));
       if (TREE_CODE (t) == COMPOUND_EXPR)
 	t = expr_last (t);
       if (TREE_CODE (t) == CONSTRUCTOR
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.979
diff -u -p -r1.979 pt.c
--- gcc/cp/pt.c 5 Mar 2005 15:44:20 -0000 1.979
+++ gcc/cp/pt.c 8 Mar 2005 20:33:22 -0000
@@ -8744,6 +8744,11 @@ tsubst_copy_and_build (tree t, 
       return build_throw
 	(RECUR (TREE_OPERAND (t, 0)));
 
+    case COMPOUND_LITERAL_EXPR:
+      return build_compound_literal
+	(RECUR (TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (t))),
+	 RECUR (DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t))));
+
     case CONSTRUCTOR:
       {
 	tree r;
Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.531
diff -u -p -r1.531 call.c
--- gcc/cp/call.c 24 Feb 2005 21:55:10 -0000 1.531
+++ gcc/cp/call.c 8 Mar 2005 20:33:26 -0000
@@ -3655,6 +3655,54 @@ build_new_op (enum tree_code code, int f
 			TYPE_BINFO (TREE_TYPE (arg1)),
 			flags, &candidates);
     }
+  /* Per 13.3.1.2/3, 2nd bullet, if no operand has a class type, then
+     only non-member functions that have type T1 or reference to
+     cv-qualified-opt T1 for the first argument, if the first argument
+     has an enumeration type, or T2 or reference to cv-qualified-opt
+     T2 for the second argument, if the the second argument has an
+     enumeration type.  Filter out those that don't match.  */
+  else if (! arg2 || ! CLASS_TYPE_P (TREE_TYPE (arg2)))
+    {
+      struct z_candidate **candp, **next;
+
+      for (candp = &candidates; *candp; candp = next)
+	{
+	  tree parmlist, parmtype;
+
+	  cand = *candp;
+	  next = &cand->next;
+
+	  parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+	  parmtype = TREE_VALUE (parmlist);
+
+	  if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE
+	      && (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)),
+			       TYPE_MAIN_VARIANT (parmtype))
+		  || (TREE_CODE (parmtype) == REFERENCE_TYPE
+		      && reference_related_p (TREE_TYPE (arg1),
+					      TREE_TYPE (parmtype)))))
+	    continue;
+
+	  if (! arg2)
+	    continue;
+
+	  parmlist = TREE_CHAIN (parmlist);
+	  parmtype = TREE_VALUE (parmlist);
+
+	  if (TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE
+	      && (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)),
+			       TYPE_MAIN_VARIANT (parmtype))
+		  || (TREE_CODE (parmtype) == REFERENCE_TYPE
+		      && reference_related_p (TREE_TYPE (arg2),
+					      TREE_TYPE (parmtype)))))
+	    continue;
+
+	  /* Neither argument has an appropriate type, so remove this
+	     candidate function from the list.  */
+	  *candp = cand->next;
+	  next = candp;
+	}
+    }
 
   /* Rearrange the arguments for ?: so that add_builtin_candidate only has
      to know about two args; a builtin candidate will always have a first
@@ -4850,12 +4898,14 @@ build_over_call (struct z_candidate *can
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
 	{
-	  if (TREE_CODE (arg) == TARGET_EXPR)
+	  if (TREE_CODE (arg) == TARGET_EXPR
+	      || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
 	    return arg;
 	  else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	    return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
 	}
       else if (TREE_CODE (arg) == TARGET_EXPR
+	       || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR
 	       || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	{
 	  tree to = stabilize_reference
Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.709
diff -u -p -r1.709 class.c
--- gcc/cp/class.c 7 Mar 2005 23:08:57 -0000 1.709
+++ gcc/cp/class.c 8 Mar 2005 20:33:31 -0000
@@ -5234,6 +5234,7 @@ fixed_type_or_null (tree instance, int* 
 	}
       /* fall through...  */
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.17
diff -u -p -r1.17 cp-gimplify.c
--- gcc/cp/cp-gimplify.c 22 Dec 2004 18:00:38 -0000 1.17
+++ gcc/cp/cp-gimplify.c 8 Mar 2005 20:33:31 -0000
@@ -1,6 +1,6 @@
 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@redhat.com>
 
 This file is part of GCC.
@@ -125,6 +125,8 @@ cp_gimplify_init_expr (tree *expr_p, tre
     from = TARGET_EXPR_INITIAL (from);
   if (TREE_CODE (from) == CLEANUP_POINT_EXPR)
     from = TREE_OPERAND (from, 0);
+  if (TREE_CODE (from) == COMPOUND_LITERAL_EXPR)
+    from = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (from));
 
   /* Look through any COMPOUND_EXPRs.  */
   sub = expr_last (from);
Index: gcc/cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.180
diff -u -p -r1.180 cvt.c
--- gcc/cp/cvt.c 9 Feb 2005 02:53:37 -0000 1.180
+++ gcc/cp/cvt.c 8 Mar 2005 20:33:32 -0000
@@ -575,7 +575,8 @@ convert_from_reference (tree val)
 tree
 force_rvalue (tree expr)
 {
-  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR)
+  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR
+      && TREE_CODE (expr) != COMPOUND_LITERAL_EXPR)
     expr = ocp_convert (TREE_TYPE (expr), expr,
 			CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
@@ -640,6 +641,16 @@ ocp_convert (tree type, tree expr, int c
 	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
 	  return e;
 	}
+      else if (TREE_CODE (e) == COMPOUND_LITERAL_EXPR)
+	{
+	  /* Don't build a NOP_EXPR of class type.  Instead, change the
+	     type of the temporary.  Only allow this for cv-qual changes,
+	     though.  */
+	  gcc_assert (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
+				   TYPE_MAIN_VARIANT (type)));
+	  TREE_TYPE (e) = TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (e)) = type;
+	  return e;
+	}	  
       else
 	{
 	  /* We shouldn't be treating objects of ADDRESSABLE type as
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* g++.dg/tree-ssa/pr20103.C: New test.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 8 Mar 2005 20:33:46 -0000
@@ -0,0 +1,59 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}
+
+template <typename T, typename U>
+void baz(T &x)
+{
+    foo ((U){x});
+    bar ((U){x}); // { dg-error "non-const reference" }
+    bac ((U){x});
+    bap (&(U){x}); // { dg-error "address of temporary" }
+
+    foo ((const U&)(U){x});
+    bar ((U&)(U){x}); // { dg-error "invalid cast" }
+    bac ((const U&)(U){x});
+    bap (&(const U&)(U){x});
+}
+
+void bazT(A &x) {
+  baz<A,B>(x);
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (29 preceding siblings ...)
  2005-03-08 20:44 ` aoliva at redhat dot com
@ 2005-03-08 21:55 ` aoliva at redhat dot com
  2005-03-11 15:20 ` rth at gcc dot gnu dot org
                   ` (14 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-08 21:55 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-08 21:55 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar  8, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> Okie dokie, how about this?

> The change to the gimplify.c is needed to avoid having
> gimple_add_tmp_var twice for the variable, once while expanding the
> declaration/initialization, once while expanding the clean-ups.

> Ok to install?  Passed check-g++ (except for the already-broken
> eh/cleanup1.C) on x86_64-linux-gnu; just started bootstrap and full
> reg-testing.

Err...  *This* was the one that passed check-g++.  The one I posted in
a hurry earlier was very incomplete, and contained fragments of other
patches.  Sorry about that.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* gimplify.c (gimplify_decl_expr): Don't add temp variable if it
	was already seen in a bind expr.

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.115
diff -u -p -r2.115 gimplify.c
--- gcc/gimplify.c 8 Mar 2005 13:56:57 -0000 2.115
+++ gcc/gimplify.c 8 Mar 2005 21:48:41 -0000
@@ -1047,7 +1047,8 @@ gimplify_decl_expr (tree *stmt_p)
       /* 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_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+      if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE
+	  && !DECL_SEEN_IN_BIND_EXPR_P (decl))
 	gimple_add_tmp_var (decl);
     }
 
Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* cp-tree.h (build_compound_literal): Declare.
	* semantics.c (finish_compound_literal): Move most of the code...
	* tree.c (build_compound_literal): ... here.  New function.
	(lvalue_p_1): Handle COMPOUND_LITERAL_EXPR.
	(stabilize_init): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* call.c (build_over_call): Likewise.
	* class.c (fixed_type_or_null): Likewise.
	* cp-gimplify.c (cp_gimplify_init_expr): Likewise.
	* cvt.c (force_rvalue, ocp_convert): Likewise.
	* typeck.c (build_x_unary_op): Likewise.
	(cxx_mark_addressable): Likewise.
	(maybe_warn_about_returning_address_of_local): Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1107
diff -u -p -r1.1107 cp-tree.h
--- gcc/cp/cp-tree.h 1 Mar 2005 09:57:38 -0000 1.1107
+++ gcc/cp/cp-tree.h 8 Mar 2005 21:48:50 -0000
@@ -4218,6 +4218,7 @@ extern tree build_min_nt			(enum tree_co
 extern tree build_min_non_dep			(enum tree_code, tree, ...);
 extern tree build_cplus_new			(tree, tree);
 extern tree get_target_expr			(tree);
+extern tree build_compound_literal		(tree, tree);
 extern tree build_cplus_array_type		(tree, tree);
 extern tree hash_tree_cons			(tree, tree, tree);
 extern tree hash_tree_chain			(tree, tree);
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463
diff -u -p -r1.463 semantics.c
--- gcc/cp/semantics.c 23 Feb 2005 05:30:48 -0000 1.463
+++ gcc/cp/semantics.c 8 Mar 2005 21:48:52 -0000
@@ -1980,23 +1980,16 @@ finish_compound_literal (tree type, tree
   compound_literal = build_constructor (NULL_TREE, initializer_list);
   /* Mark it as a compound-literal.  */
   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+
   if (processing_template_decl)
+    /* This causes template substitution to run digest_init on the
+       CONSTRUCTOR.  */
     TREE_TYPE (compound_literal) = type;
   else
-    {
-      /* Check the initialization.  */
-      compound_literal = digest_init (type, compound_literal, NULL);
-      /* If the TYPE was an array type with an unknown bound, then we can
-	 figure out the dimension now.  For example, something like:
-
-	   `(int []) { 2, 3 }'
-
-	 implies that the array has two elements.  */
-      if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
-	complete_array_type (type, compound_literal, 1);
-    }
+    /* Check the initialization.  */
+    compound_literal = digest_init (type, compound_literal, NULL);
 
-  return compound_literal;
+  return build_compound_literal (type, compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.427
diff -u -p -r1.427 tree.c
--- gcc/cp/tree.c 21 Feb 2005 23:12:27 -0000 1.427
+++ gcc/cp/tree.c 8 Mar 2005 21:48:53 -0000
@@ -154,6 +154,7 @@ lvalue_p_1 (tree ref,
 			 treat_class_rvalues_as_lvalues);
 
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
 
     case CALL_EXPR:
@@ -365,6 +366,43 @@ get_target_expr (tree init)
   return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the
+   compound literal, which may be an incomplete array type completed
+   by the initializer; COMPOUND_LITERAL is a CONSTRUCTOR that
+   initializes the compound literal.  */
+
+tree
+build_compound_literal (tree type, tree compound_literal)
+{
+  /* We do not use start_decl here because we have a type, not a declarator;
+     and do not use finish_decl because the decl should be stored inside
+     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
+  tree decl;
+  tree complit;
+  tree stmt;
+
+  if (type == error_mark_node || compound_literal == error_mark_node)
+    return error_mark_node;
+
+  /* If the TYPE was an array type with an unknown bound, then we can
+     figure out the dimension now.  For example, something like:
+
+     `(int []) { 2, 3 }'
+
+     implies that the array has two elements.  */
+  if (!processing_template_decl
+      && TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+    complete_array_type (type, compound_literal, 1);
+
+  decl = build_local_temp (type);
+  DECL_INITIAL (decl) = compound_literal;
+
+  stmt = build_stmt (DECL_EXPR, decl);
+  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  TREE_SIDE_EFFECTS (complit) = 1;
+
+  return complit;
+}
 \f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
@@ -2241,6 +2279,8 @@ stabilize_init (tree init, tree *initp)
 	t = TREE_OPERAND (t, 1);
       if (TREE_CODE (t) == TARGET_EXPR)
 	t = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (t) == COMPOUND_LITERAL_EXPR)
+	t = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t));
       if (TREE_CODE (t) == COMPOUND_EXPR)
 	t = expr_last (t);
       if (TREE_CODE (t) == CONSTRUCTOR
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.979
diff -u -p -r1.979 pt.c
--- gcc/cp/pt.c 5 Mar 2005 15:44:20 -0000 1.979
+++ gcc/cp/pt.c 8 Mar 2005 21:49:01 -0000
@@ -8744,6 +8744,11 @@ tsubst_copy_and_build (tree t, 
       return build_throw
 	(RECUR (TREE_OPERAND (t, 0)));
 
+    case COMPOUND_LITERAL_EXPR:
+      return build_compound_literal
+	(RECUR (TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (t))),
+	 RECUR (DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t))));
+
     case CONSTRUCTOR:
       {
 	tree r;
Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.531
diff -u -p -r1.531 call.c
--- gcc/cp/call.c 24 Feb 2005 21:55:10 -0000 1.531
+++ gcc/cp/call.c 8 Mar 2005 21:49:05 -0000
@@ -4850,12 +4850,14 @@ build_over_call (struct z_candidate *can
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
 	{
-	  if (TREE_CODE (arg) == TARGET_EXPR)
+	  if (TREE_CODE (arg) == TARGET_EXPR
+	      || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
 	    return arg;
 	  else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	    return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
 	}
       else if (TREE_CODE (arg) == TARGET_EXPR
+	       || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR
 	       || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	{
 	  tree to = stabilize_reference
Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.709
diff -u -p -r1.709 class.c
--- gcc/cp/class.c 7 Mar 2005 23:08:57 -0000 1.709
+++ gcc/cp/class.c 8 Mar 2005 21:49:10 -0000
@@ -5234,6 +5234,7 @@ fixed_type_or_null (tree instance, int* 
 	}
       /* fall through...  */
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.17
diff -u -p -r1.17 cp-gimplify.c
--- gcc/cp/cp-gimplify.c 22 Dec 2004 18:00:38 -0000 1.17
+++ gcc/cp/cp-gimplify.c 8 Mar 2005 21:49:10 -0000
@@ -1,6 +1,6 @@
 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@redhat.com>
 
 This file is part of GCC.
@@ -125,6 +125,8 @@ cp_gimplify_init_expr (tree *expr_p, tre
     from = TARGET_EXPR_INITIAL (from);
   if (TREE_CODE (from) == CLEANUP_POINT_EXPR)
     from = TREE_OPERAND (from, 0);
+  if (TREE_CODE (from) == COMPOUND_LITERAL_EXPR)
+    from = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (from));
 
   /* Look through any COMPOUND_EXPRs.  */
   sub = expr_last (from);
Index: gcc/cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.180
diff -u -p -r1.180 cvt.c
--- gcc/cp/cvt.c 9 Feb 2005 02:53:37 -0000 1.180
+++ gcc/cp/cvt.c 8 Mar 2005 21:49:11 -0000
@@ -575,7 +575,8 @@ convert_from_reference (tree val)
 tree
 force_rvalue (tree expr)
 {
-  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR)
+  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR
+      && TREE_CODE (expr) != COMPOUND_LITERAL_EXPR)
     expr = ocp_convert (TREE_TYPE (expr), expr,
 			CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
@@ -640,6 +641,16 @@ ocp_convert (tree type, tree expr, int c
 	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
 	  return e;
 	}
+      else if (TREE_CODE (e) == COMPOUND_LITERAL_EXPR)
+	{
+	  /* Don't build a NOP_EXPR of class type.  Instead, change the
+	     type of the temporary.  Only allow this for cv-qual changes,
+	     though.  */
+	  gcc_assert (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
+				   TYPE_MAIN_VARIANT (type)));
+	  TREE_TYPE (e) = TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (e)) = type;
+	  return e;
+	}	  
       else
 	{
 	  /* We shouldn't be treating objects of ADDRESSABLE type as
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.617
diff -u -p -r1.617 typeck.c
--- gcc/cp/typeck.c 5 Mar 2005 15:44:20 -0000 1.617
+++ gcc/cp/typeck.c 8 Mar 2005 21:49:15 -0000
@@ -3590,7 +3590,8 @@ build_x_unary_op (enum tree_code code, t
 	      PTRMEM_OK_P (xarg) = ptrmem;
 	    }	      
         }
-      else if (TREE_CODE (xarg) == TARGET_EXPR)
+      else if (TREE_CODE (xarg) == TARGET_EXPR
+	       || TREE_CODE (xarg) == COMPOUND_LITERAL_EXPR)
 	warning ("taking address of temporary");
       exp = build_unary_op (ADDR_EXPR, xarg, 0);
     }
@@ -4323,7 +4324,12 @@ cxx_mark_addressable (tree exp)
 
       case TARGET_EXPR:
 	TREE_ADDRESSABLE (x) = 1;
-	cxx_mark_addressable (TREE_OPERAND (x, 0));
+	cxx_mark_addressable (TARGET_EXPR_SLOT (x));
+	return true;
+
+      case COMPOUND_LITERAL_EXPR:
+	TREE_ADDRESSABLE (x) = 1;
+	cxx_mark_addressable (COMPOUND_LITERAL_EXPR_DECL (x));
 	return true;
 
       default:
@@ -5986,7 +5992,8 @@ maybe_warn_about_returning_address_of_lo
   if (TREE_CODE (valtype) == REFERENCE_TYPE)
     {
       if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
-	  || TREE_CODE (whats_returned) == TARGET_EXPR)
+	  || TREE_CODE (whats_returned) == TARGET_EXPR
+	  || TREE_CODE (whats_returned) == COMPOUND_LITERAL_EXPR)
 	{
 	  warning ("returning reference to temporary");
 	  return;
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* g++.dg/tree-ssa/pr20103.C: New test.
	* g++.dg/template/complit1.C: Expect error like ext/complit1.C.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 8 Mar 2005 21:49:29 -0000
@@ -0,0 +1,59 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}
+
+template <typename T, typename U>
+void baz(T &x)
+{
+    foo ((U){x});
+    bar ((U){x}); // { dg-error "non-const reference" }
+    bac ((U){x});
+    bap (&(U){x}); // { dg-error "address of temporary" }
+
+    foo ((const U&)(U){x});
+    bar ((U&)(U){x}); // { dg-error "invalid cast" }
+    bac ((const U&)(U){x});
+    bap (&(const U&)(U){x});
+}
+
+void bazT(A &x) {
+  baz<A,B>(x);
+}
Index: gcc/testsuite/g++.dg/template/complit1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/complit1.C,v
retrieving revision 1.3
diff -u -p -r1.3 complit1.C
--- gcc/testsuite/g++.dg/template/complit1.C 28 Dec 2002 07:48:08 -0000 1.3
+++ gcc/testsuite/g++.dg/template/complit1.C 8 Mar 2005 21:49:29 -0000
@@ -6,6 +6,6 @@ template <int D> struct C {
 };
 
 template<int D>
-C<D>::C() : d((int[]){1,2,3}) {}
+C<D>::C() : d((int[]){1,2,3}) {}  // { dg-error "assignment of arrays" }
 
-template class C<1>;
+template class C<1>; // { dg-error "instantiated from" }
Index: gcc/testsuite/g++.old-deja/g++.oliva/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* expr2.C: Fixed.

Index: gcc/testsuite/g++.old-deja/g++.oliva/expr2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.oliva/expr2.C,v
retrieving revision 1.5
diff -u -p -r1.5 expr2.C
--- gcc/testsuite/g++.old-deja/g++.oliva/expr2.C 1 May 2003 02:02:47 -0000 1.5
+++ gcc/testsuite/g++.old-deja/g++.oliva/expr2.C 8 Mar 2005 21:49:29 -0000
@@ -1,4 +1,4 @@
-// { dg-do run { xfail *-*-* } }
+// { dg-do run }
 
 // Copyright (C) 2000 Free Software Foundation
 

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (30 preceding siblings ...)
  2005-03-08 21:55 ` aoliva at redhat dot com
@ 2005-03-11 15:20 ` rth at gcc dot gnu dot org
  2005-03-11 19:29 ` aoliva at redhat dot com
                   ` (13 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: rth at gcc dot gnu dot org @ 2005-03-11 15:20 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rth at gcc dot gnu dot org  2005-03-11 15:19 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Tue, Mar 08, 2005 at 05:42:57PM -0300, Alexandre Oliva wrote:
> The change to the gimplify.c is needed to avoid having
> gimple_add_tmp_var twice for the variable, once while expanding the
> declaration/initialization, once while expanding the clean-ups.

Can you say more about how this comes to be?  It doesn't make
sense to me...


r~


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (31 preceding siblings ...)
  2005-03-11 15:20 ` rth at gcc dot gnu dot org
@ 2005-03-11 19:29 ` aoliva at redhat dot com
  2005-03-17 10:42 ` aoliva at redhat dot com
                   ` (12 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-11 19:29 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-11 19:29 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar 11, 2005, Richard Henderson <rth@gcc.gnu.org> wrote:

> On Tue, Mar 08, 2005 at 05:42:57PM -0300, Alexandre Oliva wrote:
>> The change to the gimplify.c is needed to avoid having
>> gimple_add_tmp_var twice for the variable, once while expanding the
>> declaration/initialization, once while expanding the clean-ups.

> Can you say more about how this comes to be?  It doesn't make
> sense to me...

Just a matter of misinterpreting observed behavior :-(

Here's the correct sequence of events without the change:

gimplify_compound_literal_expr calls gimple_add_tmp_var, and then
gimplify_and_add for the statement list containing the decl of the
temporary variable

gimplify_and_add calls gimplify_stmt for the stmt list, that calls
calls gimplify_expr, that calls gimplify_decl_expr, that calls
gimple_add_tmp_var again.

I should now try to figure out why it is that in C it doesn't get
called twice, in but in C++ it does.

I remember I tried to remove the first call from
gimplify_compound_literal_expr, but that didn't work because the
presence of the initializer would cause gimplify_decl_expr to build a
modify_expr referencing the decl, and this fails if the decl isn't,
erhm, bound yet.  Perhaps I should move the call to gimple_add_tmp_var
in gimplify_decl_expr before the init stmt; this even makes sense to
me.


Incidentally, we don't actually generate cleanups for these temps,
unlike the target_expr case, so we fail to call dtors for them.  Ugh.
Fixing this will take some more work.  Patch withdrawn for the time
being.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (32 preceding siblings ...)
  2005-03-11 19:29 ` aoliva at redhat dot com
@ 2005-03-17 10:42 ` aoliva at redhat dot com
  2005-03-17 11:49 ` rth at gcc dot gnu dot org
                   ` (11 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-17 10:42 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-17 10:36 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar 11, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> gimplify_and_add calls gimplify_stmt for the stmt list, that calls
> calls gimplify_expr, that calls gimplify_decl_expr, that calls
> gimple_add_tmp_var again.

I don't see any benefit in calling gimple_add_tmp_var *after*
gimplifying the initializer, so I moved the call before that, which
enabled me to get the C++-specific compound-literal-expr gimplifier to
not call gimple_add_tmp_var at all.

As for handling compound-literal-expr cleanups, this patch does so by
using target_expr gimplification code, replacing the
compound-literal-expr with a target_expr when the
compound-literal-expr is found to need a cleanup, and immediately
gimplifying that.  This avoids duplicating the code from a number of
static functions in gimplify.c, but I'm open to other approaches, such
as exporting gimple_push_cleanup from gimplify.c.

Tested on x86_64-linux-gnu.  Ok to install?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* gimplify.c (gimplify_decl_expr): Add temp variable to binding
	before gimplifying its initializer.

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.118
diff -u -p -r2.118 gimplify.c
--- gcc/gimplify.c 14 Mar 2005 20:01:40 -0000 2.118
+++ gcc/gimplify.c 17 Mar 2005 07:56:22 -0000
@@ -990,6 +990,15 @@ gimplify_decl_expr (tree *stmt_p)
     {
       tree init = DECL_INITIAL (decl);
 
+      /* 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.  c_gimplify_compound_literal_expr may
+	 have already added this tmp var, so don't do it again in this
+	 case.  */
+      if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+	gimple_add_tmp_var (decl);
+
       if (!TREE_CONSTANT (DECL_SIZE (decl)))
 	{
 	  /* This is a variable-sized decl.  Simplify its size and mark it
@@ -1043,12 +1052,6 @@ gimplify_decl_expr (tree *stmt_p)
 	       as they may contain a label address.  */
 	    walk_tree (&init, force_labels_r, NULL, NULL);
 	}
-
-      /* 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_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
-	gimple_add_tmp_var (decl);
     }
 
   return GS_ALL_DONE;
Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* cp-tree.h (build_compound_literal): Declare.
	* semantics.c (finish_compound_literal): Move most of the code...
	* tree.c (build_compound_literal): ... here.  New function.
	(lvalue_p_1): Handle COMPOUND_LITERAL_EXPR.
	(stabilize_init): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* call.c (build_over_call): Likewise.
	* class.c (fixed_type_or_null): Likewise.
	* cp-gimplify.c (cp_gimplify_init_expr): Likewise.
	(cp_gimplify_compound_literal_expr): New.
	(cp_gimplify_expr): Use it.
	* cvt.c (force_rvalue, ocp_convert): Handle COMPOUND_LITERAL_EXPR.
	* typeck.c (build_x_unary_op): Likewise.
	(cxx_mark_addressable): Likewise.
	(maybe_warn_about_returning_address_of_local): Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1110
diff -u -p -r1.1110 cp-tree.h
--- gcc/cp/cp-tree.h 14 Mar 2005 14:33:17 -0000 1.1110
+++ gcc/cp/cp-tree.h 17 Mar 2005 07:56:31 -0000
@@ -4219,6 +4219,7 @@ extern tree build_min_nt			(enum tree_co
 extern tree build_min_non_dep			(enum tree_code, tree, ...);
 extern tree build_cplus_new			(tree, tree);
 extern tree get_target_expr			(tree);
+extern tree build_compound_literal		(tree, tree);
 extern tree build_cplus_array_type		(tree, tree);
 extern tree hash_tree_cons			(tree, tree, tree);
 extern tree hash_tree_chain			(tree, tree);
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.464
diff -u -p -r1.464 semantics.c
--- gcc/cp/semantics.c 14 Mar 2005 14:33:34 -0000 1.464
+++ gcc/cp/semantics.c 17 Mar 2005 07:56:33 -0000
@@ -1980,23 +1980,16 @@ finish_compound_literal (tree type, tree
   compound_literal = build_constructor (NULL_TREE, initializer_list);
   /* Mark it as a compound-literal.  */
   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+
   if (processing_template_decl)
+    /* This causes template substitution to run digest_init on the
+       CONSTRUCTOR.  */
     TREE_TYPE (compound_literal) = type;
   else
-    {
-      /* Check the initialization.  */
-      compound_literal = digest_init (type, compound_literal, NULL);
-      /* If the TYPE was an array type with an unknown bound, then we can
-	 figure out the dimension now.  For example, something like:
-
-	   `(int []) { 2, 3 }'
-
-	 implies that the array has two elements.  */
-      if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
-	complete_array_type (type, compound_literal, 1);
-    }
+    /* Check the initialization.  */
+    compound_literal = digest_init (type, compound_literal, NULL);
 
-  return compound_literal;
+  return build_compound_literal (type, compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.427
diff -u -p -r1.427 tree.c
--- gcc/cp/tree.c 21 Feb 2005 23:12:27 -0000 1.427
+++ gcc/cp/tree.c 17 Mar 2005 07:56:35 -0000
@@ -154,6 +154,7 @@ lvalue_p_1 (tree ref,
 			 treat_class_rvalues_as_lvalues);
 
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
 
     case CALL_EXPR:
@@ -365,6 +366,43 @@ get_target_expr (tree init)
   return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the
+   compound literal, which may be an incomplete array type completed
+   by the initializer; COMPOUND_LITERAL is a CONSTRUCTOR that
+   initializes the compound literal.  */
+
+tree
+build_compound_literal (tree type, tree compound_literal)
+{
+  /* We do not use start_decl here because we have a type, not a declarator;
+     and do not use finish_decl because the decl should be stored inside
+     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
+  tree decl;
+  tree complit;
+  tree stmt;
+
+  if (type == error_mark_node || compound_literal == error_mark_node)
+    return error_mark_node;
+
+  /* If the TYPE was an array type with an unknown bound, then we can
+     figure out the dimension now.  For example, something like:
+
+     `(int []) { 2, 3 }'
+
+     implies that the array has two elements.  */
+  if (!processing_template_decl
+      && TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+    complete_array_type (type, compound_literal, 1);
+
+  decl = build_local_temp (type);
+  DECL_INITIAL (decl) = compound_literal;
+
+  stmt = build_stmt (DECL_EXPR, decl);
+  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  TREE_SIDE_EFFECTS (complit) = 1;
+
+  return complit;
+}
 \f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
@@ -2241,6 +2279,8 @@ stabilize_init (tree init, tree *initp)
 	t = TREE_OPERAND (t, 1);
       if (TREE_CODE (t) == TARGET_EXPR)
 	t = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (t) == COMPOUND_LITERAL_EXPR)
+	t = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t));
       if (TREE_CODE (t) == COMPOUND_EXPR)
 	t = expr_last (t);
       if (TREE_CODE (t) == CONSTRUCTOR
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.984
diff -u -p -r1.984 pt.c
--- gcc/cp/pt.c 14 Mar 2005 14:51:14 -0000 1.984
+++ gcc/cp/pt.c 17 Mar 2005 07:56:42 -0000
@@ -8832,6 +8832,11 @@ tsubst_copy_and_build (tree t, 
       return build_throw
 	(RECUR (TREE_OPERAND (t, 0)));
 
+    case COMPOUND_LITERAL_EXPR:
+      return build_compound_literal
+	(RECUR (TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (t))),
+	 RECUR (DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t))));
+
     case CONSTRUCTOR:
       {
 	tree r;
Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.531
diff -u -p -r1.531 call.c
--- gcc/cp/call.c 24 Feb 2005 21:55:10 -0000 1.531
+++ gcc/cp/call.c 17 Mar 2005 07:56:46 -0000
@@ -4850,12 +4850,14 @@ build_over_call (struct z_candidate *can
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
 	{
-	  if (TREE_CODE (arg) == TARGET_EXPR)
+	  if (TREE_CODE (arg) == TARGET_EXPR
+	      || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
 	    return arg;
 	  else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	    return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
 	}
       else if (TREE_CODE (arg) == TARGET_EXPR
+	       || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR
 	       || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	{
 	  tree to = stabilize_reference
Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.709
diff -u -p -r1.709 class.c
--- gcc/cp/class.c 7 Mar 2005 23:08:57 -0000 1.709
+++ gcc/cp/class.c 17 Mar 2005 07:56:52 -0000
@@ -5234,6 +5234,7 @@ fixed_type_or_null (tree instance, int* 
 	}
       /* fall through...  */
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.17
diff -u -p -r1.17 cp-gimplify.c
--- gcc/cp/cp-gimplify.c 22 Dec 2004 18:00:38 -0000 1.17
+++ gcc/cp/cp-gimplify.c 17 Mar 2005 07:56:52 -0000
@@ -1,6 +1,6 @@
 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@redhat.com>
 
 This file is part of GCC.
@@ -125,6 +125,8 @@ cp_gimplify_init_expr (tree *expr_p, tre
     from = TARGET_EXPR_INITIAL (from);
   if (TREE_CODE (from) == CLEANUP_POINT_EXPR)
     from = TREE_OPERAND (from, 0);
+  if (TREE_CODE (from) == COMPOUND_LITERAL_EXPR)
+    from = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (from));
 
   /* Look through any COMPOUND_EXPRs.  */
   sub = expr_last (from);
@@ -170,6 +172,32 @@ gimplify_must_not_throw_expr (tree *expr
     *expr_p = stmt;
 }
 
+/* Gimplify a compound literal expression.  This just means adding the
+   DECL_EXPR before the current EXPR_STMT and using its anonymous decl
+   instead, unless cleanups are needed.  */
+
+static enum gimplify_status
+cp_gimplify_compound_literal_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
+  tree decl = DECL_EXPR_DECL (decl_s);
+  tree init = DECL_INITIAL (decl);
+  tree cleanup = cxx_maybe_build_cleanup (decl);
+  
+  if (cleanup)
+    {
+      DECL_INITIAL (decl) = NULL_TREE;
+      *expr_p = build4 (TARGET_EXPR, TREE_TYPE (decl), decl,
+			init, cleanup, NULL_TREE);
+      return gimplify_expr (expr_p, pre_p, post_p, is_gimple_val, fb_rvalue);
+    }
+
+  /* If no cleanups are needed, we can do things in a simpler way.  */
+  gimplify_and_add (decl_s, pre_p);
+  *expr_p = decl;
+  return GS_OK;
+}
+
 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
 
 int
@@ -254,6 +282,11 @@ cp_gimplify_expr (tree *expr_p, tree *pr
       ret = GS_OK;
       break;
 
+    case COMPOUND_LITERAL_EXPR:
+      cp_gimplify_compound_literal_expr (expr_p, pre_p, post_p);
+      ret = GS_OK;
+      break;
+
     default:
       ret = c_gimplify_expr (expr_p, pre_p, post_p);
       break;
Index: gcc/cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.180
diff -u -p -r1.180 cvt.c
--- gcc/cp/cvt.c 9 Feb 2005 02:53:37 -0000 1.180
+++ gcc/cp/cvt.c 17 Mar 2005 07:56:53 -0000
@@ -575,7 +575,8 @@ convert_from_reference (tree val)
 tree
 force_rvalue (tree expr)
 {
-  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR)
+  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR
+      && TREE_CODE (expr) != COMPOUND_LITERAL_EXPR)
     expr = ocp_convert (TREE_TYPE (expr), expr,
 			CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
@@ -640,6 +641,16 @@ ocp_convert (tree type, tree expr, int c
 	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
 	  return e;
 	}
+      else if (TREE_CODE (e) == COMPOUND_LITERAL_EXPR)
+	{
+	  /* Don't build a NOP_EXPR of class type.  Instead, change the
+	     type of the temporary.  Only allow this for cv-qual changes,
+	     though.  */
+	  gcc_assert (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
+				   TYPE_MAIN_VARIANT (type)));
+	  TREE_TYPE (e) = TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (e)) = type;
+	  return e;
+	}	  
       else
 	{
 	  /* We shouldn't be treating objects of ADDRESSABLE type as
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.618
diff -u -p -r1.618 typeck.c
--- gcc/cp/typeck.c 9 Mar 2005 07:28:10 -0000 1.618
+++ gcc/cp/typeck.c 17 Mar 2005 07:56:57 -0000
@@ -3574,7 +3574,8 @@ build_x_unary_op (enum tree_code code, t
 	      PTRMEM_OK_P (xarg) = ptrmem;
 	    }	      
         }
-      else if (TREE_CODE (xarg) == TARGET_EXPR)
+      else if (TREE_CODE (xarg) == TARGET_EXPR
+	       || TREE_CODE (xarg) == COMPOUND_LITERAL_EXPR)
 	warning ("taking address of temporary");
       exp = build_unary_op (ADDR_EXPR, xarg, 0);
     }
@@ -4307,7 +4308,12 @@ cxx_mark_addressable (tree exp)
 
       case TARGET_EXPR:
 	TREE_ADDRESSABLE (x) = 1;
-	cxx_mark_addressable (TREE_OPERAND (x, 0));
+	cxx_mark_addressable (TARGET_EXPR_SLOT (x));
+	return true;
+
+      case COMPOUND_LITERAL_EXPR:
+	TREE_ADDRESSABLE (x) = 1;
+	cxx_mark_addressable (COMPOUND_LITERAL_EXPR_DECL (x));
 	return true;
 
       default:
@@ -5970,7 +5976,8 @@ maybe_warn_about_returning_address_of_lo
   if (TREE_CODE (valtype) == REFERENCE_TYPE)
     {
       if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
-	  || TREE_CODE (whats_returned) == TARGET_EXPR)
+	  || TREE_CODE (whats_returned) == TARGET_EXPR
+	  || TREE_CODE (whats_returned) == COMPOUND_LITERAL_EXPR)
 	{
 	  warning ("returning reference to temporary");
 	  return;
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* g++.dg/tree-ssa/pr20103.C: New test.
	* g++.dg/template/complit1.C: Expect error like ext/complit1.C.
	* g++.dg/ext/complit4.C: New test.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 17 Mar 2005 07:57:11 -0000
@@ -0,0 +1,59 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}
+
+template <typename T, typename U>
+void baz(T &x)
+{
+    foo ((U){x});
+    bar ((U){x}); // { dg-error "non-const reference" }
+    bac ((U){x});
+    bap (&(U){x}); // { dg-error "address of temporary" }
+
+    foo ((const U&)(U){x});
+    bar ((U&)(U){x}); // { dg-error "invalid cast" }
+    bac ((const U&)(U){x});
+    bap (&(const U&)(U){x});
+}
+
+void bazT(A &x) {
+  baz<A,B>(x);
+}
Index: gcc/testsuite/g++.dg/template/complit1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/complit1.C,v
retrieving revision 1.3
diff -u -p -r1.3 complit1.C
--- gcc/testsuite/g++.dg/template/complit1.C 28 Dec 2002 07:48:08 -0000 1.3
+++ gcc/testsuite/g++.dg/template/complit1.C 17 Mar 2005 07:57:11 -0000
@@ -6,6 +6,6 @@ template <int D> struct C {
 };
 
 template<int D>
-C<D>::C() : d((int[]){1,2,3}) {}
+C<D>::C() : d((int[]){1,2,3}) {}  // { dg-error "assignment of arrays" }
 
-template class C<1>;
+template class C<1>; // { dg-error "instantiated from" }
Index: gcc/testsuite/g++.dg/ext/complit4.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/complit4.C
diff -N gcc/testsuite/g++.dg/ext/complit4.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/complit4.C 17 Mar 2005 07:57:11 -0000
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "" }
+// { dg-final { scan-assembler "_ZN1sD1Ev.*_ZN1sD1Ev.*_ZN1sD1Ev" } }
+
+// Make sure we issue 3 dtor calls: one for the t::x, one for the s
+// temporary in normal execution flow and one for the same s temporary
+// in the EH cleanup should the dtor of t::x throw.
+
+struct s {
+  int i;
+  ~s();
+};
+
+struct t {
+  s x;
+  ~t() {}
+};
+
+void f () {
+  (t){(s){1}};
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (33 preceding siblings ...)
  2005-03-17 10:42 ` aoliva at redhat dot com
@ 2005-03-17 11:49 ` rth at gcc dot gnu dot org
  2005-03-18  5:39 ` aoliva at redhat dot com
                   ` (10 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: rth at gcc dot gnu dot org @ 2005-03-17 11:49 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rth at gcc dot gnu dot org  2005-03-17 11:49 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Thu, Mar 17, 2005 at 05:11:08AM -0300, Alexandre Oliva wrote:
> 	* gimplify.c (gimplify_decl_expr): Add temp variable to binding
> 	before gimplifying its initializer.

Ok.

> +cp_gimplify_compound_literal_expr (tree *expr_p, tree *pre_p, tree *post_p)
> +{
> +  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
> +  tree decl = DECL_EXPR_DECL (decl_s);
> +  tree init = DECL_INITIAL (decl);
> +  tree cleanup = cxx_maybe_build_cleanup (decl);
> +  
> +  if (cleanup)
> +    {
> +      DECL_INITIAL (decl) = NULL_TREE;
> +      *expr_p = build4 (TARGET_EXPR, TREE_TYPE (decl), decl,
> +			init, cleanup, NULL_TREE);
> +      return gimplify_expr (expr_p, pre_p, post_p, is_gimple_val, fb_rvalue);

You don't need to recurse here.  Just return GS_OK.

> +  /* If no cleanups are needed, we can do things in a simpler way.  */
> +  gimplify_and_add (decl_s, pre_p);
> +  *expr_p = decl;
> +  return GS_OK;

If you've simplified to a decl, you can return GS_ALL_DONE.

> +    case COMPOUND_LITERAL_EXPR:
> +      cp_gimplify_compound_literal_expr (expr_p, pre_p, post_p);
> +      ret = GS_OK;

Should be "ret = cp_gimplify_compound_literal_expr (...)".

> +// { dg-final { scan-assembler "_ZN1sD1Ev.*_ZN1sD1Ev.*_ZN1sD1Ev" } }
> +
> +// Make sure we issue 3 dtor calls: one for the t::x, one for the s
> +// temporary in normal execution flow and one for the same s temporary
> +// in the EH cleanup should the dtor of t::x throw.

Wouldn't it be a lot safer to make this a run test instead?


r~


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (34 preceding siblings ...)
  2005-03-17 11:49 ` rth at gcc dot gnu dot org
@ 2005-03-18  5:39 ` aoliva at redhat dot com
  2005-03-18 10:16 ` aoliva at redhat dot com
                   ` (9 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-18  5:39 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-18 05:38 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar 17, 2005, Richard Henderson <rth@gcc.gnu.org> wrote:

> On Thu, Mar 17, 2005 at 05:11:08AM -0300, Alexandre Oliva wrote:
>> * gimplify.c (gimplify_decl_expr): Add temp variable to binding
>> before gimplifying its initializer.

> Ok.

>> +cp_gimplify_compound_literal_expr (tree *expr_p, tree *pre_p, tree *post_p)

>> +      return gimplify_expr (expr_p, pre_p, post_p, is_gimple_val, fb_rvalue);

> You don't need to recurse here.  Just return GS_OK.

Neat!

>> +  /* If no cleanups are needed, we can do things in a simpler way.  */
>> +  gimplify_and_add (decl_s, pre_p);
>> +  *expr_p = decl;
>> +  return GS_OK;

> If you've simplified to a decl, you can return GS_ALL_DONE.

Cool!  I've now made the same change to the function in c-gimplify.c
that handles compound literal exprs, from which I'd copied this code.

>> +    case COMPOUND_LITERAL_EXPR:
>> +      cp_gimplify_compound_literal_expr (expr_p, pre_p, post_p);
>> +      ret = GS_OK;

> Should be "ret = cp_gimplify_compound_literal_expr (...)".

Doh.  One shouldn't change the return type of a function from void to
something else without checking existing calls, even ones introduced
in the same patch :-/

>> +// { dg-final { scan-assembler "_ZN1sD1Ev.*_ZN1sD1Ev.*_ZN1sD1Ev" } }
>> +
>> +// Make sure we issue 3 dtor calls: one for the t::x, one for the s
>> +// temporary in normal execution flow and one for the same s temporary
>> +// in the EH cleanup should the dtor of t::x throw.

> Wouldn't it be a lot safer to make this a run test instead?

Indeed.  Done.

Here's the latest revision of the patch, yet to be bootstrapped and
tested on x86_64-linux-gnu.  Hopefully my box won't hang overnight
again :-(  It's giving me a lot of grief, but I still haven't figured
out what's wrong with it.  Could be the FCdevel kernel built with gcc4
exposing bugs in usb2 or firewire disk drivers, or the internal ide HD
that a few weeks ago looked like it was going to die but then
apparently changed its mind :-(

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* gimplify.c (gimplify_decl_expr): Add temp variable to binding
	before gimplifying its initializer.
	* c-gimplify.c (gimplify_compound_literal_expr): After replacing
	the expr with a decl, we're all done.

Index: gcc/gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.118
diff -u -p -r2.118 gimplify.c
--- gcc/gimplify.c 14 Mar 2005 20:01:40 -0000 2.118
+++ gcc/gimplify.c 18 Mar 2005 05:30:03 -0000
@@ -990,6 +990,15 @@ gimplify_decl_expr (tree *stmt_p)
     {
       tree init = DECL_INITIAL (decl);
 
+      /* 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.  c_gimplify_compound_literal_expr may
+	 have already added this tmp var, so don't do it again in this
+	 case.  */
+      if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+	gimple_add_tmp_var (decl);
+
       if (!TREE_CONSTANT (DECL_SIZE (decl)))
 	{
 	  /* This is a variable-sized decl.  Simplify its size and mark it
@@ -1043,12 +1052,6 @@ gimplify_decl_expr (tree *stmt_p)
 	       as they may contain a label address.  */
 	    walk_tree (&init, force_labels_r, NULL, NULL);
 	}
-
-      /* 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_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
-	gimple_add_tmp_var (decl);
     }
 
   return GS_ALL_DONE;
Index: gcc/c-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-gimplify.c,v
retrieving revision 2.26
diff -u -p -r2.26 c-gimplify.c
--- gcc/c-gimplify.c 27 Jan 2005 18:22:19 -0000 2.26
+++ gcc/c-gimplify.c 18 Mar 2005 05:29:53 -0000
@@ -487,7 +487,7 @@ gimplify_compound_literal_expr (tree *ex
 
   gimplify_and_add (decl_s, pre_p);
   *expr_p = decl;
-  return GS_OK;
+  return GS_ALL_DONE;
 }
 
 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* cp-tree.h (build_compound_literal): Declare.
	* semantics.c (finish_compound_literal): Move most of the code...
	* tree.c (build_compound_literal): ... here.  New function.
	(lvalue_p_1): Handle COMPOUND_LITERAL_EXPR.
	(stabilize_init): Likewise.
	* pt.c (tsubst_copy_and_build): Likewise.
	* call.c (build_over_call): Likewise.
	* class.c (fixed_type_or_null): Likewise.
	* cp-gimplify.c (cp_gimplify_init_expr): Likewise.
	(cp_gimplify_compound_literal_expr): New.
	(cp_gimplify_expr): Use it.
	* cvt.c (force_rvalue, ocp_convert): Handle COMPOUND_LITERAL_EXPR.
	* typeck.c (build_x_unary_op): Likewise.
	(cxx_mark_addressable): Likewise.
	(maybe_warn_about_returning_address_of_local): Likewise.

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1111
diff -u -p -r1.1111 cp-tree.h
--- gcc/cp/cp-tree.h 17 Mar 2005 14:37:04 -0000 1.1111
+++ gcc/cp/cp-tree.h 18 Mar 2005 05:30:12 -0000
@@ -4219,6 +4219,7 @@ extern tree build_min_nt			(enum tree_co
 extern tree build_min_non_dep			(enum tree_code, tree, ...);
 extern tree build_cplus_new			(tree, tree);
 extern tree get_target_expr			(tree);
+extern tree build_compound_literal		(tree, tree);
 extern tree build_cplus_array_type		(tree, tree);
 extern tree hash_tree_cons			(tree, tree, tree);
 extern tree hash_tree_chain			(tree, tree);
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.464
diff -u -p -r1.464 semantics.c
--- gcc/cp/semantics.c 14 Mar 2005 14:33:34 -0000 1.464
+++ gcc/cp/semantics.c 18 Mar 2005 05:30:14 -0000
@@ -1980,23 +1980,16 @@ finish_compound_literal (tree type, tree
   compound_literal = build_constructor (NULL_TREE, initializer_list);
   /* Mark it as a compound-literal.  */
   TREE_HAS_CONSTRUCTOR (compound_literal) = 1;
+
   if (processing_template_decl)
+    /* This causes template substitution to run digest_init on the
+       CONSTRUCTOR.  */
     TREE_TYPE (compound_literal) = type;
   else
-    {
-      /* Check the initialization.  */
-      compound_literal = digest_init (type, compound_literal, NULL);
-      /* If the TYPE was an array type with an unknown bound, then we can
-	 figure out the dimension now.  For example, something like:
-
-	   `(int []) { 2, 3 }'
-
-	 implies that the array has two elements.  */
-      if (TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
-	complete_array_type (type, compound_literal, 1);
-    }
+    /* Check the initialization.  */
+    compound_literal = digest_init (type, compound_literal, NULL);
 
-  return compound_literal;
+  return build_compound_literal (type, compound_literal);
 }
 
 /* Return the declaration for the function-name variable indicated by
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.427
diff -u -p -r1.427 tree.c
--- gcc/cp/tree.c 21 Feb 2005 23:12:27 -0000 1.427
+++ gcc/cp/tree.c 18 Mar 2005 05:30:16 -0000
@@ -154,6 +154,7 @@ lvalue_p_1 (tree ref,
 			 treat_class_rvalues_as_lvalues);
 
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
       return treat_class_rvalues_as_lvalues ? clk_class : clk_none;
 
     case CALL_EXPR:
@@ -365,6 +366,43 @@ get_target_expr (tree init)
   return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
+/* Build a COMPOUND_LITERAL_EXPR.  TYPE is the type given in the
+   compound literal, which may be an incomplete array type completed
+   by the initializer; COMPOUND_LITERAL is a CONSTRUCTOR that
+   initializes the compound literal.  */
+
+tree
+build_compound_literal (tree type, tree compound_literal)
+{
+  /* We do not use start_decl here because we have a type, not a declarator;
+     and do not use finish_decl because the decl should be stored inside
+     the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR.  */
+  tree decl;
+  tree complit;
+  tree stmt;
+
+  if (type == error_mark_node || compound_literal == error_mark_node)
+    return error_mark_node;
+
+  /* If the TYPE was an array type with an unknown bound, then we can
+     figure out the dimension now.  For example, something like:
+
+     `(int []) { 2, 3 }'
+
+     implies that the array has two elements.  */
+  if (!processing_template_decl
+      && TREE_CODE (type) == ARRAY_TYPE && !COMPLETE_TYPE_P (type))
+    complete_array_type (type, compound_literal, 1);
+
+  decl = build_local_temp (type);
+  DECL_INITIAL (decl) = compound_literal;
+
+  stmt = build_stmt (DECL_EXPR, decl);
+  complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
+  TREE_SIDE_EFFECTS (complit) = 1;
+
+  return complit;
+}
 \f
 static tree
 build_cplus_array_type_1 (tree elt_type, tree index_type)
@@ -2241,6 +2279,8 @@ stabilize_init (tree init, tree *initp)
 	t = TREE_OPERAND (t, 1);
       if (TREE_CODE (t) == TARGET_EXPR)
 	t = TARGET_EXPR_INITIAL (t);
+      if (TREE_CODE (t) == COMPOUND_LITERAL_EXPR)
+	t = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t));
       if (TREE_CODE (t) == COMPOUND_EXPR)
 	t = expr_last (t);
       if (TREE_CODE (t) == CONSTRUCTOR
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.985
diff -u -p -r1.985 pt.c
--- gcc/cp/pt.c 17 Mar 2005 13:26:39 -0000 1.985
+++ gcc/cp/pt.c 18 Mar 2005 05:30:23 -0000
@@ -8785,6 +8785,11 @@ tsubst_copy_and_build (tree t, 
       return build_throw
 	(RECUR (TREE_OPERAND (t, 0)));
 
+    case COMPOUND_LITERAL_EXPR:
+      return build_compound_literal
+	(RECUR (TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (t))),
+	 RECUR (DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (t))));
+
     case CONSTRUCTOR:
       {
 	tree r;
Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.531
diff -u -p -r1.531 call.c
--- gcc/cp/call.c 24 Feb 2005 21:55:10 -0000 1.531
+++ gcc/cp/call.c 18 Mar 2005 05:30:27 -0000
@@ -4850,12 +4898,14 @@ build_over_call (struct z_candidate *can
          temp or an INIT_EXPR otherwise.  */
       if (integer_zerop (TREE_VALUE (args)))
 	{
-	  if (TREE_CODE (arg) == TARGET_EXPR)
+	  if (TREE_CODE (arg) == TARGET_EXPR
+	      || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
 	    return arg;
 	  else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	    return build_target_expr_with_type (arg, DECL_CONTEXT (fn));
 	}
       else if (TREE_CODE (arg) == TARGET_EXPR
+	       || TREE_CODE (arg) == COMPOUND_LITERAL_EXPR
 	       || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn)))
 	{
 	  tree to = stabilize_reference
Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.709
diff -u -p -r1.709 class.c
--- gcc/cp/class.c 7 Mar 2005 23:08:57 -0000 1.709
+++ gcc/cp/class.c 18 Mar 2005 05:30:32 -0000
@@ -5234,6 +5234,7 @@ fixed_type_or_null (tree instance, int* 
 	}
       /* fall through...  */
     case TARGET_EXPR:
+    case COMPOUND_LITERAL_EXPR:
     case PARM_DECL:
     case RESULT_DECL:
       if (IS_AGGR_TYPE (TREE_TYPE (instance)))
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.17
diff -u -p -r1.17 cp-gimplify.c
--- gcc/cp/cp-gimplify.c 22 Dec 2004 18:00:38 -0000 1.17
+++ gcc/cp/cp-gimplify.c 18 Mar 2005 05:30:32 -0000
@@ -1,6 +1,6 @@
 /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
 
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Jason Merrill <jason@redhat.com>
 
 This file is part of GCC.
@@ -125,6 +125,8 @@ cp_gimplify_init_expr (tree *expr_p, tre
     from = TARGET_EXPR_INITIAL (from);
   if (TREE_CODE (from) == CLEANUP_POINT_EXPR)
     from = TREE_OPERAND (from, 0);
+  if (TREE_CODE (from) == COMPOUND_LITERAL_EXPR)
+    from = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (from));
 
   /* Look through any COMPOUND_EXPRs.  */
   sub = expr_last (from);
@@ -170,6 +172,32 @@ gimplify_must_not_throw_expr (tree *expr
     *expr_p = stmt;
 }
 
+/* Gimplify a compound literal expression.  This just means adding the
+   DECL_EXPR before the current EXPR_STMT and using its anonymous decl
+   instead, unless cleanups are needed.  */
+
+static enum gimplify_status
+cp_gimplify_compound_literal_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
+  tree decl = DECL_EXPR_DECL (decl_s);
+  tree init = DECL_INITIAL (decl);
+  tree cleanup = cxx_maybe_build_cleanup (decl);
+  
+  if (cleanup)
+    {
+      DECL_INITIAL (decl) = NULL_TREE;
+      *expr_p = build4 (TARGET_EXPR, TREE_TYPE (decl), decl,
+			init, cleanup, NULL_TREE);
+      return GS_OK;
+    }
+
+  /* If no cleanups are needed, we can do things in a simpler way.  */
+  gimplify_and_add (decl_s, pre_p);
+  *expr_p = decl;
+  return GS_ALL_DONE;
+}
+
 /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
 
 int
@@ -254,6 +282,10 @@ cp_gimplify_expr (tree *expr_p, tree *pr
       ret = GS_OK;
       break;
 
+    case COMPOUND_LITERAL_EXPR:
+      ret = cp_gimplify_compound_literal_expr (expr_p, pre_p, post_p);
+      break;
+
     default:
       ret = c_gimplify_expr (expr_p, pre_p, post_p);
       break;
Index: gcc/cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.180
diff -u -p -r1.180 cvt.c
--- gcc/cp/cvt.c 9 Feb 2005 02:53:37 -0000 1.180
+++ gcc/cp/cvt.c 18 Mar 2005 05:30:33 -0000
@@ -575,7 +575,8 @@ convert_from_reference (tree val)
 tree
 force_rvalue (tree expr)
 {
-  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR)
+  if (IS_AGGR_TYPE (TREE_TYPE (expr)) && TREE_CODE (expr) != TARGET_EXPR
+      && TREE_CODE (expr) != COMPOUND_LITERAL_EXPR)
     expr = ocp_convert (TREE_TYPE (expr), expr,
 			CONV_IMPLICIT|CONV_FORCE_TEMP, LOOKUP_NORMAL);
   else
@@ -640,6 +641,16 @@ ocp_convert (tree type, tree expr, int c
 	  TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
 	  return e;
 	}
+      else if (TREE_CODE (e) == COMPOUND_LITERAL_EXPR)
+	{
+	  /* Don't build a NOP_EXPR of class type.  Instead, change the
+	     type of the temporary.  Only allow this for cv-qual changes,
+	     though.  */
+	  gcc_assert (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)),
+				   TYPE_MAIN_VARIANT (type)));
+	  TREE_TYPE (e) = TREE_TYPE (COMPOUND_LITERAL_EXPR_DECL (e)) = type;
+	  return e;
+	}	  
       else
 	{
 	  /* We shouldn't be treating objects of ADDRESSABLE type as
Index: gcc/cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.618
diff -u -p -r1.618 typeck.c
--- gcc/cp/typeck.c 9 Mar 2005 07:28:10 -0000 1.618
+++ gcc/cp/typeck.c 18 Mar 2005 05:30:37 -0000
@@ -3574,7 +3574,8 @@ build_x_unary_op (enum tree_code code, t
 	      PTRMEM_OK_P (xarg) = ptrmem;
 	    }	      
         }
-      else if (TREE_CODE (xarg) == TARGET_EXPR)
+      else if (TREE_CODE (xarg) == TARGET_EXPR
+	       || TREE_CODE (xarg) == COMPOUND_LITERAL_EXPR)
 	warning ("taking address of temporary");
       exp = build_unary_op (ADDR_EXPR, xarg, 0);
     }
@@ -4307,7 +4308,12 @@ cxx_mark_addressable (tree exp)
 
       case TARGET_EXPR:
 	TREE_ADDRESSABLE (x) = 1;
-	cxx_mark_addressable (TREE_OPERAND (x, 0));
+	cxx_mark_addressable (TARGET_EXPR_SLOT (x));
+	return true;
+
+      case COMPOUND_LITERAL_EXPR:
+	TREE_ADDRESSABLE (x) = 1;
+	cxx_mark_addressable (COMPOUND_LITERAL_EXPR_DECL (x));
 	return true;
 
       default:
@@ -5970,7 +5976,8 @@ maybe_warn_about_returning_address_of_lo
   if (TREE_CODE (valtype) == REFERENCE_TYPE)
     {
       if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
-	  || TREE_CODE (whats_returned) == TARGET_EXPR)
+	  || TREE_CODE (whats_returned) == TARGET_EXPR
+	  || TREE_CODE (whats_returned) == COMPOUND_LITERAL_EXPR)
 	{
 	  warning ("returning reference to temporary");
 	  return;
Index: gcc/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR c++/20103
	* g++.dg/tree-ssa/pr20103.C: New test.
	* g++.dg/template/complit1.C: Expect error like ext/complit1.C.
	* g++.dg/ext/complit4.C: New test.

Index: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
===================================================================
RCS file: gcc/testsuite/g++.dg/tree-ssa/pr20103.C
diff -N gcc/testsuite/g++.dg/tree-ssa/pr20103.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/tree-ssa/pr20103.C 18 Mar 2005 05:30:51 -0000
@@ -0,0 +1,59 @@
+// PR c++/20103
+
+// { dg-do compile }
+
+// { dg-options "" }
+
+// Gimplification used to fail for (B){x}, because create_tmp_var
+// required a non-addressable type, and we didn't wrap the constructor
+// in a target_expr, ensuring it's moved to a separate decl.
+
+// Whether it is an lvalue, like in C, or an rvalue, is up to the ISO
+// C++ Commitete to decide in the second version of the C++ Standard.
+// We're going with rvalues for now.
+
+struct A
+{
+    A(const A&);
+};
+
+struct B
+{
+    A a;
+};
+
+void foo(B);
+void bar(B&); // { dg-error "in passing argument" }
+void bac(const B&);
+void bap(const B*);
+
+void baz(A &x)
+{
+    foo ((B){x});
+    bar ((B){x}); // { dg-error "non-const reference" }
+    bac ((B){x});
+    bap (&(B){x}); // { dg-error "address of temporary" }
+
+    foo ((const B&)(B){x});
+    bar ((B&)(B){x}); // { dg-error "invalid cast" }
+    bac ((const B&)(B){x});
+    bap (&(const B&)(B){x});
+}
+
+template <typename T, typename U>
+void baz(T &x)
+{
+    foo ((U){x});
+    bar ((U){x}); // { dg-error "non-const reference" }
+    bac ((U){x});
+    bap (&(U){x}); // { dg-error "address of temporary" }
+
+    foo ((const U&)(U){x});
+    bar ((U&)(U){x}); // { dg-error "invalid cast" }
+    bac ((const U&)(U){x});
+    bap (&(const U&)(U){x});
+}
+
+void bazT(A &x) {
+  baz<A,B>(x);
+}
Index: gcc/testsuite/g++.dg/template/complit1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/template/complit1.C,v
retrieving revision 1.3
diff -u -p -r1.3 complit1.C
--- gcc/testsuite/g++.dg/template/complit1.C 28 Dec 2002 07:48:08 -0000 1.3
+++ gcc/testsuite/g++.dg/template/complit1.C 18 Mar 2005 05:30:51 -0000
@@ -6,6 +6,6 @@ template <int D> struct C {
 };
 
 template<int D>
-C<D>::C() : d((int[]){1,2,3}) {}
+C<D>::C() : d((int[]){1,2,3}) {}  // { dg-error "assignment of arrays" }
 
-template class C<1>;
+template class C<1>; // { dg-error "instantiated from" }
Index: gcc/testsuite/g++.dg/ext/complit4.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/complit4.C
diff -N gcc/testsuite/g++.dg/ext/complit4.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/complit4.C 18 Mar 2005 05:30:51 -0000
@@ -0,0 +1,44 @@
+// { dg-do run }
+// { dg-options "" }
+
+// Make sure we issue dtor calls for t::x, and for the s temporary
+// used to construct it, in normal and eh-cleanup control flows.
+
+#include <stdlib.h>
+
+static int s_dtor_count = 0;
+static bool t_dtor_throws = false;
+
+struct s {
+  int i;
+  ~s() {
+    s_dtor_count++;
+  }
+};
+
+struct t {
+  s x;
+  ~t() {
+    if (t_dtor_throws)
+      throw s_dtor_count;
+  }
+};
+
+int main () {
+  s_dtor_count = 0;
+  (t){(s){1}};
+  if (s_dtor_count != 2)
+    abort ();
+
+  try {
+    t_dtor_throws = true;
+    s_dtor_count = 0;
+    (t){(s){1}};
+    abort ();
+  } catch (int saved_s_dtor_count) {
+    if (s_dtor_count != 2)
+      abort ();
+    if (saved_s_dtor_count != 0)
+      abort ();
+  }
+}

-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (35 preceding siblings ...)
  2005-03-18  5:39 ` aoliva at redhat dot com
@ 2005-03-18 10:16 ` aoliva at redhat dot com
  2005-04-02 17:27 ` aoliva at redhat dot com
                   ` (8 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-03-18 10:16 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-03-18 10:14 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar 18, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Mar 17, 2005, Richard Henderson <rth@gcc.gnu.org> wrote:
>>> +cp_gimplify_compound_literal_expr (tree *expr_p, tree *pre_p, tree *post_p)

>>> +      return gimplify_expr (expr_p, pre_p, post_p, is_gimple_val, fb_rvalue);

>> You don't need to recurse here.  Just return GS_OK.

> Neat!

FWIW, removing the recursion enabled me to remove the post_p argument
as well, but I only realized that after posting the patch.  I'm not
reposting it right now for this trivial reason, but consider the
patch with this additional change.



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (36 preceding siblings ...)
  2005-03-18 10:16 ` aoliva at redhat dot com
@ 2005-04-02 17:27 ` aoliva at redhat dot com
  2005-04-05 14:47 ` pinskia at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-04-02 17:27 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-04-02 17:27 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Mar 18, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> Index: gcc/ChangeLog
> from  Alexandre Oliva  <aoliva@redhat.com>

> 	PR c++/20103
> 	* gimplify.c (gimplify_decl_expr): Add temp variable to binding
> 	before gimplifying its initializer.
> 	* c-gimplify.c (gimplify_compound_literal_expr): After replacing
> 	the expr with a decl, we're all done.

> Index: gcc/cp/ChangeLog
> from  Alexandre Oliva  <aoliva@redhat.com>

> 	PR c++/20103
> 	* cp-tree.h (build_compound_literal): Declare.
> 	* semantics.c (finish_compound_literal): Move most of the code...
> 	* tree.c (build_compound_literal): ... here.  New function.
> 	(lvalue_p_1): Handle COMPOUND_LITERAL_EXPR.
> 	(stabilize_init): Likewise.
> 	* pt.c (tsubst_copy_and_build): Likewise.
> 	* call.c (build_over_call): Likewise.
> 	* class.c (fixed_type_or_null): Likewise.
> 	* cp-gimplify.c (cp_gimplify_init_expr): Likewise.
> 	(cp_gimplify_compound_literal_expr): New.
> 	(cp_gimplify_expr): Use it.
> 	* cvt.c (force_rvalue, ocp_convert): Handle COMPOUND_LITERAL_EXPR.
> 	* typeck.c (build_x_unary_op): Likewise.
> 	(cxx_mark_addressable): Likewise.
> 	(maybe_warn_about_returning_address_of_local): Likewise.

Ping?

http://gcc.gnu.org/PR20103



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (37 preceding siblings ...)
  2005-04-02 17:27 ` aoliva at redhat dot com
@ 2005-04-05 14:47 ` pinskia at gcc dot gnu dot org
  2005-04-17  3:57 ` mmitchel at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-04-05 14:47 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |critical


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (38 preceding siblings ...)
  2005-04-05 14:47 ` pinskia at gcc dot gnu dot org
@ 2005-04-17  3:57 ` mmitchel at gcc dot gnu dot org
  2005-04-17  3:59 ` aoliva at redhat dot com
                   ` (5 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2005-04-17  3:57 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mmitchel at gcc dot gnu dot org  2005-04-17 03:57 -------
Alexandre, I dropped the ball here.  This patch is too much buck for not enough
bang for 4.0.0, but I will review it for 4.0.1.

Target milestone changed to 4.0.1.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|4.0.0                       |4.0.1


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (39 preceding siblings ...)
  2005-04-17  3:57 ` mmitchel at gcc dot gnu dot org
@ 2005-04-17  3:59 ` aoliva at redhat dot com
  2005-04-17  4:03 ` mark at codesourcery dot com
                   ` (4 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-04-17  3:59 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-04-17 03:59 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

Mark, did you give up on COMPOUND_LITERAL_EXPRs in C++ for 4.0?  The
C++ portion of the patch at http://gcc.gnu.org/PR20103 is still
awaiting review even for mainline :-(



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (40 preceding siblings ...)
  2005-04-17  3:59 ` aoliva at redhat dot com
@ 2005-04-17  4:03 ` mark at codesourcery dot com
  2005-04-17  6:25 ` aoliva at redhat dot com
                   ` (3 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: mark at codesourcery dot com @ 2005-04-17  4:03 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mark at codesourcery dot com  2005-04-17 04:03 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable
 types

Alexandre Oliva wrote:
> Mark, did you give up on COMPOUND_LITERAL_EXPRs in C++ for 4.0?  The
> C++ portion of the patch at http://gcc.gnu.org/PR20103 is still
> awaiting review even for mainline :-(

Our messages crossed.  Ironically, I was just making a pass over the 
open 4.0 regressions, and realized that I'd failed to review this patch. 
  It's an ICE-on-invalid on a GNU C++ extension, so I've now pushed it 
back to 4.0.1.  I will be sure to review it before then.

Sorry,



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (41 preceding siblings ...)
  2005-04-17  4:03 ` mark at codesourcery dot com
@ 2005-04-17  6:25 ` aoliva at redhat dot com
  2005-07-06 17:03 ` mmitchel at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  45 siblings, 0 replies; 55+ messages in thread
From: aoliva at redhat dot com @ 2005-04-17  6:25 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From aoliva at gcc dot gnu dot org  2005-04-17 06:24 -------
Subject: Re: [PR c++/20103] failure to gimplify constructors for addressable types

On Apr 17, 2005, Mark Mitchell <mark@codesourcery.com> wrote:

> Alexandre Oliva wrote:
>> Mark, did you give up on COMPOUND_LITERAL_EXPRs in C++ for 4.0?  The
>> C++ portion of the patch at http://gcc.gnu.org/PR20103 is still
>> awaiting review even for mainline :-(

> Our messages crossed.  Ironically, I was just making a pass over the
> open 4.0 regressions, and realized that I'd failed to review this
> patch. It's an ICE-on-invalid on a GNU C++ extension, so I've now
> pushed it back to 4.0.1.  I will be sure to review it before then.

> Sorry,

No worries.  I didn't think it was all that important, but thought I'd
point it out just in case you'd forgotten about it.

How about reviewing it for mainline ASAP, so that we can be even more
confident when it goes into 4.0.1?



-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (42 preceding siblings ...)
  2005-04-17  6:25 ` aoliva at redhat dot com
@ 2005-07-06 17:03 ` mmitchel at gcc dot gnu dot org
  2005-07-22 21:12 ` steven at gcc dot gnu dot org
  2005-09-27 16:18 ` mmitchel at gcc dot gnu dot org
  45 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2005-07-06 17:03 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From mmitchel at gcc dot gnu dot org  2005-07-06 17:02 -------
Postponed until 4.0.2.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|4.0.1                       |4.0.2


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (43 preceding siblings ...)
  2005-07-06 17:03 ` mmitchel at gcc dot gnu dot org
@ 2005-07-22 21:12 ` steven at gcc dot gnu dot org
  2005-09-27 16:18 ` mmitchel at gcc dot gnu dot org
  45 siblings, 0 replies; 55+ messages in thread
From: steven at gcc dot gnu dot org @ 2005-07-22 21:12 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From steven at gcc dot gnu dot org  2005-07-22 21:10 -------
Well?  So many patches, and still not fixed?  :-) 
 

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mark at codesourcery dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
  2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
                   ` (44 preceding siblings ...)
  2005-07-22 21:12 ` steven at gcc dot gnu dot org
@ 2005-09-27 16:18 ` mmitchel at gcc dot gnu dot org
  45 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2005-09-27 16:18 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|4.0.2                       |4.0.3


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
                   ` (6 preceding siblings ...)
  2006-07-03 23:52 ` tbm at cyrius dot com
@ 2007-02-14  9:05 ` mmitchel at gcc dot gnu dot org
  7 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2007-02-14  9:05 UTC (permalink / raw)
  To: gcc-bugs



-- 

mmitchel at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Target Milestone|4.1.2                       |4.1.3


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
                   ` (5 preceding siblings ...)
  2006-06-10 22:23 ` pinskia at gcc dot gnu dot org
@ 2006-07-03 23:52 ` tbm at cyrius dot com
  2007-02-14  9:05 ` mmitchel at gcc dot gnu dot org
  7 siblings, 0 replies; 55+ messages in thread
From: tbm at cyrius dot com @ 2006-07-03 23:52 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #57 from tbm at cyrius dot com  2006-07-03 23:51 -------
(In reply to comment #56)
> complit1.C: In constructor 'Foo::Foo(int, int)':
> complit1.C:14: internal compiler error: in emit_move_insn, at expr.c:3275
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <URL:http://gcc.gnu.org/bugs.html> for instructions.
> 
> (should I file a different bug?)

For the record, I reported this as PR28018 without knowing of this PR.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
                   ` (4 preceding siblings ...)
  2006-06-09  9:57 ` jakub at gcc dot gnu dot org
@ 2006-06-10 22:23 ` pinskia at gcc dot gnu dot org
  2006-07-03 23:52 ` tbm at cyrius dot com
  2007-02-14  9:05 ` mmitchel at gcc dot gnu dot org
  7 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2006-06-10 22:23 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #56 from pinskia at gcc dot gnu dot org  2006-06-10 22:22 -------
complit1.C has an internal error now on powerpc-darwin:
 Foo::Foo(int, int)
complit1.C:14: error: ISO C++ forbids assignment of arrays
 Foo::Foo(int, int) Foo::Foo(int, int)
Analyzing compilation unitPerforming intraprocedural optimizations
Assembling functions:
 Foo::Foo(int, int)
complit1.C: In constructor 'Foo::Foo(int, int)':
complit1.C:14: internal compiler error: in emit_move_insn, at expr.c:3275
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

(should I file a different bug?)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
                   ` (3 preceding siblings ...)
  2006-05-25 20:26 ` mmitchel at gcc dot gnu dot org
@ 2006-06-09  9:57 ` jakub at gcc dot gnu dot org
  2006-06-10 22:23 ` pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 55+ messages in thread
From: jakub at gcc dot gnu dot org @ 2006-06-09  9:57 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #55 from jakub at gcc dot gnu dot org  2006-06-09 09:42 -------
*** Bug 27129 has been marked as a duplicate of this bug. ***


-- 

jakub at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
                   ` (2 preceding siblings ...)
  2005-10-31  2:44 ` mmitchel at gcc dot gnu dot org
@ 2006-05-25 20:26 ` mmitchel at gcc dot gnu dot org
  2006-06-09  9:57 ` jakub at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2006-05-25 20:26 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #54 from mmitchel at gcc dot gnu dot org  2006-05-25 20:26 -------
Fixed in 4.2.


-- 

mmitchel at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|[4.0/4.1/4.2 regression] ICE|[4.0/4.1 regression] ICE in
                   |in create_tmp_var with C99  |create_tmp_var with C99
                   |style struct initializer    |style struct initializer


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
  2005-10-13 20:06 ` pinskia at gcc dot gnu dot org
  2005-10-14 14:37 ` pinskia at gcc dot gnu dot org
@ 2005-10-31  2:44 ` mmitchel at gcc dot gnu dot org
  2006-05-25 20:26 ` mmitchel at gcc dot gnu dot org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 55+ messages in thread
From: mmitchel at gcc dot gnu dot org @ 2005-10-31  2:44 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #44 from mmitchel at gcc dot gnu dot org  2005-10-31 02:44 -------
Leaving as P2; we should at least look hard at all of this again for 4.1.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
  2005-10-13 20:06 ` pinskia at gcc dot gnu dot org
@ 2005-10-14 14:37 ` pinskia at gcc dot gnu dot org
  2005-10-31  2:44 ` mmitchel at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-10-14 14:37 UTC (permalink / raw)
  To: gcc-bugs



-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|critical                    |major


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [Bug c++/20103] [4.0/4.1 regression] ICE in create_tmp_var with C99 style struct initializer
       [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
@ 2005-10-13 20:06 ` pinskia at gcc dot gnu dot org
  2005-10-14 14:37 ` pinskia at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 55+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-10-13 20:06 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #43 from pinskia at gcc dot gnu dot org  2005-10-13 20:06 -------
: Search converges between 2004-05-11-trunk (#454) and 2004-05-14-trunk (#455).


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20103


^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2007-02-14  9:04 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-20 17:37 [Bug c++/20103] New: [4.0 regression] ICE in create_tmp_var falk at debian dot org
2005-02-20 17:52 ` [Bug c++/20103] " falk at debian dot org
2005-02-20 19:02 ` pinskia at gcc dot gnu dot org
2005-02-20 19:25 ` pinskia at gcc dot gnu dot org
2005-02-20 19:27 ` pinskia at gcc dot gnu dot org
2005-02-21 21:49 ` pinskia at gcc dot gnu dot org
2005-02-23 11:10 ` [Bug c++/20103] [4.0 regression] ICE in create_tmp_var with C99 style struct initializer pinskia at gcc dot gnu dot org
2005-03-02 13:48 ` [Bug c++/20103] [4.0/4.1 " reichelt at gcc dot gnu dot org
2005-03-03  7:01 ` aoliva at gcc dot gnu dot org
2005-03-03  7:42 ` aoliva at redhat dot com
2005-03-04 23:22 ` aoliva at redhat dot com
2005-03-04 23:30 ` mark at codesourcery dot com
2005-03-05 11:41 ` giovannibajo at libero dot it
2005-03-05 12:16 ` joseph at codesourcery dot com
2005-03-05 13:37 ` aoliva at redhat dot com
2005-03-05 14:03 ` aoliva at redhat dot com
2005-03-05 21:47 ` mark at codesourcery dot com
2005-03-06  7:30 ` aoliva at redhat dot com
2005-03-06 18:02 ` mark at codesourcery dot com
2005-03-07  3:26 ` aoliva at redhat dot com
2005-03-07  4:44 ` mark at codesourcery dot com
2005-03-07  8:51 ` giovannibajo at libero dot it
2005-03-07 14:44 ` aoliva at redhat dot com
2005-03-07 16:05 ` mark at codesourcery dot com
2005-03-07 17:05 ` aoliva at redhat dot com
2005-03-07 18:05 ` mark at codesourcery dot com
2005-03-07 21:58 ` aoliva at redhat dot com
2005-03-07 22:39 ` mark at codesourcery dot com
2005-03-08  7:25 ` aoliva at redhat dot com
2005-03-08  7:46 ` mark at codesourcery dot com
2005-03-08 20:44 ` aoliva at redhat dot com
2005-03-08 21:55 ` aoliva at redhat dot com
2005-03-11 15:20 ` rth at gcc dot gnu dot org
2005-03-11 19:29 ` aoliva at redhat dot com
2005-03-17 10:42 ` aoliva at redhat dot com
2005-03-17 11:49 ` rth at gcc dot gnu dot org
2005-03-18  5:39 ` aoliva at redhat dot com
2005-03-18 10:16 ` aoliva at redhat dot com
2005-04-02 17:27 ` aoliva at redhat dot com
2005-04-05 14:47 ` pinskia at gcc dot gnu dot org
2005-04-17  3:57 ` mmitchel at gcc dot gnu dot org
2005-04-17  3:59 ` aoliva at redhat dot com
2005-04-17  4:03 ` mark at codesourcery dot com
2005-04-17  6:25 ` aoliva at redhat dot com
2005-07-06 17:03 ` mmitchel at gcc dot gnu dot org
2005-07-22 21:12 ` steven at gcc dot gnu dot org
2005-09-27 16:18 ` mmitchel at gcc dot gnu dot org
     [not found] <bug-20103-2744@http.gcc.gnu.org/bugzilla/>
2005-10-13 20:06 ` pinskia at gcc dot gnu dot org
2005-10-14 14:37 ` pinskia at gcc dot gnu dot org
2005-10-31  2:44 ` mmitchel at gcc dot gnu dot org
2006-05-25 20:26 ` mmitchel at gcc dot gnu dot org
2006-06-09  9:57 ` jakub at gcc dot gnu dot org
2006-06-10 22:23 ` pinskia at gcc dot gnu dot org
2006-07-03 23:52 ` tbm at cyrius dot com
2007-02-14  9:05 ` mmitchel at gcc dot gnu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).