cp-tree.h (DECL_ANON_UNION_ELEMS): New macro.
authorMark Mitchell <mark@codesourcery.com>
Fri, 24 Sep 1999 01:17:29 +0000 (01:17 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 24 Sep 1999 01:17:29 +0000 (01:17 +0000)
* cp-tree.h (DECL_ANON_UNION_ELEMS): New macro.
* decl2.c (finish_anon_union): Set DECL_ANON_UNION_ELEMS.
Don't call expand_anon_union_decl here
* semantics.c (exapnd_stmt): Call it here, instead.
* typeck.c (mark_addressable): Addressed variables are implicitly
used.

From-SVN: r29645

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.old-deja/g++.eh/crash2.C [new file with mode: 0644]

index 5f27676..1fdf67f 100644 (file)
@@ -1,3 +1,12 @@
+1999-09-23  Mark Mitchell  <mark@codesourcery.com>
+
+       * cp-tree.h (DECL_ANON_UNION_ELEMS): New macro.
+       * decl2.c (finish_anon_union): Set DECL_ANON_UNION_ELEMS.
+       Don't call expand_anon_union_decl here
+       * semantics.c (exapnd_stmt): Call it here, instead.
+       * typeck.c (mark_addressable): Addressed variables are implicitly
+       used.
+       
 1999-09-23  Martin v. Löwis  <loewis@informatik.hu-berlin.de>
 
        * cp-tree.h (VAR_OR_FUNCTION_DECL_CHECK): New macro.
index f4e993f..9c623be 100644 (file)
@@ -116,7 +116,10 @@ Boston, MA 02111-1307, USA.  */
      calling the function.  The TREE_VALUE is the declaration for the 
      virtual function itself.  When CLASSTYPE_COM_INTERFACE_P does not
      hold, the first entry does not have a TREE_VALUE; it is just an
-     offset.  */ 
+     offset.
+
+   DECL_ARGUMENTS
+     For a VAR_DECL this is DECL_ANON_UNION_ELEMS.  */
 
 /* Language-specific tree checkers. */
 
@@ -2229,6 +2232,10 @@ extern int flag_new_for_scope;
 #define SET_ANON_AGGR_TYPE_P(NODE)                     \
   (TYPE_LANG_SPECIFIC (NODE)->anon_aggr = 1)
 
+/* For a VAR_DECL that is an anonymous union, these are the various
+   sub-variables that make up the anonymous union.  */
+#define DECL_ANON_UNION_ELEMS(NODE) DECL_ARGUMENTS ((NODE))
+
 #define UNKNOWN_TYPE LANG_TYPE
 
 /* Define fields and accessors for nodes representing declared names.  */
index 3b80f68..9967460 100644 (file)
@@ -2131,7 +2131,6 @@ finish_anon_union (anon_union_decl)
      tree anon_union_decl;
 {
   tree type = TREE_TYPE (anon_union_decl);
-  tree elems = NULL_TREE;
   tree main_decl;
   int public_p = TREE_PUBLIC (anon_union_decl);
   int static_p = TREE_STATIC (anon_union_decl);
@@ -2146,7 +2145,8 @@ finish_anon_union (anon_union_decl)
       return;
     }
 
-  main_decl = build_anon_union_vars (anon_union_decl, &elems, 
+  main_decl = build_anon_union_vars (anon_union_decl,
+                                    &DECL_ANON_UNION_ELEMS (anon_union_decl),
                                     static_p, external_p);
 
   if (main_decl == NULL_TREE)
@@ -2159,11 +2159,12 @@ finish_anon_union (anon_union_decl)
     {
       make_decl_rtl (main_decl, 0, toplevel_bindings_p ());
       DECL_RTL (anon_union_decl) = DECL_RTL (main_decl);
+      expand_anon_union_decl (anon_union_decl, 
+                             NULL_TREE,
+                             DECL_ANON_UNION_ELEMS (anon_union_decl));
     }
-
-  /* The following call assumes that there are never any cleanups
-     for anonymous unions--a reasonable assumption.  */
-  expand_anon_union_decl (anon_union_decl, NULL_TREE, elems);
+  else
+    add_decl_stmt (anon_union_decl);
 }
 
 /* Finish processing a builtin type TYPE.  It's name is NAME,
index 964cdb1..cd48570 100644 (file)
@@ -2254,8 +2254,14 @@ expand_stmt (t)
            if (TREE_CODE (decl) == VAR_DECL 
                && !TREE_STATIC (decl)
                && !DECL_EXTERNAL (decl))
-             /* Let the back-end know about this variable.  */
-             emit_local_var (decl);
+             {
+               /* Let the back-end know about this variable.  */
+               if (!ANON_AGGR_TYPE_P (TREE_TYPE (decl)))
+                 emit_local_var (decl);
+               else
+                 expand_anon_union_decl (decl, NULL_TREE, 
+                                         DECL_ANON_UNION_ELEMS (decl));
+             }
 
            resume_momentary (i);
          }
index a4d0255..3803a42 100644 (file)
@@ -4999,8 +4999,10 @@ mark_addressable (exp)
            && !DECL_ARTIFICIAL (x) && extra_warnings)
          cp_warning ("address requested for `%D', which is declared `register'",
                      x);
-       put_var_into_stack (x);
        TREE_ADDRESSABLE (x) = 1;
+       TREE_USED (x) = 1;
+       if (current_function && expanding_p)
+         put_var_into_stack (x);
        return 1;
 
       case FUNCTION_DECL:
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/crash2.C b/gcc/testsuite/g++.old-deja/g++.eh/crash2.C
new file mode 100644 (file)
index 0000000..463df9d
--- /dev/null
@@ -0,0 +1,27 @@
+// Build don't link:
+// Origin: Thomas Kunert <kunert@physik.tu-dresden.de>
+// Special g++ Options: -O
+
+struct C {
+    ~C();
+};    
+
+struct R {
+    bool empty() const;
+    C m_;
+};
+
+struct R1 {
+    R1( const R& a );
+  ~R1 ();
+    C m_;
+};
+
+R1 get_empty();
+
+R1::R1( const R& a ) :
+    m_( a.empty() ? get_empty().m_ : C() )
+{}
+
+void qnorm( const R & r)
+{ R1 n( r ); }