Commit 824b9a4c by Mike Stump

90th Cygnus<->FSF quick merge

From-SVN: r13604
parent 44c389e4
Thu Jan 30 19:18:00 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (lookup_name_real): Also build a TYPENAME_TYPE for nested
classes.
* pt.c (tsubst): Don't recurse for the type of a TYPENAME_TYPE.
Wed Jan 29 11:40:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (duplicate_decls): Next route, pedwarn about different
exceptions if -pedantic *or* olddecl !DECL_IN_SYSTEM_HEADER.
Tue Jan 28 20:43:29 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* cp-tree.h (HAS_DEFAULT_IMPLEMENTATION): Delete macro.
(struct lang_type): Delete has_default_implementation member.
Increase dummy to 21.
* decl.c (start_method): Delete usage.
* cp-tree.h (build_call, null_ptr_cst_p, in_function_p,
store_after_parms, start_decl_1, auto_function): Add decls.
(get_arglist_len_in_bytes, declare_implicit_exception,
have_exceptions_p, make_type_decl, typedecl_for_tag,
store_in_parms, pop_implicit_try_blocks, push_exception_cleanup,
build_component_type_expr, cplus_exception_name,
{make,clear}_anon_parm_name, dont_see_typename): Removed decls.
* call.c (build_this): Make static.
(is_complete): Likewise.
(implicit_conversion): Likewise.
(reference_binding): Likewise.
(standard_conversion): Likewise.
(strip_top_quals): Likewise.
(non_reference): Likewise.
(build_conv): Likewise.
(user_harshness): Likewise.
(rank_for_ideal): Likewise.
* decl.c (start_decl_1): Delete forward decl.
(push_decl_level): Make static.
(resume_binding_level): Make static.
(namespace_bindings_p): Make static.
(declare_namespace_level): Make static.
(lookup_name_real): Make static.
(duplicate_decls): Make static. Take register off NEWDECL and
OLDDECL parm decls.
* decl2.c (get_sentry): Make static.
(temp_name_p): Delete fn.
* except.c (auto_function): Delete decl.
* lex.c (handle_{cp,sysv}_pragma): Make static.
(handle_sysv_pragma) [HANDLE_SYSV_PRAGMA]: Add forward decl.
* method.c (do_build_{copy_constructor,assign_ref}): Make static.
* pt.c (tsubst_expr_values): Make static.
* rtti.c (combine_strings): Delete decl.
Tue Jan 28 16:40:40 1997 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (push_template_decl): Handle getting a typedef.
* call.c (build_new_function_call): Complain about void arg.
Tue Jan 28 15:25:09 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (duplicate_decls): Give pedwarn of different exceptions
if -pedantic, instead of olddecl !DECL_IN_SYSTEM_HEADER.
Mon Jan 27 19:21:29 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_throw): Don't expand the cleanup tree here,
since we are not going to write the rtl out. Fixes problem with
-g -O on SPARC.
Mon Jan 27 16:24:35 1997 Sean McNeil <sean@mcneil.com>
* Make-lang.in: Add $(exeext) as necessary.
Mon Jan 27 13:20:39 1997 Mike Stump <mrs@cygnus.com>
* parse.y (handler_seq): Must have at least one catch clause.
Sat Jan 25 12:00:05 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (add_builtin_candidate): Restore ?: hack.
* decl.c (grok_op_properties): More warnings.
Sat Jan 25 08:50:03 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* decl.c (duplicate_decls): On second thought, do it as a pedwarn
still but only if !DECL_IN_SYSTEM_HEADER (olddecl).
* decl.c (duplicate_decls): Scale back to a warning, and only do
'em if -pedantic.
Fri Jan 24 17:52:54 1997 Mike Stump <mrs@cygnus.com>
* decl.c (duplicate_decls): pedwarn mismatched exception
specifications.
Thu Jan 23 18:18:54 1997 Mike Stump <mrs@cygnus.com>
* call.c (build_new_method_call): Don't display the invisible
argument for controlling virtual bases.
Thu Jan 23 16:48:10 1997 Mike Stump <mrs@cygnus.com>
* new: Add nothrow new and delete, bad_alloc and throw specifications
for delete.
* decl.c (init_decl_processing): Add throw specification for delete.
* new.cc (nothrow): Define.
* lex.c (real_yylex): Removing warning that throw and friends are
keywords.
* new1.cc (operator new (size_t sz, const nothrow_t&)): Define.
* new2.cc (operator new[] (size_t sz, const nothrow_t&): Define.
* Make-lang.in: Add new{1,2}.{cc,o}.
Thu Jan 23 16:39:06 1997 Jason Merrill <jason@yorick.cygnus.com>
* lex.c (cons_up_default_function): Fix return type of synth op=.
* init.c (emit_base_init): Add warnings for uninitialized members
and bases.
* decl.c (xref_basetypes): Add warning for non-polymorphic type
with destructor used as base type.
* decl.c (grok_op_properties): Add warning for op= returning void.
* typeck.c (c_expand_return): Add warning for op= returning anything
other than *this.
* class.c (finish_struct_1): Add warning for class with pointers
but not copy ctor or copy op=.
* cp-tree.h (TI_PENDING_TEMPLATE_FLAG): New macro.
* pt.c (add_pending_template): Use it instead of LANG_FLAG_0.
(instantiate_template): If -fexternal-templates, add this
instantiation to pending_templates.
* decl2.c (copy_assignment_arg_p): Disable old hack to support
Booch components.
Tue Jan 21 18:32:04 1997 Mike Stump <mrs@cygnus.com>
* cvt.c (cp_convert): Pedwarn enum to pointer conversions.
Mon Jan 20 17:59:51 1997 Jason Merrill <jason@yorick.cygnus.com> Mon Jan 20 17:59:51 1997 Jason Merrill <jason@yorick.cygnus.com>
* call.c (standard_conversion): Handle getting references. Tack * call.c (standard_conversion): Handle getting references. Tack
......
...@@ -58,9 +58,10 @@ CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \ ...@@ -58,9 +58,10 @@ CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
$(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h $(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h
# Extra code to include in libgcc2. # Extra code to include in libgcc2.
CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o exception.o CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o new1.o new2.o exception.o
CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/exception.cc \ CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \
$(srcdir)/cp/tinfo.cc $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h $(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \
$(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
# Define the names for selecting c++ in LANGUAGES. # Define the names for selecting c++ in LANGUAGES.
# Note that it would be nice to move the dependency on g++ # Note that it would be nice to move the dependency on g++
...@@ -125,9 +126,9 @@ cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o ...@@ -125,9 +126,9 @@ cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o
# Build hooks: # Build hooks:
c++.all.build: g++ $(DEMANGLER_PROG) c++.all.build: g++$(exeext) $(DEMANGLER_PROG)
c++.all.cross: g++-cross $(DEMANGLER_PROG) c++.all.cross: g++-cross$(exeext) $(DEMANGLER_PROG)
c++.start.encap: g++ c++.start.encap: g++$(exeext)
c++.rest.encap: $(DEMANGLER_PROG) c++.rest.encap: $(DEMANGLER_PROG)
c++.info: c++.info:
...@@ -146,6 +147,12 @@ exception.o: cc1plus $(srcdir)/cp/exception.cc ...@@ -146,6 +147,12 @@ exception.o: cc1plus $(srcdir)/cp/exception.cc
new.o: cc1plus $(srcdir)/cp/new.cc new.o: cc1plus $(srcdir)/cp/new.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/new.cc -c $(srcdir)/cp/new.cc
new1.o: cc1plus $(srcdir)/cp/new1.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/new1.cc
new2.o: cc1plus $(srcdir)/cp/new2.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/new2.cc
# We want to update cplib2.txt if any of the source files change... # We want to update cplib2.txt if any of the source files change...
cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
......
...@@ -82,7 +82,7 @@ rank_for_overload (x, y) ...@@ -82,7 +82,7 @@ rank_for_overload (x, y)
/* Compare two candidates, argument by argument. */ /* Compare two candidates, argument by argument. */
int static int
rank_for_ideal (x, y) rank_for_ideal (x, y)
struct candidate *x, *y; struct candidate *x, *y;
{ {
...@@ -627,7 +627,7 @@ convert_harshness (type, parmtype, parm) ...@@ -627,7 +627,7 @@ convert_harshness (type, parmtype, parm)
/* A clone of build_type_conversion for checking user-defined conversions in /* A clone of build_type_conversion for checking user-defined conversions in
overload resolution. */ overload resolution. */
int static int
user_harshness (type, parmtype) user_harshness (type, parmtype)
register tree type, parmtype; register tree type, parmtype;
{ {
...@@ -2935,7 +2935,7 @@ null_ptr_cst_p (t) ...@@ -2935,7 +2935,7 @@ null_ptr_cst_p (t)
return 0; return 0;
} }
tree static tree
build_conv (code, type, from) build_conv (code, type, from)
enum tree_code code; enum tree_code code;
tree type, from; tree type, from;
...@@ -2967,7 +2967,7 @@ build_conv (code, type, from) ...@@ -2967,7 +2967,7 @@ build_conv (code, type, from)
return t; return t;
} }
tree static tree
non_reference (t) non_reference (t)
tree t; tree t;
{ {
...@@ -2976,7 +2976,7 @@ non_reference (t) ...@@ -2976,7 +2976,7 @@ non_reference (t)
return t; return t;
} }
tree static tree
strip_top_quals (t) strip_top_quals (t)
tree t; tree t;
{ {
...@@ -2989,7 +2989,7 @@ strip_top_quals (t) ...@@ -2989,7 +2989,7 @@ strip_top_quals (t)
TO, if any. For proper handling of null pointer constants, you must TO, if any. For proper handling of null pointer constants, you must
also pass the expression EXPR to convert from. */ also pass the expression EXPR to convert from. */
tree static tree
standard_conversion (to, from, expr) standard_conversion (to, from, expr)
tree to, from, expr; tree to, from, expr;
{ {
...@@ -3158,7 +3158,7 @@ standard_conversion (to, from, expr) ...@@ -3158,7 +3158,7 @@ standard_conversion (to, from, expr)
Currently does not distinguish in the generated trees between binding to Currently does not distinguish in the generated trees between binding to
an lvalue and a temporary. Should it? */ an lvalue and a temporary. Should it? */
tree static tree
reference_binding (rto, rfrom, expr, flags) reference_binding (rto, rfrom, expr, flags)
tree rto, rfrom, expr; tree rto, rfrom, expr;
int flags; int flags;
...@@ -3218,7 +3218,7 @@ reference_binding (rto, rfrom, expr, flags) ...@@ -3218,7 +3218,7 @@ reference_binding (rto, rfrom, expr, flags)
FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is
significant. */ significant. */
tree static tree
implicit_conversion (to, from, expr, flags) implicit_conversion (to, from, expr, flags)
tree to, from, expr; tree to, from, expr;
int flags; int flags;
...@@ -3498,7 +3498,7 @@ build_builtin_candidate (candidates, fnname, type1, type2, ...@@ -3498,7 +3498,7 @@ build_builtin_candidate (candidates, fnname, type1, type2,
return cand; return cand;
} }
int static int
is_complete (t) is_complete (t)
tree t; tree t;
{ {
...@@ -3841,15 +3841,10 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2, ...@@ -3841,15 +3841,10 @@ add_builtin_candidate (candidates, code, code2, fnname, type1, type2,
break; break;
case COND_EXPR: case COND_EXPR:
#if 0
/* Kludge around broken overloading rules whereby /* Kludge around broken overloading rules whereby
bool ? const char& : enum is ambiguous bool ? const char& : enum is ambiguous
(between int and const char&). */ (between int and const char&). */
/* Not needed for compiles without -pedantic, since the rank compare
in joust will pick the int promotion. Let's just leave this out
for now. */
flags |= LOOKUP_NO_TEMP_BIND; flags |= LOOKUP_NO_TEMP_BIND;
#endif
/* Extension: Support ?: of enumeral type. Hopefully this will not /* Extension: Support ?: of enumeral type. Hopefully this will not
be an extension for long. */ be an extension for long. */
...@@ -4124,7 +4119,7 @@ splice_viable (cands) ...@@ -4124,7 +4119,7 @@ splice_viable (cands)
return cands; return cands;
} }
tree static tree
build_this (obj) build_this (obj)
tree obj; tree obj;
{ {
...@@ -4306,8 +4301,15 @@ build_new_function_call (fn, args, obj) ...@@ -4306,8 +4301,15 @@ build_new_function_call (fn, args, obj)
tree templates = NULL_TREE; tree templates = NULL_TREE;
for (t = args; t; t = TREE_CHAIN (t)) for (t = args; t; t = TREE_CHAIN (t))
if (TREE_VALUE (t) == error_mark_node) {
return error_mark_node; if (TREE_VALUE (t) == error_mark_node)
return error_mark_node;
else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE)
{
error ("invalid use of void expression");
return error_mark_node;
}
}
for (t = TREE_VALUE (fn); t; t = DECL_CHAIN (t)) for (t = TREE_VALUE (fn); t; t = DECL_CHAIN (t))
{ {
...@@ -5190,6 +5192,12 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -5190,6 +5192,12 @@ build_new_method_call (instance, name, args, basetype_path, flags)
struct z_candidate *candidates = 0, *cand; struct z_candidate *candidates = 0, *cand;
tree basetype, mem_args, fns, instance_ptr; tree basetype, mem_args, fns, instance_ptr;
tree pretty_name; tree pretty_name;
tree user_args = args;
/* If there is an extra argument for controlling virtual bases,
remove it for error reporting. */
if (flags & LOOKUP_HAS_IN_CHARGE)
user_args = TREE_CHAIN (args);
for (fns = args; fns; fns = TREE_CHAIN (fns)) for (fns = args; fns; fns = TREE_CHAIN (fns))
if (TREE_VALUE (fns) == error_mark_node) if (TREE_VALUE (fns) == error_mark_node)
...@@ -5284,7 +5292,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -5284,7 +5292,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
if (flags & LOOKUP_SPECULATIVELY) if (flags & LOOKUP_SPECULATIVELY)
return NULL_TREE; return NULL_TREE;
cp_error ("no matching function for call to `%T::%D (%A)%V'", basetype, cp_error ("no matching function for call to `%T::%D (%A)%V'", basetype,
pretty_name, args, TREE_TYPE (TREE_TYPE (instance_ptr))); pretty_name, user_args, TREE_TYPE (TREE_TYPE (instance_ptr)));
print_z_candidates (candidates); print_z_candidates (candidates);
return error_mark_node; return error_mark_node;
} }
...@@ -5293,7 +5301,8 @@ build_new_method_call (instance, name, args, basetype_path, flags) ...@@ -5293,7 +5301,8 @@ build_new_method_call (instance, name, args, basetype_path, flags)
if (cand == 0) if (cand == 0)
{ {
cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name, args); cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name,
user_args);
print_z_candidates (candidates); print_z_candidates (candidates);
return error_mark_node; return error_mark_node;
} }
......
...@@ -3046,6 +3046,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3046,6 +3046,7 @@ finish_struct_1 (t, warn_anon)
tree access_decls = NULL_TREE; tree access_decls = NULL_TREE;
int aggregate = 1; int aggregate = 1;
int empty = 1; int empty = 1;
int has_pointers = 0;
if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
pedwarn ("anonymous class type not used to declare any objects"); pedwarn ("anonymous class type not used to declare any objects");
...@@ -3334,6 +3335,9 @@ finish_struct_1 (t, warn_anon) ...@@ -3334,6 +3335,9 @@ finish_struct_1 (t, warn_anon)
} }
} }
if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
has_pointers = 1;
/* If any field is const, the structure type is pseudo-const. */ /* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x)) if (TREE_READONLY (x))
{ {
...@@ -3581,6 +3585,22 @@ finish_struct_1 (t, warn_anon) ...@@ -3581,6 +3585,22 @@ finish_struct_1 (t, warn_anon)
} }
} }
/* Effective C++ rule 11. */
if (has_pointers && extra_warnings
&& ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
{
cp_warning ("`%#T' has pointer data members", t);
if (! TYPE_HAS_INIT_REF (t))
{
cp_warning (" but does not override `%T(const %T&)'", t, t);
if (! TYPE_HAS_ASSIGN_REF (t))
cp_warning (" or `operator=(const %T&)'", t);
}
else if (! TYPE_HAS_ASSIGN_REF (t))
cp_warning (" but does not override `operator=(const %T&)'", t);
}
TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t);
TYPE_HAS_COMPLEX_INIT_REF (t) TYPE_HAS_COMPLEX_INIT_REF (t)
......
...@@ -1194,11 +1194,12 @@ cp_convert (type, expr, convtype, flags) ...@@ -1194,11 +1194,12 @@ cp_convert (type, expr, convtype, flags)
if (INTEGRAL_CODE_P (code)) if (INTEGRAL_CODE_P (code))
{ {
tree intype = TREE_TYPE (e); tree intype = TREE_TYPE (e);
/* enum = enum, enum = int, enum = float are all errors. */ /* enum = enum, enum = int, enum = float, (enum)pointer are all
errors. */
if (flag_int_enum_equivalence == 0 if (flag_int_enum_equivalence == 0
&& TREE_CODE (type) == ENUMERAL_TYPE && TREE_CODE (type) == ENUMERAL_TYPE
&& ARITHMETIC_TYPE_P (intype) && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC))
&& ! (convtype & CONV_STATIC)) || (TREE_CODE (intype) == POINTER_TYPE)))
{ {
cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type); cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type);
......
...@@ -483,6 +483,7 @@ tree signed_size_zero_node; ...@@ -483,6 +483,7 @@ tree signed_size_zero_node;
/* Allocate a level of searching. */ /* Allocate a level of searching. */
static
struct stack_level * struct stack_level *
push_decl_level (stack, obstack) push_decl_level (stack, obstack)
struct stack_level *stack; struct stack_level *stack;
...@@ -762,7 +763,7 @@ suspend_binding_level () ...@@ -762,7 +763,7 @@ suspend_binding_level ()
} }
} }
void static void
resume_binding_level (b) resume_binding_level (b)
struct binding_level *b; struct binding_level *b;
{ {
...@@ -841,7 +842,7 @@ toplevel_bindings_p () ...@@ -841,7 +842,7 @@ toplevel_bindings_p ()
/* Nonzero if this is a namespace scope. */ /* Nonzero if this is a namespace scope. */
int static int
namespace_bindings_p () namespace_bindings_p ()
{ {
return current_binding_level->namespace_p; return current_binding_level->namespace_p;
...@@ -879,7 +880,7 @@ declare_pseudo_global_level () ...@@ -879,7 +880,7 @@ declare_pseudo_global_level ()
current_binding_level->pseudo_global = 1; current_binding_level->pseudo_global = 1;
} }
void static void
declare_namespace_level () declare_namespace_level ()
{ {
current_binding_level->namespace_p = 1; current_binding_level->namespace_p = 1;
...@@ -2351,7 +2352,7 @@ warn_extern_redeclared_static (newdecl, olddecl) ...@@ -2351,7 +2352,7 @@ warn_extern_redeclared_static (newdecl, olddecl)
int int
duplicate_decls (newdecl, olddecl) duplicate_decls (newdecl, olddecl)
register tree newdecl, olddecl; tree newdecl, olddecl;
{ {
extern struct obstack permanent_obstack; extern struct obstack permanent_obstack;
unsigned olddecl_uid = DECL_UID (olddecl); unsigned olddecl_uid = DECL_UID (olddecl);
...@@ -2679,11 +2680,12 @@ duplicate_decls (newdecl, olddecl) ...@@ -2679,11 +2680,12 @@ duplicate_decls (newdecl, olddecl)
TREE_TYPE (olddecl) = build_exception_variant (newtype, TREE_TYPE (olddecl) = build_exception_variant (newtype,
TYPE_RAISES_EXCEPTIONS (oldtype)); TYPE_RAISES_EXCEPTIONS (oldtype));
if (! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) if ((pedantic || ! DECL_IN_SYSTEM_HEADER (olddecl))
&& ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
{ {
cp_error ("declaration of `%D' throws different exceptions...", cp_pedwarn ("declaration of `%D' throws different exceptions",
newdecl); newdecl);
cp_error_at ("...from previous declaration here", olddecl); cp_pedwarn_at ("previous declaration here", olddecl);
} }
} }
TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;
...@@ -4275,7 +4277,7 @@ make_typename_type (context, name) ...@@ -4275,7 +4277,7 @@ make_typename_type (context, name)
If PREFER_TYPE is -2, we're being called from yylex(). (UGLY) If PREFER_TYPE is -2, we're being called from yylex(). (UGLY)
Otherwise we prefer non-TYPE_DECLs. */ Otherwise we prefer non-TYPE_DECLs. */
tree static tree
lookup_name_real (name, prefer_type, nonclass) lookup_name_real (name, prefer_type, nonclass)
tree name; tree name;
int prefer_type, nonclass; int prefer_type, nonclass;
...@@ -4897,6 +4899,9 @@ init_decl_processing () ...@@ -4897,6 +4899,9 @@ init_decl_processing ()
void_ftype_ptr void_ftype_ptr
= build_function_type (void_type_node, = build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node, endlink)); tree_cons (NULL_TREE, ptr_type_node, endlink));
void_ftype_ptr
= build_exception_variant (void_ftype_ptr,
tree_cons (NULL_TREE, NULL_TREE, NULL_TREE));
float_ftype_float float_ftype_float
= build_function_type (float_type_node, = build_function_type (float_type_node,
...@@ -5659,8 +5664,6 @@ groktypename (typename) ...@@ -5659,8 +5664,6 @@ groktypename (typename)
to parse initializers. */ to parse initializers. */
int debug_temp_inits = 1; int debug_temp_inits = 1;
void start_decl_1 ();
tree tree
start_decl (declarator, declspecs, initialized) start_decl (declarator, declspecs, initialized)
tree declarator, declspecs; tree declarator, declspecs;
...@@ -10145,6 +10148,31 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10145,6 +10148,31 @@ grok_op_properties (decl, virtualp, friendp)
else else
cp_error ("`%D' must take either one or two arguments", decl); cp_error ("`%D' must take either one or two arguments", decl);
} }
/* More Effective C++ rule 6. */
if (extra_warnings
&& (name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR]))
{
tree arg = TREE_VALUE (argtypes);
tree ret = TREE_TYPE (TREE_TYPE (decl));
if (methodp || TREE_CODE (arg) == REFERENCE_TYPE)
arg = TREE_TYPE (arg);
arg = TYPE_MAIN_VARIANT (arg);
if (list_length (argtypes) == 2)
{
if (TREE_CODE (ret) != REFERENCE_TYPE
|| !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ret)),
arg, 1))
cp_warning ("prefix `%D' should return `%T'", decl,
build_reference_type (arg));
}
else
{
if (!comptypes (TYPE_MAIN_VARIANT (ret), arg, 1))
cp_warning ("postfix `%D' should return `%T'", decl, arg);
}
}
} }
else if (unary_op_p (name)) else if (unary_op_p (name))
{ {
...@@ -10165,7 +10193,25 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10165,7 +10193,25 @@ grok_op_properties (decl, virtualp, friendp)
else else
cp_error ("`%D' must take exactly two arguments", decl); cp_error ("`%D' must take exactly two arguments", decl);
} }
}
/* More Effective C++ rule 7. */
if (extra_warnings
&& (name == ansi_opname [TRUTH_ANDIF_EXPR]
|| name == ansi_opname [TRUTH_ORIF_EXPR]
|| name == ansi_opname [COMPOUND_EXPR]))
cp_warning ("user-defined `%D' always evaluates both arguments",
decl);
}
/* Effective C++ rule 23. */
if (extra_warnings
&& list_length (argtypes) == 3
&& (name == ansi_opname [PLUS_EXPR]
|| name == ansi_opname [MINUS_EXPR]
|| name == ansi_opname [TRUNC_DIV_EXPR]
|| name == ansi_opname [MULT_EXPR])
&& TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE)
cp_warning ("`%D' should return by value", decl);
/* 13.4.0.8 */ /* 13.4.0.8 */
if (argtypes) if (argtypes)
...@@ -10465,6 +10511,13 @@ xref_basetypes (code_type_node, name, ref, binfo) ...@@ -10465,6 +10511,13 @@ xref_basetypes (code_type_node, name, ref, binfo)
continue; continue;
} }
/* Effective C++ rule 14. The case of virtual functions but
non-virtual dtor is handled in finish_struct_1. */
if (warn_nonvdtor && ! TYPE_VIRTUAL_P (basetype)
&& TYPE_HAS_DESTRUCTOR (basetype))
cp_warning ("base class `%#T' has a non-virtual destructor",
basetype);
/* Note that the BINFO records which describe individual /* Note that the BINFO records which describe individual
inheritances are *not* shared in the lattice! They inheritances are *not* shared in the lattice! They
cannot be shared because a given baseclass may be cannot be shared because a given baseclass may be
...@@ -10990,6 +11043,12 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -10990,6 +11043,12 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
if (warn_about_return_type) if (warn_about_return_type)
warning ("return-type defaults to `int'"); warning ("return-type defaults to `int'");
/* Effective C++ rule 15. See also c_expand_return. */
if (extra_warnings
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
&& TREE_TYPE (fntype) == void_type_node)
cp_warning ("`operator=' should return a reference to `*this'");
/* Make the init_value nonzero so pushdecl knows this is not tentative. /* Make the init_value nonzero so pushdecl knows this is not tentative.
error_mark_node is replaced below (in poplevel) with the BLOCK. */ error_mark_node is replaced below (in poplevel) with the BLOCK. */
DECL_INITIAL (decl1) = error_mark_node; DECL_INITIAL (decl1) = error_mark_node;
...@@ -12045,11 +12104,7 @@ start_method (declspecs, declarator) ...@@ -12045,11 +12104,7 @@ start_method (declspecs, declarator)
return NULL_TREE; return NULL_TREE;
if (IS_SIGNATURE (current_class_type)) if (IS_SIGNATURE (current_class_type))
{ IS_DEFAULT_IMPLEMENTATION (fndecl) = 1;
IS_DEFAULT_IMPLEMENTATION (fndecl) = 1;
/* In case we need this info later. */
HAS_DEFAULT_IMPLEMENTATION (current_class_type) = 1;
}
if (DECL_IN_AGGR_P (fndecl)) if (DECL_IN_AGGR_P (fndecl))
{ {
......
...@@ -1698,7 +1698,11 @@ copy_assignment_arg_p (parmtype, virtualp) ...@@ -1698,7 +1698,11 @@ copy_assignment_arg_p (parmtype, virtualp)
parmtype = TREE_TYPE (parmtype); parmtype = TREE_TYPE (parmtype);
if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type) if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type)
|| (virtualp && DERIVED_FROM_P (parmtype, current_class_type))) #if 0
/* Non-standard hack to support old Booch components. */
|| (! virtualp && DERIVED_FROM_P (parmtype, current_class_type))
#endif
)
return 1; return 1;
return 0; return 0;
...@@ -1972,16 +1976,6 @@ get_temp_regvar (type, init) ...@@ -1972,16 +1976,6 @@ get_temp_regvar (type, init)
return decl; return decl;
} }
/* Make the macro TEMP_NAME_P available to units which do not
include c-tree.h. */
int
temp_name_p (decl)
tree decl;
{
return TEMP_NAME_P (decl);
}
/* Finish off the processing of a UNION_TYPE structure. /* Finish off the processing of a UNION_TYPE structure.
If there are static members, then all members are If there are static members, then all members are
static, and must be laid out together. If the static, and must be laid out together. If the
...@@ -2224,8 +2218,10 @@ coerce_delete_type (type) ...@@ -2224,8 +2218,10 @@ coerce_delete_type (type)
type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types)); type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types));
arg_types = TREE_CHAIN (arg_types); arg_types = TREE_CHAIN (arg_types);
} }
if (TREE_TYPE (type) != void_type_node) if (TREE_TYPE (type) != void_type_node)
e1 = 1, error ("`operator delete' must return type `void'"); e1 = 1, error ("`operator delete' must return type `void'");
if (arg_types == NULL_TREE if (arg_types == NULL_TREE
|| TREE_VALUE (arg_types) != ptr_type_node) || TREE_VALUE (arg_types) != ptr_type_node)
e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); e2 = 1, error ("`operator delete' takes type `void *' as first parameter");
...@@ -2249,8 +2245,10 @@ coerce_delete_type (type) ...@@ -2249,8 +2245,10 @@ coerce_delete_type (type)
error ("`...' invalid in specification of `operator delete'"); error ("`...' invalid in specification of `operator delete'");
} }
} }
if (e3) if (e3)
arg_types = tree_cons (NULL_TREE, ptr_type_node, build_tree_list (NULL_TREE, sizetype)); arg_types = tree_cons (NULL_TREE, ptr_type_node,
build_tree_list (NULL_TREE, sizetype));
else if (e3 |= e2) else if (e3 |= e2)
{ {
if (arg_types == NULL_TREE) if (arg_types == NULL_TREE)
...@@ -2663,7 +2661,7 @@ extern tree maybe_templates; ...@@ -2663,7 +2661,7 @@ extern tree maybe_templates;
extern struct obstack permanent_obstack; extern struct obstack permanent_obstack;
extern tree get_id_2 (); extern tree get_id_2 ();
tree static tree
get_sentry (base) get_sentry (base)
tree base; tree base;
{ {
......
...@@ -223,8 +223,6 @@ do_function_call (func, params, return_type) ...@@ -223,8 +223,6 @@ do_function_call (func, params, return_type)
/* ========================================================================= */ /* ========================================================================= */
extern tree auto_function PROTO((tree, tree, enum built_in_function));
/* sets up all the global eh stuff that needs to be initialized at the /* sets up all the global eh stuff that needs to be initialized at the
start of compilation. start of compilation.
...@@ -531,7 +529,8 @@ expand_start_catch_block (declspecs, declarator) ...@@ -531,7 +529,8 @@ expand_start_catch_block (declspecs, declarator)
code to handle jumping back to the correct place, and for emitting code to handle jumping back to the correct place, and for emitting
the label to jump to if this catch block didn't match. */ the label to jump to if this catch block didn't match. */
void expand_end_catch_block () void
expand_end_catch_block ()
{ {
rtx start_region_label_rtx; rtx start_region_label_rtx;
rtx end_region_label_rtx; rtx end_region_label_rtx;
...@@ -1070,7 +1069,6 @@ expand_throw (exp) ...@@ -1070,7 +1069,6 @@ expand_throw (exp)
} }
else else
{ {
rtx cleanup_insns;
tree object; tree object;
/* Make a copy of the thrown object. WP 15.1.5 */ /* Make a copy of the thrown object. WP 15.1.5 */
...@@ -1088,12 +1086,9 @@ expand_throw (exp) ...@@ -1088,12 +1086,9 @@ expand_throw (exp)
object = build_reinterpret_cast (TREE_TYPE (exp), saved_throw_value); object = build_reinterpret_cast (TREE_TYPE (exp), saved_throw_value);
object = build_indirect_ref (object, NULL_PTR); object = build_indirect_ref (object, NULL_PTR);
cleanup = maybe_build_cleanup_and_delete (object); cleanup = maybe_build_cleanup_and_delete (object);
if (cleanup)
expand_expr (cleanup, const0_rtx, VOIDmode, 0);
cleanup_insns = get_insns ();
end_sequence (); end_sequence ();
if (cleanup && cleanup_insns) if (cleanup)
{ {
cleanup = start_anon_func (); cleanup = start_anon_func ();
......
...@@ -587,7 +587,12 @@ emit_base_init (t, immediately) ...@@ -587,7 +587,12 @@ emit_base_init (t, immediately)
if (TREE_PURPOSE (rbase_init_list)) if (TREE_PURPOSE (rbase_init_list))
init = TREE_VALUE (rbase_init_list); init = TREE_VALUE (rbase_init_list);
else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo)))
init = NULL_TREE; {
init = NULL_TREE;
if (extra_warnings && copy_args_p (current_function_decl))
cp_warning ("base class `%#T' should be explicitly initialized in the copy constructor",
BINFO_TYPE (base_binfo));
}
if (init != void_list_node) if (init != void_list_node)
{ {
...@@ -673,6 +678,11 @@ emit_base_init (t, immediately) ...@@ -673,6 +678,11 @@ emit_base_init (t, immediately)
init = DECL_INITIAL (member); init = DECL_INITIAL (member);
from_init_list = 0; from_init_list = 0;
/* Effective C++ rule 12. */
if (extra_warnings && init == NULL_TREE
&& TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE)
cp_warning ("`%D' should be initialized in the member initialization list", member);
} }
perform_member_init (member, name, init, from_init_list); perform_member_init (member, name, init, from_init_list);
......
...@@ -1671,12 +1671,13 @@ cons_up_default_function (type, full_name, kind) ...@@ -1671,12 +1671,13 @@ cons_up_default_function (type, full_name, kind)
break; break;
case 5: case 5:
type = build_type_variant (type, 1, 0);
/* Fall through... */
case 6: case 6:
retref = 1; retref = 1;
declspecs = build_decl_list (NULL_TREE, type); declspecs = build_decl_list (NULL_TREE, type);
if (kind == 5)
type = build_type_variant (type, 1, 0);
name = ansi_opname [(int) MODIFY_EXPR]; name = ansi_opname [(int) MODIFY_EXPR];
argtype = build_reference_type (type); argtype = build_reference_type (type);
...@@ -1894,7 +1895,10 @@ get_last_nonwhite_on_line () ...@@ -1894,7 +1895,10 @@ get_last_nonwhite_on_line ()
int linemode; int linemode;
int handle_cp_pragma (); #ifdef HANDLE_SYSV_PRAGMA
static int handle_sysv_pragma ();
#endif
static int handle_cp_pragma ();
int int
check_newline () check_newline ()
...@@ -3005,18 +3009,6 @@ real_yylex () ...@@ -3005,18 +3009,6 @@ real_yylex ()
/* If we did not find a keyword, look for an identifier /* If we did not find a keyword, look for an identifier
(or a typename). */ (or a typename). */
if (strcmp ("catch", token_buffer) == 0
|| strcmp ("throw", token_buffer) == 0
|| strcmp ("try", token_buffer) == 0)
{
static int did_warn = 0;
if (! did_warn && ! flag_exceptions)
{
pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
did_warn = 1;
}
}
if (value == IDENTIFIER || value == TYPESPEC) if (value == IDENTIFIER || value == TYPESPEC)
GNU_xref_ref (current_function_decl, token_buffer); GNU_xref_ref (current_function_decl, token_buffer);
...@@ -4259,7 +4251,7 @@ yyerror (string) ...@@ -4259,7 +4251,7 @@ yyerror (string)
error (buf, token_buffer); error (buf, token_buffer);
} }
int static int
handle_cp_pragma (pname) handle_cp_pragma (pname)
char *pname; char *pname;
{ {
...@@ -4444,7 +4436,7 @@ handle_cp_pragma (pname) ...@@ -4444,7 +4436,7 @@ handle_cp_pragma (pname)
/* This function has to be in this file, in order to get at /* This function has to be in this file, in order to get at
the token types. */ the token types. */
int static int
handle_sysv_pragma (finput, token) handle_sysv_pragma (finput, token)
FILE *finput; FILE *finput;
register int token; register int token;
......
...@@ -1664,7 +1664,7 @@ make_thunk (function, delta) ...@@ -1664,7 +1664,7 @@ make_thunk (function, delta)
void void
emit_thunk (thunk_fndecl) emit_thunk (thunk_fndecl)
tree thunk_fndecl; tree thunk_fndecl;
{ {
rtx insns; rtx insns;
char buffer[250]; char buffer[250];
...@@ -1917,7 +1917,7 @@ largest_union_member (type) ...@@ -1917,7 +1917,7 @@ largest_union_member (type)
/* Generate code for default X(X&) constructor. */ /* Generate code for default X(X&) constructor. */
void static void
do_build_copy_constructor (fndecl) do_build_copy_constructor (fndecl)
tree fndecl; tree fndecl;
{ {
...@@ -2020,7 +2020,7 @@ do_build_copy_constructor (fndecl) ...@@ -2020,7 +2020,7 @@ do_build_copy_constructor (fndecl)
pop_momentary (); pop_momentary ();
} }
void static void
do_build_assign_ref (fndecl) do_build_assign_ref (fndecl)
tree fndecl; tree fndecl;
{ {
......
...@@ -4,3 +4,5 @@ ...@@ -4,3 +4,5 @@
#pragma implementation "new" #pragma implementation "new"
#include "new" #include "new"
const nothrow_t nothrow = { };
...@@ -3724,8 +3724,12 @@ try_block: ...@@ -3724,8 +3724,12 @@ try_block:
; ;
handler_seq: handler_seq:
/* empty */ handler
| handler_seq CATCH | handler_seq handler
;
handler:
CATCH
{ {
if (processing_template_decl) if (processing_template_decl)
{ {
...@@ -3734,7 +3738,7 @@ handler_seq: ...@@ -3734,7 +3738,7 @@ handler_seq:
add_tree ($<ttype>$); add_tree ($<ttype>$);
} }
} }
.pushlevel handler_args .pushlevel handler_args
{ {
if (processing_template_decl) if (processing_template_decl)
{ {
...@@ -3743,7 +3747,7 @@ handler_seq: ...@@ -3743,7 +3747,7 @@ handler_seq:
last_tree = $<ttype>3; last_tree = $<ttype>3;
} }
} }
compstmt compstmt
{ {
if (processing_template_decl) if (processing_template_decl)
{ {
...@@ -3754,7 +3758,7 @@ handler_seq: ...@@ -3754,7 +3758,7 @@ handler_seq:
else else
expand_end_catch_block (); expand_end_catch_block ();
} }
.poplevel .poplevel
; ;
type_specifier_seq: type_specifier_seq:
......
...@@ -67,7 +67,7 @@ void pop_template_decls (); ...@@ -67,7 +67,7 @@ void pop_template_decls ();
tree classtype_mangled_name (); tree classtype_mangled_name ();
static char * mangle_class_name_for_template (); static char * mangle_class_name_for_template ();
tree tsubst_expr_values (); static tree tsubst_expr_values ();
tree most_specialized_class PROTO((tree, tree)); tree most_specialized_class PROTO((tree, tree));
tree get_class_bindings PROTO((tree, tree, tree)); tree get_class_bindings PROTO((tree, tree, tree));
tree make_temp_vec PROTO((int)); tree make_temp_vec PROTO((int));
...@@ -251,7 +251,7 @@ push_template_decl (decl) ...@@ -251,7 +251,7 @@ push_template_decl (decl)
primary = 1; primary = 1;
/* Partial specialization. */ /* Partial specialization. */
if (TREE_CODE (decl) == TYPE_DECL if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)
&& CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl)))
{ {
tree type = TREE_TYPE (decl); tree type = TREE_TYPE (decl);
...@@ -287,7 +287,7 @@ push_template_decl (decl) ...@@ -287,7 +287,7 @@ push_template_decl (decl)
if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx))
cp_error ("must specialize `%#T' before defining member `%#D'", cp_error ("must specialize `%#T' before defining member `%#D'",
ctx, decl); ctx, decl);
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)); tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl));
else if (! DECL_TEMPLATE_INFO (decl)) else if (! DECL_TEMPLATE_INFO (decl))
{ {
...@@ -309,7 +309,7 @@ push_template_decl (decl) ...@@ -309,7 +309,7 @@ push_template_decl (decl)
info = perm_tree_cons (tmpl, args, NULL_TREE); info = perm_tree_cons (tmpl, args, NULL_TREE);
if (TREE_CODE (decl) == TYPE_DECL) if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
{ {
CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (tmpl)) = info; CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (tmpl)) = info;
DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl));
...@@ -647,13 +647,13 @@ add_pending_template (d) ...@@ -647,13 +647,13 @@ add_pending_template (d)
else else
ti = DECL_TEMPLATE_INFO (d); ti = DECL_TEMPLATE_INFO (d);
if (TREE_LANG_FLAG_0 (ti)) if (TI_PENDING_TEMPLATE_FLAG (ti))
return; return;
*template_tail = perm_tree_cons *template_tail = perm_tree_cons
(current_function_decl, d, NULL_TREE); (current_function_decl, d, NULL_TREE);
template_tail = &TREE_CHAIN (*template_tail); template_tail = &TREE_CHAIN (*template_tail);
TREE_LANG_FLAG_0 (ti) = 1; TI_PENDING_TEMPLATE_FLAG (ti) = 1;
} }
/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of /* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of
...@@ -1359,7 +1359,8 @@ tsubst (t, args, nargs, in_decl) ...@@ -1359,7 +1359,8 @@ tsubst (t, args, nargs, in_decl)
type = TREE_TYPE (t); type = TREE_TYPE (t);
if (type == unknown_type_node) if (type == unknown_type_node)
my_friendly_abort (42); my_friendly_abort (42);
if (type && TREE_CODE (t) != FUNCTION_DECL) if (type && TREE_CODE (t) != FUNCTION_DECL
&& TREE_CODE (t) != TYPENAME_TYPE)
type = tsubst (type, args, nargs, in_decl); type = tsubst (type, args, nargs, in_decl);
switch (TREE_CODE (t)) switch (TREE_CODE (t))
...@@ -2523,6 +2524,9 @@ instantiate_template (tmpl, targ_ptr) ...@@ -2523,6 +2524,9 @@ instantiate_template (tmpl, targ_ptr)
/* substitute template parameters */ /* substitute template parameters */
fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr, len, tmpl); fndecl = tsubst (DECL_RESULT (tmpl), targ_ptr, len, tmpl);
if (flag_external_templates)
add_pending_template (fndecl);
out: out:
function_maybepermanent_obstack = old_fmp_obstack; function_maybepermanent_obstack = old_fmp_obstack;
pop_obstacks (); pop_obstacks ();
...@@ -3520,7 +3524,7 @@ tsubst_chain (t, argvec) ...@@ -3520,7 +3524,7 @@ tsubst_chain (t, argvec)
return NULL_TREE; return NULL_TREE;
} }
tree static tree
tsubst_expr_values (t, argvec) tsubst_expr_values (t, argvec)
tree t, argvec; tree t, argvec;
{ {
......
...@@ -38,9 +38,6 @@ extern struct obstack *permanent_obstack; ...@@ -38,9 +38,6 @@ extern struct obstack *permanent_obstack;
tree type_info_type_node; tree type_info_type_node;
tree tinfo_fn_id; tree tinfo_fn_id;
tree tinfo_fn_type; tree tinfo_fn_type;
/* in c-common.c */
extern tree combine_strings PROTO((tree));
void void
init_rtti_processing () init_rtti_processing ()
...@@ -266,7 +263,7 @@ build_x_typeid (exp) ...@@ -266,7 +263,7 @@ build_x_typeid (exp)
return convert_from_reference (exp); return convert_from_reference (exp);
} }
tree static tree
get_tinfo_var (type) get_tinfo_var (type)
tree type; tree type;
{ {
...@@ -358,7 +355,7 @@ get_tinfo_fn (type) ...@@ -358,7 +355,7 @@ get_tinfo_fn (type)
return d; return d;
} }
tree static tree
get_typeid_1 (type) get_typeid_1 (type)
tree type; tree type;
{ {
...@@ -392,7 +389,7 @@ get_typeid (type) ...@@ -392,7 +389,7 @@ get_typeid (type)
/* Check whether TEST is null before returning RESULT. If TEST is used in /* Check whether TEST is null before returning RESULT. If TEST is used in
RESULT, it must have previously had a save_expr applied to it. */ RESULT, it must have previously had a save_expr applied to it. */
tree static tree
ifnonnull (test, result) ifnonnull (test, result)
tree test, result; tree test, result;
{ {
......
...@@ -7116,6 +7116,12 @@ c_expand_return (retval) ...@@ -7116,6 +7116,12 @@ c_expand_return (retval)
retval = current_class_ptr; retval = current_class_ptr;
} }
/* Effective C++ rule 15. See also start_function. */
if (extra_warnings
&& DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR]
&& retval != current_class_ref)
cp_warning ("`operator=' should return a reference to `*this'");
if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE) if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE)
{ {
current_function_returns_null = 1; current_function_returns_null = 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment