aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-24 01:17:29 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-24 01:17:29 +0000
commit0fa5e05c2f36dda5b06b259779afc7867b0da9f7 (patch)
treeb2c6898fd3ead0e1c37050fb2615df46e6890c1d /gcc
parenta571f7a00e33edb193e1a74869dab3f0576eb87c (diff)
downloadgcc-0fa5e05c2f36dda5b06b259779afc7867b0da9f7.zip
gcc-0fa5e05c2f36dda5b06b259779afc7867b0da9f7.tar.gz
gcc-0fa5e05c2f36dda5b06b259779afc7867b0da9f7.tar.bz2
cp-tree.h (DECL_ANON_UNION_ELEMS): New macro.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/decl2.c13
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/crash2.C27
6 files changed, 62 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5f27676..1fdf67f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f4e993f..9c623be 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 3b80f68..9967460 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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,
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 964cdb1..cd48570 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a4d0255..3803a42 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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
index 0000000..463df9d
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/crash2.C
@@ -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 ); }