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
This commit is contained in:
Mark Mitchell 2003-04-23 16:27:27 +00:00 committed by Mark Mitchell
parent f0ddce84f9
commit 4223f82fbc
8 changed files with 50 additions and 75 deletions

View File

@ -1,3 +1,14 @@
2003-04-23 Mark Mitchell <mark@codesourcery.com>
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 <mark@codesourcery.com>
PR c++/10446

View File

@ -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. */

View File

@ -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 *);

View File

@ -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);

View File

@ -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;

View File

@ -1,3 +1,11 @@
2003-04-23 Mark Mitchell <mark@codesourcery.com>
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 <mark@codesourcery.com>
PR c++/10446

View File

@ -0,0 +1,12 @@
struct Bar
{
typedef int type;
};
struct Foo
{
void func(void)
{
mutable Bar::type x; // { dg-error "" }
}
};

View File

@ -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 "" }
}