re PR c++/14401 (Uninitialized reference error not reported.)
PR c++/14401 * class.c (check_field_decls): Complain about non-static data members of reference type in unions. Propagate CLASSTYPE_REF_FIELDS_NEED_INIT and CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static data members. * init.c (perform_member_init): Complain about mbmers with const type that are not explicitly initialized. PR c++/14401 * g++.dg/init/ctor3.C: New test. * g++.dg/init/union1.C: New test. * g++.dg/ext/anon-struct4.C: New test. From-SVN: r79158
This commit is contained in:
parent
f1c4ca32d0
commit
58ec3cc5c0
21 changed files with 146 additions and 162 deletions
|
@ -1,3 +1,44 @@
|
|||
2004-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/14401
|
||||
* class.c (check_field_decls): Complain about non-static data
|
||||
members of reference type in unions. Propagate
|
||||
CLASSTYPE_REF_FIELDS_NEED_INIT and
|
||||
CLASSTYPE_READONLY_FIELDS_NEED_INIT from the types of non-static
|
||||
data members.
|
||||
* init.c (perform_member_init): Complain about mbmers with const
|
||||
type that are not explicitly initialized.
|
||||
|
||||
2004-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* class.c (check_methods): Don't use IDENTIFIER_ERROR_LOCUS.
|
||||
* cp-tree.h (DECL_INVALID_OVERRIDER_P): New macro.
|
||||
(lang_identifier): Remove implicit_decl and error_locus.
|
||||
(IDENTIFIER_IMPLICIT_DECL): Remove.
|
||||
(SET_IDENTIFIER_IMPLICTI_DECL): Likewise.
|
||||
(IDENTIFIER_ERROR_LOCUS): Likewise.
|
||||
(SET_IDENTIFIER_ERROR_LOCUS): Likewise.
|
||||
(TYPE_ASSEMBLER_NAME_STRING): Likewise.
|
||||
(TYPE_ASSEMBLER_NAME_LENGTH): Likewise.
|
||||
(implicitly_declare): Remove.
|
||||
* decl.c (warn_extern_redeclared_static): Remove check of
|
||||
IDENTIFIER_IMPLICIT_DECL.
|
||||
(duplicate_decls): Don't check IDENTIFIER_ERROR_LOCUS.
|
||||
(implicitly_declare): Remove.
|
||||
(grok_ctor_properties): Don't set IDENTIFIER_ERROR_LOCUS.
|
||||
(start_function): Don't check IDENTIFIER_IMPLICIT_DECL.
|
||||
(start_method): Don't check IDENTIFIER_ERROR_LOCUS.
|
||||
* lex.c (unqualified_name_lookup_error): Create a dummy VAR_DECL
|
||||
in the innermost scope, rather than at namespace scope.
|
||||
* name-lookup.c (push_local_binding): Give it external linkage.
|
||||
(pushdecl): Remove dead code.
|
||||
* name-lookup.h (push_local_binding): Declare it.
|
||||
* ptree.c (cxx_print_identifier): Don't print
|
||||
IDENTIFIER_IMPLICIT_DECL or IDENTIFIER_ERROR_LOCUS.
|
||||
* search.c (check_final_overrider): Use DECL_INVALID_OVERRIDER_P,
|
||||
not IDENTIFIER_ERROR_LOCUS.
|
||||
* typeck.c (build_function_call): Remove dead code.
|
||||
|
||||
2004-03-08 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/13170
|
||||
|
|
|
@ -2923,9 +2923,30 @@ check_field_decls (tree t, tree *access_decls,
|
|||
|
||||
/* If we've gotten this far, it's a data member, possibly static,
|
||||
or an enumerator. */
|
||||
|
||||
DECL_CONTEXT (x) = t;
|
||||
|
||||
/* When this goes into scope, it will be a non-local reference. */
|
||||
DECL_NONLOCAL (x) = 1;
|
||||
|
||||
if (TREE_CODE (t) == UNION_TYPE)
|
||||
{
|
||||
/* [class.union]
|
||||
|
||||
If a union contains a static data member, or a member of
|
||||
reference type, the program is ill-formed. */
|
||||
if (TREE_CODE (x) == VAR_DECL)
|
||||
{
|
||||
cp_error_at ("`%D' may not be static because it is a member of a union", x);
|
||||
continue;
|
||||
}
|
||||
if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
{
|
||||
cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",
|
||||
x, type);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* ``A local class cannot have static data members.'' ARM 9.4 */
|
||||
if (current_function_decl && TREE_STATIC (x))
|
||||
cp_error_at ("field `%D' in local class cannot be static", x);
|
||||
|
@ -2949,21 +2970,9 @@ check_field_decls (tree t, tree *access_decls,
|
|||
if (type == error_mark_node)
|
||||
continue;
|
||||
|
||||
/* When this goes into scope, it will be a non-local reference. */
|
||||
DECL_NONLOCAL (x) = 1;
|
||||
|
||||
if (TREE_CODE (x) == CONST_DECL)
|
||||
if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)
|
||||
continue;
|
||||
|
||||
if (TREE_CODE (x) == VAR_DECL)
|
||||
{
|
||||
if (TREE_CODE (t) == UNION_TYPE)
|
||||
/* Unions cannot have static members. */
|
||||
cp_error_at ("field `%D' declared static in union", x);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Now it can only be a FIELD_DECL. */
|
||||
|
||||
if (TREE_PRIVATE (x) || TREE_PROTECTED (x))
|
||||
|
@ -2994,6 +3003,14 @@ check_field_decls (tree t, tree *access_decls,
|
|||
if (TYPE_PTR_P (type))
|
||||
has_pointers = 1;
|
||||
|
||||
if (CLASS_TYPE_P (type))
|
||||
{
|
||||
if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))
|
||||
SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);
|
||||
if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
|
||||
SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);
|
||||
}
|
||||
|
||||
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
|
||||
CLASSTYPE_HAS_MUTABLE (t) = 1;
|
||||
|
||||
|
@ -3683,11 +3700,6 @@ check_methods (tree t)
|
|||
|
||||
for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x))
|
||||
{
|
||||
/* If this was an evil function, don't keep it in class. */
|
||||
if (DECL_ASSEMBLER_NAME_SET_P (x)
|
||||
&& IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
|
||||
continue;
|
||||
|
||||
check_for_override (x, t);
|
||||
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
|
||||
cp_error_at ("initializer specified for non-virtual method `%D'", x);
|
||||
|
|
|
@ -100,6 +100,7 @@ struct diagnostic_context;
|
|||
4: DECL_C_BIT_FIELD (in a FIELD_DECL)
|
||||
DECL_VAR_MARKED_P (in a VAR_DECL)
|
||||
DECL_SELF_REFERENCE_P (in a TYPE_DECL)
|
||||
DECL_INVALID_OVERRIRDER_P (in a FUNCTION_DECL)
|
||||
5: DECL_INTERFACE_KNOWN.
|
||||
6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL).
|
||||
7: DECL_DEAD_FOR_LOCAL (in VAR_DECL).
|
||||
|
@ -224,8 +225,6 @@ struct lang_identifier GTY(())
|
|||
tree class_value;
|
||||
tree class_template_info;
|
||||
tree label_value;
|
||||
tree implicit_decl;
|
||||
tree error_locus;
|
||||
};
|
||||
|
||||
/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a
|
||||
|
@ -399,16 +398,6 @@ typedef enum cp_id_kind
|
|||
#define SET_IDENTIFIER_LABEL_VALUE(NODE, VALUE) \
|
||||
IDENTIFIER_LABEL_VALUE (NODE) = (VALUE)
|
||||
|
||||
#define IDENTIFIER_IMPLICIT_DECL(NODE) \
|
||||
(LANG_IDENTIFIER_CAST (NODE)->implicit_decl)
|
||||
#define SET_IDENTIFIER_IMPLICIT_DECL(NODE, VALUE) \
|
||||
IDENTIFIER_IMPLICIT_DECL (NODE) = (VALUE)
|
||||
|
||||
#define IDENTIFIER_ERROR_LOCUS(NODE) \
|
||||
(LANG_IDENTIFIER_CAST (NODE)->error_locus)
|
||||
#define SET_IDENTIFIER_ERROR_LOCUS(NODE, VALUE) \
|
||||
IDENTIFIER_ERROR_LOCUS (NODE) = (VALUE)
|
||||
|
||||
/* Nonzero if this identifier is used as a virtual function name somewhere
|
||||
(optimizes searches). */
|
||||
#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1 (NODE)
|
||||
|
@ -888,11 +877,6 @@ enum languages { lang_c, lang_cplusplus, lang_java };
|
|||
#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE)))
|
||||
#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE)))
|
||||
|
||||
#define TYPE_ASSEMBLER_NAME_STRING(NODE) \
|
||||
(IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
|
||||
#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) \
|
||||
(IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE))))
|
||||
|
||||
/* Nonzero if NODE has no name for linkage purposes. */
|
||||
#define TYPE_ANONYMOUS_P(NODE) \
|
||||
(TAGGED_TYPE_P (NODE) && ANON_AGGRNAME_P (TYPE_LINKAGE_IDENTIFIER (NODE)))
|
||||
|
@ -1951,6 +1935,13 @@ struct lang_decl GTY(())
|
|||
#define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->decl_flags.needs_final_overrider)
|
||||
|
||||
/* True (in a FUNCTION_DECL) if NODE is a virtual function that is an
|
||||
invalid overrider for a function from a base class. Once we have
|
||||
complained about an invalid overrider we avoid complaining about it
|
||||
again. */
|
||||
#define DECL_INVALID_OVERRIDER_P(NODE) \
|
||||
(DECL_LANG_FLAG_4 (NODE))
|
||||
|
||||
/* The thunks associated with NODE, a FUNCTION_DECL. */
|
||||
#define DECL_THUNKS(NODE) \
|
||||
(DECL_LANG_SPECIFIC (NODE)->u.f.context)
|
||||
|
@ -3614,7 +3605,6 @@ extern tree duplicate_decls (tree, tree);
|
|||
extern tree pushdecl_top_level (tree);
|
||||
extern tree pushdecl_top_level_and_finish (tree, tree);
|
||||
extern tree push_using_decl (tree, tree);
|
||||
extern tree implicitly_declare (tree);
|
||||
extern tree declare_local_label (tree);
|
||||
extern tree define_label (location_t, tree);
|
||||
extern void check_goto (tree);
|
||||
|
|
|
@ -1097,11 +1097,6 @@ decls_match (tree newdecl, tree olddecl)
|
|||
void
|
||||
warn_extern_redeclared_static (tree newdecl, tree olddecl)
|
||||
{
|
||||
static const char *const explicit_extern_static_warning
|
||||
= "`%D' was declared `extern' and later `static'";
|
||||
static const char *const implicit_extern_static_warning
|
||||
= "`%D' was declared implicitly `extern' and later `static'";
|
||||
|
||||
tree name;
|
||||
|
||||
if (TREE_CODE (newdecl) == TYPE_DECL
|
||||
|
@ -1127,9 +1122,7 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
|
|||
return;
|
||||
|
||||
name = DECL_ASSEMBLER_NAME (newdecl);
|
||||
pedwarn (IDENTIFIER_IMPLICIT_DECL (name)
|
||||
? implicit_extern_static_warning
|
||||
: explicit_extern_static_warning, newdecl);
|
||||
pedwarn ("`%D' was declared `extern' and later `static'", newdecl);
|
||||
cp_pedwarn_at ("previous declaration of `%D'", olddecl);
|
||||
}
|
||||
|
||||
|
@ -1373,10 +1366,7 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
else
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Already complained about this, so don't do so again. */
|
||||
else if (current_class_type == NULL_TREE
|
||||
|| IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)
|
||||
else
|
||||
{
|
||||
error ("conflicting declaration '%#D'", newdecl);
|
||||
cp_error_at ("'%D' has a previous declaration as `%#D'",
|
||||
|
@ -1943,39 +1933,6 @@ duplicate_decls (tree newdecl, tree olddecl)
|
|||
return olddecl;
|
||||
}
|
||||
|
||||
/* Generate an implicit declaration for identifier FUNCTIONID
|
||||
as a function of type int (). Print a warning if appropriate. */
|
||||
|
||||
tree
|
||||
implicitly_declare (tree functionid)
|
||||
{
|
||||
tree decl;
|
||||
|
||||
/* We used to reuse an old implicit decl here,
|
||||
but this loses with inline functions because it can clobber
|
||||
the saved decl chains. */
|
||||
decl = build_lang_decl (FUNCTION_DECL, functionid, default_function_type);
|
||||
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
|
||||
/* ISO standard says implicit declarations are in the innermost block.
|
||||
So we record the decl in the standard fashion. */
|
||||
pushdecl (decl);
|
||||
rest_of_decl_compilation (decl, NULL, 0, 0);
|
||||
|
||||
if (warn_implicit
|
||||
/* Only one warning per identifier. */
|
||||
&& IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE)
|
||||
{
|
||||
pedwarn ("implicit declaration of function `%#D'", decl);
|
||||
}
|
||||
|
||||
SET_IDENTIFIER_IMPLICIT_DECL (functionid, decl);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
/* Return zero if the declaration NEWDECL is valid
|
||||
when the declaration OLDDECL (assumed to be for the same name)
|
||||
has already been seen.
|
||||
|
@ -8844,7 +8801,6 @@ grok_ctor_properties (tree ctype, tree decl)
|
|||
instantiated, but that's hard to forestall. */
|
||||
error ("invalid constructor; you probably meant `%T (const %T&)'",
|
||||
ctype, ctype);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -10154,12 +10110,6 @@ start_function (tree declspecs, tree declarator, tree attrs, int flags)
|
|||
ctype = NULL_TREE;
|
||||
}
|
||||
|
||||
/* Warn if function was previously implicitly declared
|
||||
(but not if we warned then). */
|
||||
if (! warn_implicit
|
||||
&& IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE)
|
||||
cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)));
|
||||
|
||||
/* Set up current_class_type, and enter the scope of the class, if
|
||||
appropriate. */
|
||||
if (ctype)
|
||||
|
@ -10929,13 +10879,10 @@ start_method (tree declspecs, tree declarator, tree attrlist)
|
|||
|
||||
if (DECL_IN_AGGR_P (fndecl))
|
||||
{
|
||||
if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type)
|
||||
{
|
||||
if (DECL_CONTEXT (fndecl)
|
||||
&& TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
|
||||
error ("`%D' is already defined in class `%T'", fndecl,
|
||||
DECL_CONTEXT (fndecl));
|
||||
}
|
||||
if (DECL_CONTEXT (fndecl)
|
||||
&& TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL)
|
||||
error ("`%D' is already defined in class `%T'", fndecl,
|
||||
DECL_CONTEXT (fndecl));
|
||||
return void_type_node;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,6 +371,9 @@ perform_member_init (tree member, tree init)
|
|||
/* member traversal: note it leaves init NULL */
|
||||
else if (TREE_CODE (type) == REFERENCE_TYPE)
|
||||
pedwarn ("uninitialized reference member `%D'", member);
|
||||
else if (CP_TYPE_CONST_P (type))
|
||||
pedwarn ("uninitialized mber `%D' with `const' type `%T'",
|
||||
member, type);
|
||||
}
|
||||
else if (TREE_CODE (init) == TREE_LIST)
|
||||
/* There was an explicit member initialization. Do some work
|
||||
|
|
24
gcc/cp/lex.c
24
gcc/cp/lex.c
|
@ -627,26 +627,18 @@ unqualified_name_lookup_error (tree name)
|
|||
if (name != ansi_opname (ERROR_MARK))
|
||||
error ("`%D' not defined", name);
|
||||
}
|
||||
else if (current_function_decl == 0)
|
||||
error ("`%D' was not declared in this scope", name);
|
||||
else
|
||||
{
|
||||
if (IDENTIFIER_NAMESPACE_VALUE (name) != error_mark_node
|
||||
|| IDENTIFIER_ERROR_LOCUS (name) != current_function_decl)
|
||||
error ("`%D' was not declared in this scope", name);
|
||||
/* Prevent repeated error messages by creating a VAR_DECL with
|
||||
this NAME in the innermost block scope. */
|
||||
if (current_function_decl)
|
||||
{
|
||||
static int undeclared_variable_notice;
|
||||
|
||||
error ("`%D' undeclared (first use this function)", name);
|
||||
|
||||
if (! undeclared_variable_notice)
|
||||
{
|
||||
error ("(Each undeclared identifier is reported only once for each function it appears in.)");
|
||||
undeclared_variable_notice = 1;
|
||||
}
|
||||
tree decl;
|
||||
decl = build_decl (VAR_DECL, name, error_mark_node);
|
||||
DECL_CONTEXT (decl) = current_function_decl;
|
||||
push_local_binding (name, decl, 0);
|
||||
}
|
||||
/* Prevent repeated error messages. */
|
||||
SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl);
|
||||
}
|
||||
|
||||
return error_mark_node;
|
||||
|
|
|
@ -36,7 +36,6 @@ static cxx_scope *innermost_nonclass_level (void);
|
|||
static tree select_decl (cxx_binding *, int);
|
||||
static cxx_binding *binding_for_name (cxx_scope *, tree);
|
||||
static tree lookup_name_current_level (tree);
|
||||
static void push_local_binding (tree, tree, int);
|
||||
static tree push_overloaded_decl (tree, int);
|
||||
static bool lookup_using_namespace (tree, cxx_binding *, tree,
|
||||
tree, int);
|
||||
|
@ -647,13 +646,7 @@ pushdecl (tree x)
|
|||
t = NULL_TREE;
|
||||
}
|
||||
|
||||
if (t == error_mark_node)
|
||||
{
|
||||
/* error_mark_node is 0 for a while during initialization! */
|
||||
t = NULL_TREE;
|
||||
cp_error_at ("`%#D' used prior to declaration", x);
|
||||
}
|
||||
else if (t != NULL_TREE)
|
||||
if (t && t != error_mark_node)
|
||||
{
|
||||
if (different_binding_level)
|
||||
{
|
||||
|
@ -830,24 +823,6 @@ pushdecl (tree x)
|
|||
|| TREE_CODE (x) == TEMPLATE_DECL))
|
||||
SET_IDENTIFIER_NAMESPACE_VALUE (name, x);
|
||||
|
||||
/* Don't forget if the function was used via an implicit decl. */
|
||||
if (IDENTIFIER_IMPLICIT_DECL (name)
|
||||
&& TREE_USED (IDENTIFIER_IMPLICIT_DECL (name)))
|
||||
TREE_USED (x) = 1;
|
||||
|
||||
/* Don't forget if its address was taken in that way. */
|
||||
if (IDENTIFIER_IMPLICIT_DECL (name)
|
||||
&& TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name)))
|
||||
TREE_ADDRESSABLE (x) = 1;
|
||||
|
||||
/* Warn about mismatches against previous implicit decl. */
|
||||
if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE
|
||||
/* If this real decl matches the implicit, don't complain. */
|
||||
&& ! (TREE_CODE (x) == FUNCTION_DECL
|
||||
&& TREE_TYPE (TREE_TYPE (x)) == integer_type_node))
|
||||
warning
|
||||
("`%D' was previously implicitly declared to return `int'", x);
|
||||
|
||||
/* If new decl is `static' and an `extern' was seen previously,
|
||||
warn about it. */
|
||||
if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t))
|
||||
|
@ -1035,7 +1010,7 @@ maybe_push_decl (tree decl)
|
|||
doesn't really belong to this binding level, that it got here
|
||||
through a using-declaration. */
|
||||
|
||||
static void
|
||||
void
|
||||
push_local_binding (tree id, tree decl, int flags)
|
||||
{
|
||||
struct cp_binding_level *b;
|
||||
|
|
|
@ -287,6 +287,7 @@ extern tree lookup_namespace_name (tree, tree);
|
|||
extern tree lookup_qualified_name (tree, tree, bool, bool);
|
||||
extern tree lookup_name_nonclass (tree);
|
||||
extern tree lookup_function_nonclass (tree, tree);
|
||||
extern void push_local_binding (tree, tree, int);
|
||||
extern int push_class_binding (tree, tree);
|
||||
extern bool pushdecl_class_level (tree);
|
||||
extern tree pushdecl_namespace_level (tree);
|
||||
|
|
|
@ -157,8 +157,6 @@ cxx_print_identifier (FILE *file, tree node, int indent)
|
|||
cxx_print_binding (file, IDENTIFIER_BINDING (node), "local bindings");
|
||||
print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4);
|
||||
print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4);
|
||||
print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4);
|
||||
print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1703,7 +1703,10 @@ check_final_overrider (tree overrider, tree basefn)
|
|||
tree over_throw = TYPE_RAISES_EXCEPTIONS (over_type);
|
||||
tree base_throw = TYPE_RAISES_EXCEPTIONS (base_type);
|
||||
int fail = 0;
|
||||
|
||||
|
||||
if (DECL_INVALID_OVERRIDER_P (overrider))
|
||||
return 0;
|
||||
|
||||
if (same_type_p (base_return, over_return))
|
||||
/* OK */;
|
||||
else if ((CLASS_TYPE_P (over_return) && CLASS_TYPE_P (base_return))
|
||||
|
@ -1753,8 +1756,6 @@ check_final_overrider (tree overrider, tree basefn)
|
|||
fail = 2;
|
||||
if (!fail)
|
||||
/* OK */;
|
||||
else if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
if (fail == 1)
|
||||
|
@ -1768,21 +1769,16 @@ check_final_overrider (tree overrider, tree basefn)
|
|||
overrider);
|
||||
cp_error_at (" overriding `%#D'", basefn);
|
||||
}
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
|
||||
DECL_CONTEXT (overrider));
|
||||
DECL_INVALID_OVERRIDER_P (overrider) = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check throw specifier is at least as strict. */
|
||||
if (!comp_except_specs (base_throw, over_throw, 0))
|
||||
{
|
||||
if (!IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider)))
|
||||
{
|
||||
cp_error_at ("looser throw specifier for `%#F'", overrider);
|
||||
cp_error_at (" overriding `%#F'", basefn);
|
||||
SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (overrider),
|
||||
DECL_CONTEXT (overrider));
|
||||
}
|
||||
cp_error_at ("looser throw specifier for `%#F'", overrider);
|
||||
cp_error_at (" overriding `%#F'", basefn);
|
||||
DECL_INVALID_OVERRIDER_P (overrider) = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -2380,7 +2380,7 @@ build_function_call (tree function, tree params)
|
|||
tree fntype, fndecl;
|
||||
tree coerced_params;
|
||||
tree result;
|
||||
tree name = NULL_TREE, assembler_name = NULL_TREE;
|
||||
tree name = NULL_TREE;
|
||||
int is_method;
|
||||
tree original = function;
|
||||
|
||||
|
@ -2393,7 +2393,6 @@ build_function_call (tree function, tree params)
|
|||
if (TREE_CODE (function) == FUNCTION_DECL)
|
||||
{
|
||||
name = DECL_NAME (function);
|
||||
assembler_name = DECL_ASSEMBLER_NAME (function);
|
||||
|
||||
mark_used (function);
|
||||
fndecl = function;
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
2004-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
PR c++/14401
|
||||
* g++.dg/init/ctor3.C: New test.
|
||||
* g++.dg/init/union1.C: New test.
|
||||
* g++.dg/ext/anon-struct4.C: New test.
|
||||
|
||||
2004-03-08 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* g++.dg/lookup/koenig1.C: Tweak error messages.
|
||||
* g++.dg/lookup/used-before-declaration.C: Likewise.
|
||||
* g++.dg/other/do1.C: Likewise.
|
||||
* g++.dg/overload/koenig1.C: Likewise.
|
||||
* g++.dg/parse/crash13.C: Likewise.
|
||||
* g++.dg/template/instantiate3.C: Likewise.
|
||||
|
||||
2004-03-08 Eric Christopher <echristo@redhat.com>
|
||||
|
||||
* * lib/target-supports.exp: Enable libiconv in test
|
||||
|
|
3
gcc/testsuite/g++.dg/ext/anon-struct4.C
Normal file
3
gcc/testsuite/g++.dg/ext/anon-struct4.C
Normal file
|
@ -0,0 +1,3 @@
|
|||
// PR c++/14401
|
||||
|
||||
struct { struct { int& i ; } bar ; } foo ; // { dg-error "" }
|
6
gcc/testsuite/g++.dg/init/ctor3.C
Normal file
6
gcc/testsuite/g++.dg/init/ctor3.C
Normal file
|
@ -0,0 +1,6 @@
|
|||
// PR c++/14401
|
||||
|
||||
struct S {
|
||||
S() {} // { dg-error "" }
|
||||
const int i;
|
||||
};
|
5
gcc/testsuite/g++.dg/init/union1.C
Normal file
5
gcc/testsuite/g++.dg/init/union1.C
Normal file
|
@ -0,0 +1,5 @@
|
|||
// PR c++/14401
|
||||
|
||||
union U {
|
||||
int& i; // { dg-error "" }
|
||||
};
|
|
@ -9,5 +9,5 @@ class X;
|
|||
|
||||
void foo() {
|
||||
X x(1); // { dg-error "incomplete type" "" }
|
||||
bar(x); // { dg-error "undeclared" "" }
|
||||
bar(x); // { dg-error "not declared" "" }
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Copyroght (C) 2003 Free Software Foundation
|
||||
// Origin: PR/12832, Jonathan Wakely <redi@gcc.gnu.org>
|
||||
|
||||
void f() { g(); } // { dg-error "undeclared" "" }
|
||||
void g() { } // { dg-error "used" "" }
|
||||
void f() { g(); } // { dg-error "not declared" "" }
|
||||
void g() { }
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
void init ()
|
||||
{
|
||||
do { } while (0)
|
||||
obj = 0; // { dg-error "expected|undeclared" "" }
|
||||
obj = 0; // { dg-error "expected|not declared" "" }
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ void g ()
|
|||
{
|
||||
B *bp;
|
||||
N::A *ap;
|
||||
f (bp); // { dg-error "undeclared" }
|
||||
f (bp); // { dg-error "not declared" }
|
||||
f (ap);
|
||||
}
|
||||
|
|
|
@ -18,5 +18,5 @@ void func(A<T>::B* ) // { dg-error "variable|template|expression" }
|
|||
|
||||
int main()
|
||||
{
|
||||
func<void>(0); // { dg-error "undeclared|expression|;" }
|
||||
func<void>(0); // { dg-error "not declared|expression|;" }
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ template <class TYPE>
|
|||
struct ACE_Cleanup_Adapter
|
||||
{
|
||||
TYPE &object ()
|
||||
{ return object_; } // { dg-error "undeclared|reported" }
|
||||
{ return object_; } // { dg-error "not declared|reported" }
|
||||
TYPE object_; // { dg-error "incomplete type" }
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue