From 4223f82fbc44740367239b334e47ce0865d5b2d1 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Wed, 23 Apr 2003 16:27:27 +0000 Subject: [PATCH] re PR c++/9847 (ICE on :?-operator with double class definition in expand_expr) PR c++/9847 * cp-tree.h (duplicate_tag_error): Remove. * class.c (duplicate_tag_error): Remove. * semantics.c (begin_class_definition): Return immediately for a duplicate class definition. PR c++/10451 * decl.c (grokdeclarator): Correct logic for "mutable" errors. From-SVN: r65998 --- gcc/cp/ChangeLog | 11 +++++ gcc/cp/class.c | 72 ----------------------------- gcc/cp/cp-tree.h | 1 - gcc/cp/decl.c | 2 +- gcc/cp/semantics.c | 6 ++- gcc/testsuite/ChangeLog | 8 ++++ gcc/testsuite/g++.dg/parse/crash4.C | 12 +++++ gcc/testsuite/g++.dg/parse/crash5.C | 13 ++++++ 8 files changed, 50 insertions(+), 75 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/crash4.C create mode 100644 gcc/testsuite/g++.dg/parse/crash5.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c768b4f2fe3..723f67a30c9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2003-04-23 Mark Mitchell + + PR c++/9847 + * cp-tree.h (duplicate_tag_error): Remove. + * class.c (duplicate_tag_error): Remove. + * semantics.c (begin_class_definition): Return immediately for a + duplicate class definition. + + PR c++/10451 + * decl.c (grokdeclarator): Correct logic for "mutable" errors. + 2003-04-22 Mark Mitchell PR c++/10446 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 382519e7528..405e571a63f 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1924,78 +1924,6 @@ finish_struct_methods (tree t) method_name_cmp); } -/* Emit error when a duplicate definition of a type is seen. Patch up. */ - -void -duplicate_tag_error (tree t) -{ - error ("redefinition of `%#T'", t); - cp_error_at ("previous definition of `%#T'", t); - - /* Pretend we haven't defined this type. */ - - /* All of the component_decl's were TREE_CHAINed together in the parser. - finish_struct_methods walks these chains and assembles all methods with - the same base name into DECL_CHAINs. Now we don't need the parser chains - anymore, so we unravel them. */ - - /* This used to be in finish_struct, but it turns out that the - TREE_CHAIN is used by dbxout_type_methods and perhaps some other - things... */ - if (CLASSTYPE_METHOD_VEC (t)) - { - tree method_vec = CLASSTYPE_METHOD_VEC (t); - int i, len = TREE_VEC_LENGTH (method_vec); - for (i = 0; i < len; i++) - { - tree unchain = TREE_VEC_ELT (method_vec, i); - while (unchain != NULL_TREE) - { - TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE; - unchain = OVL_NEXT (unchain); - } - } - } - - if (TYPE_LANG_SPECIFIC (t)) - { - tree binfo = TYPE_BINFO (t); - int interface_only = CLASSTYPE_INTERFACE_ONLY (t); - int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t); - tree template_info = CLASSTYPE_TEMPLATE_INFO (t); - int use_template = CLASSTYPE_USE_TEMPLATE (t); - - memset ((char *) TYPE_LANG_SPECIFIC (t), 0, sizeof (struct lang_type)); - BINFO_BASETYPES(binfo) = NULL_TREE; - - TYPE_LANG_SPECIFIC (t)->u.h.is_lang_type_class = 1; - TYPE_BINFO (t) = binfo; - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); - TYPE_REDEFINED (t) = 1; - CLASSTYPE_TEMPLATE_INFO (t) = template_info; - CLASSTYPE_USE_TEMPLATE (t) = use_template; - CLASSTYPE_DECL_LIST (t) = NULL_TREE; - } - TYPE_SIZE (t) = NULL_TREE; - TYPE_MODE (t) = VOIDmode; - TYPE_FIELDS (t) = NULL_TREE; - TYPE_METHODS (t) = NULL_TREE; - TYPE_VFIELD (t) = NULL_TREE; - TYPE_CONTEXT (t) = NULL_TREE; - - /* Clear TYPE_LANG_FLAGS -- those in TYPE_LANG_SPECIFIC are cleared above. */ - TYPE_LANG_FLAG_0 (t) = 0; - TYPE_LANG_FLAG_1 (t) = 0; - TYPE_LANG_FLAG_2 (t) = 0; - TYPE_LANG_FLAG_3 (t) = 0; - TYPE_LANG_FLAG_4 (t) = 0; - TYPE_LANG_FLAG_5 (t) = 0; - TYPE_LANG_FLAG_6 (t) = 0; - /* But not this one. */ - SET_IS_AGGR_TYPE (t, 1); -} - /* Make BINFO's vtable have N entries, including RTTI entries, vbase and vcall offsets, etc. Set its type and call the backend to lay it out. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index cbee534b4da..24913624c2e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3540,7 +3540,6 @@ extern void resort_type_method_vec extern void add_method (tree, tree, int); extern int currently_open_class (tree); extern tree currently_open_derived_class (tree); -extern void duplicate_tag_error (tree); extern tree finish_struct (tree, tree); extern void finish_struct_1 (tree); extern int resolves_to_fixed_type_p (tree, int *); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 84e267ee9f6..181dd6fc4a6 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11044,7 +11044,7 @@ grokdeclarator (tree declarator, if (RIDBIT_SETP (RID_MUTABLE, specbits)) { - if (current_class_name == NULL_TREE || decl_context == PARM || friendp) + if (decl_context != FIELD || friendp) { error ("non-member `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 7c7af3e8399..cdb24f6e910 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1797,7 +1797,11 @@ begin_class_definition (t) /* If this type was already complete, and we see another definition, that's an error. */ if (COMPLETE_TYPE_P (t)) - duplicate_tag_error (t); + { + error ("redefinition of `%#T'", t); + cp_error_at ("previous definition of `%#T'", t); + return error_mark_node; + } /* Update the location of the decl. */ DECL_SOURCE_FILE (TYPE_NAME (t)) = input_filename; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 154e129e0ae..2fc733dedcb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2003-04-23 Mark Mitchell + + PR c++/10451 + * g++.dg/parse/crash4.C: New test. + + PR c++/9847 + * g++.dg/parse/crash5.C: New test. + 2003-04-22 Mark Mitchell PR c++/10446 diff --git a/gcc/testsuite/g++.dg/parse/crash4.C b/gcc/testsuite/g++.dg/parse/crash4.C new file mode 100644 index 00000000000..a24f0dd003c --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash4.C @@ -0,0 +1,12 @@ +struct Bar + { + typedef int type; + }; + + struct Foo + { + void func(void) + { + mutable Bar::type x; // { dg-error "" } + } + }; diff --git a/gcc/testsuite/g++.dg/parse/crash5.C b/gcc/testsuite/g++.dg/parse/crash5.C new file mode 100644 index 00000000000..3a4185b7e6c --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/crash5.C @@ -0,0 +1,13 @@ +// { dg-options "-w" } + +class QString { // { dg-error "" } + QString (const QString & a); // { dg-error "" } +}; + +class QString { }; // { dg-error "" } + +const QString q () { + QString z; // { dg-error "" } + int x; + return x ? QString () : QString (); // { dg-error "" } +}