diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1b6444d211b0f28b46c04ae496aac40b37b119f2..d75773fc7ca8ca2f0c2748e6924a10bfcedd0871 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2003-04-27 Mark Mitchell <mark@codesourcery.com> + PR c++/10506 + * method.c (use_thunk): Decrement immediate_size_expand. + + PR c++/10503 + * cp-tree.h (DECL_VAR_MARKED_P): New macro. + (DECL_MAYBE_TEMPLATE): Remove. + * class.c (fixed_type_or_null): Avoid infinite recursion. + * decl.c (maybe_commonize_var): Make the code match the comments. * pt.c (instantiate_decl): Move call to import_export_decl. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 405e571a63f972802c4d0242a5c7ee1678991010..33ece0dbe2fc22f44bdc542332e727630a891d3a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5388,11 +5388,21 @@ fixed_type_or_null (tree instance, int* nonnull, int* cdtorp) /* Reference variables should be references to objects. */ if (nonnull) *nonnull = 1; - - if (TREE_CODE (instance) == VAR_DECL - && DECL_INITIAL (instance)) - return fixed_type_or_null (DECL_INITIAL (instance), - nonnull, cdtorp); + + /* DECL_VAR_MARKED_P is used to prevent recursion; a + variable's initializer may refer to the variable + itself. */ + if (TREE_CODE (instance) == VAR_DECL + && DECL_INITIAL (instance) + && !DECL_VAR_MARKED_P (instance)) + { + tree type; + DECL_VAR_MARKED_P (instance) = 1; + type = fixed_type_or_null (DECL_INITIAL (instance), + nonnull, cdtorp); + DECL_VAR_MARKED_P (instance) = 0; + return type; + } } return NULL_TREE; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 24913624c2e37de7d4d066bdab8bda25c1e758d0..9db905cf45922e0a220b2d00977944ef9c9b5b4c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -95,7 +95,7 @@ struct diagnostic_context; DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) - DECL_MAYBE_TEMPLATE (in a FUNCTION_DECL) + DECL_VAR_MARKED_P (in a VAR_DECL) 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). @@ -2131,6 +2131,12 @@ struct lang_decl GTY(()) (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK (NODE)) \ ->decl_flags.u.template_info) +/* For a VAR_DECL, indicates that the variable has been processed. + This flag is set and unset throughout the code; it is always + used for a temporary purpose. */ +#define DECL_VAR_MARKED_P(NODE) \ + (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))) + /* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) \ (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_TYPE_CHECK (NODE))->template_info) @@ -2807,9 +2813,6 @@ struct lang_decl GTY(()) #define PROCESSING_REAL_TEMPLATE_DECL_P() \ (processing_template_decl > template_class_depth (current_class_type)) -/* This function may be a guiding decl for a template. */ -#define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE) - /* Nonzero if this VAR_DECL or FUNCTION_DECL has already been instantiated, i.e. its definition has been generated from the pattern given in the the template. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index b5a88f2f11d12416003e14b0abc85e4ba90ef5fa..49bb1168cfc5fab713e06ca98408464f734259a6 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -439,6 +439,9 @@ use_thunk (tree thunk_fndecl, bool emit_p) assemble_end_function (thunk_fndecl, fnname); current_function_decl = 0; cfun = 0; + /* Because init_function_start increments this, we must + decrement it. */ + immediate_size_expand--; TREE_ASM_WRITTEN (thunk_fndecl) = 1; } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d2187a657dc6cef8bd029a5d7e80df2143ec4d74..210cff6677c61981b00250b5046a3e7bbfefd23d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2003-04-27 Mark Mitchell <mark@codesourcery.com> + + PR c++/10506 + * g++.dg/init/new6.C: New test. + + PR c++/10503 + * g++.dg/init/ref6.C: New test. + 2003-04-26 David Edelsohn <edelsohn@gnu.org> * g++.dg/warn/weak1.C: XFAIL on AIX4. diff --git a/gcc/testsuite/g++.dg/init/new6.C b/gcc/testsuite/g++.dg/init/new6.C new file mode 100644 index 0000000000000000000000000000000000000000..ecbafd13e6c0a1c85141807fa55278d8e29cdc50 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/new6.C @@ -0,0 +1,8 @@ +// { dg-options "-fkeep-inline-functions" } + +struct B1 { virtual ~B1(); }; +struct B2 { virtual ~B2(); }; +struct D : B1, B2 {}; +struct X : D { X (); }; + +X::X () { new int; } diff --git a/gcc/testsuite/g++.dg/init/ref6.C b/gcc/testsuite/g++.dg/init/ref6.C new file mode 100644 index 0000000000000000000000000000000000000000..50a9636036667b7474b1d0ebaf08e38c4997426f --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ref6.C @@ -0,0 +1,12 @@ +struct B { + void g() { } +}; + +struct A { + void f() { + B &b = b; + b.g(); + } +}; + +int main(void) { }