From 0fa5e05c2f36dda5b06b259779afc7867b0da9f7 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 24 Sep 1999 01:17:29 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 ++++++++ gcc/cp/cp-tree.h | 9 +++++++- gcc/cp/decl2.c | 13 ++++++----- gcc/cp/semantics.c | 10 ++++++-- gcc/cp/typeck.c | 4 +++- gcc/testsuite/g++.old-deja/g++.eh/crash2.C | 27 ++++++++++++++++++++++ 6 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.eh/crash2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5f27676ca01..1fdf67fcdb7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1999-09-23 Mark Mitchell + + * 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 * 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 f4e993f979a..9c623bebf78 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 3b80f6825a7..99674609020 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 964cdb1da5e..cd48570ca7f 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 a4d0255312a..3803a42f009 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 00000000000..463df9d42bb --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/crash2.C @@ -0,0 +1,27 @@ +// Build don't link: +// Origin: Thomas Kunert +// 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 ); }