From 6633d6367f902b576a96132ba6a9a53368db66ba Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 18 Jun 1997 02:25:37 +0000 Subject: 91th Cygnus<->FSF quick merge From-SVN: r14253 --- gcc/cp/ChangeLog | 122 ++++++++++++++++++++++++++++++++++++++ gcc/cp/Make-lang.in | 14 ++--- gcc/cp/Makefile.in | 8 +-- gcc/cp/call.c | 20 +++++-- gcc/cp/class.c | 9 ++- gcc/cp/cp-tree.h | 5 +- gcc/cp/cvt.c | 59 +++++-------------- gcc/cp/decl.c | 38 +++++++++++- gcc/cp/decl2.c | 14 ++++- gcc/cp/except.c | 167 ++++++++++++++++++++++++++++++++++++++-------------- gcc/cp/init.c | 7 +++ gcc/cp/lex.c | 8 --- gcc/cp/method.c | 15 ----- gcc/cp/parse.y | 34 +++++++---- gcc/cp/pt.c | 62 +++++++++++++++---- gcc/cp/repo.c | 93 ++++++++++++++++++++--------- gcc/cp/typeck.c | 9 ++- gcc/cp/xref.c | 2 +- 18 files changed, 495 insertions(+), 191 deletions(-) (limited to 'gcc/cp') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 24f3d73..115c4d2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,125 @@ +Tue Jun 17 18:35:57 1997 Mike Stump + + * except.c (expand_builtin_throw): Add support + -fno-sjlj-exceptions -fPIC exception handling on the SPARC. + +Mon Jun 16 01:24:37 1997 Jason Merrill + + * repo.c (extract_string): Null-terminate. + + * cp-tree.h (TI_SPEC_INFO): New macro. + (CLASSTYPE_TI_SPEC_INFO): New macro. + * pt.c (push_template_decl): Correctly determine # of template parms + for partial specs. + + * call.c (compare_ics): Really fix 'this' conversions. + + * pt.c (do_decl_instantiation): Don't crash on explicit inst of + non-template fn. + + * pt.c (push_template_decl): Complain about mismatch in # of + template parms between a class template and a member template. + +Sun Jun 15 02:38:20 1997 Jason Merrill + + * method.c (synthesize_method): You can't call + function_cannot_inline_p after finish_function. + * decl.c (finish_function): Turn on flag_inline_functions and turn + off DECL_INLINE before handing a synthesized method to the + backend. + +Thu Jun 12 17:35:28 1997 Jason Merrill + + * method.c (synthesize_method): Remove July 30 change to never set + DECL_INLINE if at_eof. + +Thu Jun 12 15:25:08 1997 Mike Stump + + * xref.c (GNU_xref_member): Ensure that the node has a + decl_lang_specific part before checking DECL_FRIEND_P. + +Thu Jun 12 12:36:05 1997 Jason Merrill + + * pt.c (instantiate_class_template): Diagnose non-class types used + as bases. + +Wed Jun 11 17:33:40 1997 Jason Merrill + + * typeck.c (build_conditional_expr): Use convert_for_initialization + instead of convert_and_check. + +Wed Jun 11 12:31:33 1997 Brendan Kehoe + + * parse.y (typespec): Don't pedwarn for typeof. + +Tue Jun 10 00:22:09 1997 Jason Merrill + + * repo.c (finish_repo): Only check changes if we would write a + repo file. + + * call.c (compare_ics): Fix handling of 'this' conversions. + + * pt.c (do_decl_instantiation): Support static data too. Rename + from do_function_instantiation. + * cp-tree.h: Adjust. + * parse.y: Adjust. + + * repo.c (extract_string): New fn. + (get_base_filename): Use it. + (init_repo): Compare old args with current args. + +Mon Jun 9 14:25:30 1997 Mike Stump + + * Makefile.in, Make-lang.in: Protect C-ls with a comment + character, idea from Paul Eggert . + +Mon Jun 9 01:52:03 1997 Jason Merrill + + * typeck.c (c_expand_return): Be more persistent in looking for + returned temps. + + * cvt.c (build_up_reference): Use NOP_EXPR for switching from + pointer to reference. + + * class.c (build_vbase_path): Don't do anything if PATH has no steps. + +Sun Jun 8 03:07:05 1997 Jason Merrill + + * init.c (build_member_call, build_offset_ref): + Use do_scoped_id instead of do_identifier. + + * cvt.c (convert): Remove bogosity. + +Sat Jun 7 20:50:17 1997 Brendan Kehoe + + * cvt.c (build_up_reference): Do checks of ARGTYPE and + TARGET_TYPE before trying to use get_binfo. + +Fri Jun 6 17:36:39 1997 Jason Merrill + + * cvt.c (build_up_reference): Call get_binfo to get access control. + + * decl2.c (import_export_decl): If we don't support weaks, leave + statics undefined. + +Fri Jun 6 15:55:49 1997 Mike Stump + + * except.c (expand_builtin_throw): Add support for machines that + cannot access globals after throw's epilogue when + -fno-sjlj-exceptions is used. + +Thu Jun 5 16:28:43 1997 Jason Merrill + + * parse.y: 'std::' becomes '::'. + * lex.c (real_yylex): Remove 'namespace' warning. + * init.c (build_member_call): Ignore 'std::'. + (build_offset_ref): Likewise. + * decl2.c (do_using_directive): Ignore 'using namespace std;'. + (do_toplevel_using_decl): Ignore 'using std::whatever'. + * decl.c (push_namespace): Just sorry. + (pop_namespace): Nop. + (init_decl_processing): Declare std namespace. + Tue Jun 3 18:08:23 1997 Jason Merrill * search.c (push_class_decls): A name which ambiguously refers to diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 264114c..4890a94 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -35,7 +35,7 @@ # - making any compiler driver (eg: g++) # - the compiler proper (eg: cc1plus) # - define the names for selecting the language in LANGUAGES. - +# # Extra flags to pass to recursive makes. CXX_FLAGS_TO_PASS = \ "CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \ @@ -62,7 +62,7 @@ CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o new1.o new2.o exception.o CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \ $(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \ $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h - +# # Define the names for selecting c++ in LANGUAGES. # Note that it would be nice to move the dependency on g++ # into the C++ rule, but that needs a little bit of work @@ -124,7 +124,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \ cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus - +# # Build hooks: c++.all.build: g++$(exeext) $(DEMANGLER_PROG) @@ -181,7 +181,7 @@ cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs @if [ -f cplib2.ready ]; then true; else \ touch cplib2.ready; \ fi - +# # Install hooks: # cc1plus is installed elsewhere as part of $(COMPILERS). @@ -233,7 +233,7 @@ c++.uninstall: -rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext) -rm -rf $(mandir)/$(GXX_INSTALL_NAME)$(manext) -rm -rf $(mandir)/$(GXX_CROSS_NAME)$(manext) - +# # Clean hooks: # A lot of the ancillary files are deleted by the main makefile. # We just have to delete files specific to us. @@ -248,7 +248,7 @@ c++.distclean: c++.extraclean: c++.maintainer-clean: -rm -f cp/parse.c cp/parse.h - +# # Stage hooks: # The main makefile has already created stage?/cp. @@ -260,7 +260,7 @@ c++.stage3: stage3-start -mv cp/*$(objext) stage3/cp c++.stage4: stage4-start -mv cp/*$(objext) stage4/cp - +# # Maintenance hooks: # This target creates the files that can be rebuilt, but go in the diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index 03ba91a..9a7bb0b 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -116,7 +116,7 @@ all: all.indirect ####host overrides ####cross overrides ####build overrides - +# # Now figure out from those variables how to compile and link. all.indirect: Makefile ../cc1plus @@ -153,7 +153,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config # This tells GNU make version 3 not to export all the variables # defined in this file into the environment. .NOEXPORT: - +# # Lists of files for various purposes. # Language-specific object files for g++ @@ -175,7 +175,7 @@ Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure cd ..; $(SHELL) config.status native: config.status ../cc1plus - +# # Compiling object files from source files. # Note that dependencies on obstack.h are not written @@ -248,7 +248,7 @@ error.o : error.c $(CONFIG_H) $(CXX_TREE_H) errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H) sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H) - +# # These exist for maintenance purposes. # Update the tags table. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 0e36807..39bd13e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5452,15 +5452,23 @@ compare_ics (ics1, ics2) they were REF_BINDs. */ if (ICS_THIS_FLAG (ics1)) { - ics1 = build_conv (REF_BIND, TREE_TYPE (ics1), main1); - TREE_OPERAND (ics1, 0) = TREE_OPERAND (main1, 0); - main1 = ics1; + tree t = main1; + if (TREE_CODE (t) == PTR_CONV) + t = TREE_OPERAND (t, 0); + t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE); + t = build_conv (REF_BIND, TREE_TYPE (ics1), t); + ICS_STD_RANK (t) = ICS_STD_RANK (main1); + main1 = ics1 = t; } if (ICS_THIS_FLAG (ics2)) { - ics2 = build_conv (REF_BIND, TREE_TYPE (ics2), main2); - TREE_OPERAND (ics2, 0) = TREE_OPERAND (main2, 0); - main2 = ics2; + tree t = main2; + if (TREE_CODE (t) == PTR_CONV) + t = TREE_OPERAND (t, 0); + t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE); + t = build_conv (REF_BIND, TREE_TYPE (ics2), t); + ICS_STD_RANK (t) = ICS_STD_RANK (main2); + main2 = ics2 = t; } if (ICS_RANK (ics1) > ICS_RANK (ics2)) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 37cdb6b..0dee0fd 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -196,21 +196,28 @@ build_vbase_path (code, type, expr, path, alias_this) register int changed = 0; tree last = NULL_TREE, last_virtual = NULL_TREE; int nonnull = 0; - int fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); + int fixed_type_p; tree null_expr = 0, nonnull_expr; tree basetype; tree offset = integer_zero_node; + if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE) + return build1 (NOP_EXPR, type, expr); + if (nonnull == 0 && (alias_this && flag_this_is_variable <= 0)) nonnull = 1; +#if 0 /* We need additional logic to convert back to the unconverted type (the static type of the complete object), and then convert back to the type we want. Until that is done, or until we can recognize when that is, we cannot do the short cut logic. (mrs) */ + fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); +#else /* Do this, until we can undo any previous conversions. See net35.C for a testcase. */ fixed_type_p = complete_type_p (expr); +#endif if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 677c0fa..70fc150 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1078,12 +1078,14 @@ struct lang_decl #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) #define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE)) #define TI_ARGS(NODE) (TREE_VALUE (NODE)) +#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE)) #define TI_USES_TEMPLATE_PARMS(NODE) TREE_LANG_FLAG_0 (NODE) #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) #define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) #define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE)) +#define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE)) #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) #define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) @@ -1515,6 +1517,7 @@ extern tree opaque_type_node, signature_type_node; /* Array type `(void *)[]' */ extern tree vtbl_type_node; extern tree delta_type_node; +extern tree std_node; extern tree long_long_integer_type_node, long_long_unsigned_type_node; /* For building calls to `delete'. */ @@ -2295,7 +2298,7 @@ struct tinst_level *tinst_for_decl PROTO((void)); extern void mark_decl_instantiated PROTO((tree, int)); extern int more_specialized PROTO((tree, tree)); extern void mark_class_instantiated PROTO((tree, int)); -extern void do_function_instantiation PROTO((tree, tree, tree)); +extern void do_decl_instantiation PROTO((tree, tree, tree)); extern void do_type_instantiation PROTO((tree, tree)); extern tree instantiate_decl PROTO((tree)); extern tree lookup_nested_type_by_name PROTO((tree, tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 26e388d..8dbbf4a 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -407,12 +407,23 @@ build_up_reference (type, arg, flags, checkconst) address, transform all occurrences of the register, into a memory reference we could win better. */ rval = build_unary_op (ADDR_EXPR, arg, 1); - if (flags & LOOKUP_PROTECT) - rval = convert_pointer_to (target_type, rval); + if ((flags & LOOKUP_PROTECT) + && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) + && IS_AGGR_TYPE (argtype) + && IS_AGGR_TYPE (target_type)) + { + /* We go through get_binfo for the access control. */ + tree binfo = get_binfo (target_type, argtype, 1); + if (binfo == error_mark_node) + return error_mark_node; + if (binfo == NULL_TREE) + return error_not_base_type (target_type, argtype); + rval = convert_pointer_to_real (binfo, rval); + } else rval = convert_to_pointer_force (build_pointer_type (target_type), rval); - rval = build1 (CONVERT_EXPR, type, rval); + rval = build1 (NOP_EXPR, type, rval); TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); return rval; } @@ -1189,49 +1200,9 @@ convert (type, expr) if (type == error_mark_node || expr == error_mark_node) return error_mark_node; - if (TREE_TYPE (expr) == type) - return expr; - - if (TREE_CODE (type) != REFERENCE_TYPE) - { - expr = decay_conversion (expr); - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ - if (TREE_CODE (expr) == NOP_EXPR - && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 0); - } - intype = TREE_TYPE (expr); - if (TREE_CODE (type) == REFERENCE_TYPE) - { - expr = build_unary_op (ADDR_EXPR, expr, 0); - if (expr != error_mark_node) - expr = convert (build_pointer_type (TREE_TYPE (type)), expr); - if (expr != error_mark_node) - expr = build_indirect_ref (expr, 0); - return expr; - } - else if (comptypes (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type), 1)) - return build_static_cast (type, expr); - - if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE - || TREE_CODE (intype) == ENUMERAL_TYPE)) - /* OK */; - else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype)) - { - } - else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype)) - || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) - { - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return fold (build1 (NOP_EXPR, type, expr)); - } - else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) - || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype))) + if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype)) { if (TREE_READONLY_DECL_P (expr)) expr = decl_constant_value (expr); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e4ddd1d..5a5978c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -263,6 +263,9 @@ tree sigtable_entry_type; /* Array type `vtable_entry_type[]' */ tree vtbl_type_node; +/* namespace std */ +tree std_node; + /* In a destructor, the point at which all derived class destroying has been done, just before any base class destroying will be done. */ @@ -1675,6 +1678,13 @@ void push_namespace (name) tree name; { +#if 1 + static int warned; + if (! warned) + sorry ("namespace"); + + warned = 1; +#else extern tree current_namespace; tree old_id = get_namespace_id (); char *buf; @@ -1711,6 +1721,7 @@ push_namespace (name) sprintf (buf, "%s%s", old_id ? IDENTIFIER_POINTER (old_id) : "", IDENTIFIER_POINTER (name)); TREE_PURPOSE (current_namespace) = get_identifier (buf); +#endif } /* Pop from the scope of the current namespace. */ @@ -1718,6 +1729,7 @@ push_namespace (name) void pop_namespace () { +#if 0 extern tree current_namespace; tree decls, link; current_namespace = TREE_CHAIN (current_namespace); @@ -1761,6 +1773,7 @@ pop_namespace () /* suspend a level. */ suspend_binding_level (); +#endif } /* Subroutines for reverting temporarily to top-level for instantiation @@ -5289,6 +5302,10 @@ init_decl_processing () record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type); } + std_node = build_decl (NAMESPACE_DECL, get_identifier ("std"), + void_type_node); + pushdecl (std_node); + #if 0 if (flag_rtti) { @@ -12030,8 +12047,25 @@ finish_function (lineno, call_poplevel, nested) /* So we can tell if jump_optimize sets it to 1. */ can_reach_end = 0; - /* Run the optimizers and output the assembler code for this function. */ - rest_of_compilation (fndecl); + /* Run the optimizers and output the assembler code for this + function. */ + + if (DECL_ARTIFICIAL (fndecl)) + { + /* Do we really *want* to inline this synthesized method? */ + + int save_fif = flag_inline_functions; + flag_inline_functions = 1; + + /* Turn off DECL_INLINE for the moment so function_cannot_inline_p + will check our size. */ + DECL_INLINE (fndecl) = 0; + + rest_of_compilation (fndecl); + flag_inline_functions = save_fif; + } + else + rest_of_compilation (fndecl); if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl)) { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index f7e2064..229a656 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2616,7 +2616,10 @@ import_export_decl (decl) supported. */ if (flag_weak) make_decl_one_only (decl); - /* else leave vars public so multiple defs will break. */ + else + /* we can't do anything useful; leave vars for explicit + instantiation. */ + DECL_NOT_REALLY_EXTERN (decl) = 0; } } else @@ -3602,6 +3605,12 @@ void do_toplevel_using_decl (decl) tree decl; { +#if 1 + if (TREE_CODE (decl) == SCOPE_REF + && TREE_OPERAND (decl, 0) == std_node) + return; + sorry ("using-declaration"); +#else if (decl == NULL_TREE || decl == error_mark_node) return; @@ -3619,6 +3628,7 @@ do_toplevel_using_decl (decl) pushdecl (TREE_VALUE (decl)); decl = TREE_CHAIN (decl); } +#endif } tree @@ -3648,6 +3658,8 @@ void do_using_directive (namespace) tree namespace; { + if (namespace == std_node) + return; sorry ("using directive"); } diff --git a/gcc/cp/except.c b/gcc/cp/except.c index eb2a255..55ffa34 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -240,9 +240,11 @@ init_exception_processing () tree declspecs; tree d; + /* void vtype () */ + tree vtype = build_function_type (void_type_node, void_list_node); + /* void (*)() */ - tree PFV = build_pointer_type (build_function_type - (void_type_node, void_list_node)); + tree PFV = build_pointer_type (vtype); /* Arg list for the build_function_type call for set_terminate and set_unexpected. */ @@ -251,9 +253,6 @@ init_exception_processing () /* void (*pfvtype (void (*) ()))() */ tree pfvtype = build_function_type (PFV, pfvlist); - /* void vtype () */ - tree vtype = build_function_type (void_type_node, void_list_node); - set_terminate_fndecl = auto_function (get_identifier ("set_terminate"), pfvtype, NOT_BUILT_IN); set_unexpected_fndecl = auto_function (get_identifier ("set_unexpected"), @@ -290,7 +289,7 @@ init_exception_processing () NOT_BUILT_IN, NULL_PTR); empty_fndecl = builtin_function ("__empty", - build_function_type (void_type_node, void_list_node), + vtype, NOT_BUILT_IN, NULL_PTR); DECL_EXTERNAL (empty_fndecl) = 1; TREE_PUBLIC (empty_fndecl) = 1; @@ -611,18 +610,18 @@ do_unwind (inner_throw_label) /* This doesn't work for the flat model sparc, I bet. */ tree fcall; tree params; - rtx return_val_rtx; + rtx next_pc; rtx temp; /* Call to __builtin_return_address. */ params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE); fcall = build_function_call (BuiltinReturnAddress, params); - return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0); + next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0); /* In the return, the new pc is pc+8, as the value coming in is really the address of the call insn, not the next insn. */ temp = gen_reg_rtx (Pmode); emit_move_insn (temp, inner_throw_label); - emit_move_insn (return_val_rtx, plus_constant (temp, -8)); + emit_move_insn (next_pc, plus_constant (temp, -8)); emit_insn (gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, 31))); easy_expand_asm ("ret"); easy_expand_asm ("restore"); @@ -663,16 +662,16 @@ do_unwind (inner_throw_label) #if ! defined (TARGET_88000) && ! defined (ARM_FRAME_RTX) && ! defined (SPARC_STACK_ALIGN) tree fcall; tree params; - rtx return_val_rtx; + rtx next_pc; #if 0 /* I would like to do this here, but the move below doesn't seem to work. */ /* Call to __builtin_return_address. */ params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE); fcall = build_function_call (BuiltinReturnAddress, params); - return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0); + next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0); - emit_move_insn (return_val_rtx, inner_throw_label); + emit_move_insn (next_pc, inner_throw_label); /* So, for now, just pass throw label to stack unwinder. */ #endif params = tree_cons (NULL_TREE, make_tree (ptr_type_node, @@ -705,12 +704,15 @@ expand_builtin_throw () { tree fcall; tree params; - rtx return_val_rtx; + rtx handler; + rtx saved_pcnthrow; + rtx next_pc; rtx gotta_rethrow_it; rtx gotta_call_terminate; + rtx after_unwind; rtx top_of_loop; - rtx unwind_first; tree t; + rtx x; if (! doing_eh (0)) return; @@ -721,8 +723,11 @@ expand_builtin_throw () params = void_list_node; t = make_call_declarator (get_identifier ("__throw"), params, NULL_TREE, NULL_TREE); - start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"), - void_list_node), + start_function (decl_tree_cons (NULL_TREE, + get_identifier ("void"), + decl_tree_cons (NULL_TREE, + get_identifier ("static"), + NULL_TREE)), t, NULL_TREE, 0); store_parm_decls (); pushlevel (0); @@ -732,8 +737,6 @@ expand_builtin_throw () gotta_rethrow_it = gen_label_rtx (); gotta_call_terminate = gen_label_rtx (); - top_of_loop = gen_label_rtx (); - unwind_first = gen_label_rtx (); /* These two can be frontend specific. If wanted, they can go in expand_throw. */ @@ -742,54 +745,108 @@ expand_builtin_throw () GET_MODE (DECL_RTL (saved_throw_type)), 0, 0); emit_jump_insn (gen_beq (gotta_call_terminate)); - emit_jump (unwind_first); - - emit_label (top_of_loop); - /* search for an exception handler for the saved_pc */ - return_val_rtx = do_function_call (FirstExceptionMatch, - tree_cons (NULL_TREE, saved_pc, NULL_TREE), - ptr_type_node); + handler = do_function_call (FirstExceptionMatch, + tree_cons (NULL_TREE, saved_pc, + NULL_TREE), + ptr_type_node); assemble_external (TREE_OPERAND (FirstExceptionMatch, 0)); /* did we find one? */ - emit_cmp_insn (return_val_rtx, const0_rtx, EQ, NULL_RTX, - GET_MODE (return_val_rtx), 0, 0); + emit_cmp_insn (handler, const0_rtx, EQ, NULL_RTX, + GET_MODE (handler), 0, 0); /* if not, jump to gotta_rethrow_it */ emit_jump_insn (gen_beq (gotta_rethrow_it)); - /* we found it, so jump to it */ - emit_indirect_jump (return_val_rtx); + { + rtx ret_val, x; + ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, + 0, hard_frame_pointer_rtx); + + /* Set it up so that we continue at the handler. */ + emit_move_insn (ret_val, handler); +#ifdef RETURN_ADDR_OFFSET + x = plus_constant (ret_val, -RETURN_ADDR_OFFSET); + if (x != ret_val) + emit_move_insn (ret_val, x); +#endif - /* code to deal with unwinding and looking for it again */ - emit_label (gotta_rethrow_it); + expand_null_return (); + } + top_of_loop = gen_label_rtx (); + emit_label (top_of_loop); + +#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE + if (DONT_ACCESS_GBLS_AFTER_EPILOGUE) + { + saved_pcnthrow = gen_reg_rtx (Pmode); + emit_move_insn (saved_pcnthrow, hard_function_value (ptr_type_node, + NULL_TREE)); + } +#endif + /* Call to __builtin_return_address. */ #if defined (ARM_FRAME_RTX) /* was __arm */ /* This should be moved into arm.h:RETURN_ADDR_RTX */ /* This replaces a 'call' to __builtin_return_address */ - return_val_rtx = gen_reg_rtx (Pmode); - emit_move_insn (return_val_rtx, gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4))); + next_pc = gen_reg_rtx (Pmode); + emit_move_insn (next_pc, + gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4))); #else params = tree_cons (NULL_TREE, integer_zero_node, NULL_TREE); fcall = build_function_call (BuiltinReturnAddress, params); - return_val_rtx = expand_expr (fcall, NULL_RTX, Pmode, 0); + next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0); #endif /* Did __builtin_return_address return a valid address? */ - emit_cmp_insn (return_val_rtx, const0_rtx, EQ, NULL_RTX, - GET_MODE (return_val_rtx), 0, 0); + emit_cmp_insn (next_pc, const0_rtx, EQ, NULL_RTX, + GET_MODE (next_pc), 0, 0); emit_jump_insn (gen_beq (gotta_call_terminate)); - return_val_rtx = eh_outer_context (return_val_rtx); + next_pc = eh_outer_context (next_pc); /* Yes it did. */ - emit_move_insn (eh_saved_pc_rtx, return_val_rtx); +#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE + if (DONT_ACCESS_GBLS_AFTER_EPILOGUE) + { + rtx x; + + x = validize_mem (gen_rtx (MEM, Pmode, saved_pcnthrow)); + emit_move_insn (validize_mem (gen_rtx (MEM, Pmode, x)), + next_pc); +#ifdef FUNCTION_OUTGOING_VALUE + emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE), + validize_mem (gen_rtx (MEM, Pmode, + plus_constant (saved_pcnthrow, + GET_MODE_SIZE (Pmode))))); + emit_insn (gen_rtx (USE, VOIDmode, + FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE))); +#endif + } + else +#endif + emit_move_insn (eh_saved_pc_rtx, next_pc); - do_unwind (gen_rtx (LABEL_REF, Pmode, top_of_loop)); - emit_jump (top_of_loop); + after_unwind = gen_label_rtx (); + do_unwind (gen_rtx (LABEL_REF, Pmode, after_unwind)); + + emit_label (after_unwind); + +#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE + if (DONT_ACCESS_GBLS_AFTER_EPILOGUE) + { + t = make_tree (build_pointer_type (TREE_TYPE (empty_fndecl)), + hard_function_value (ptr_type_node, + NULL_TREE)); + t = build_function_call (t, NULL_TREE); + expand_expr (t, const0_rtx, VOIDmode, 0); + } + else +#endif + emit_throw (); /* no it didn't --> therefore we need to call terminate */ emit_label (gotta_call_terminate); @@ -797,17 +854,37 @@ expand_builtin_throw () assemble_external (TREE_OPERAND (Terminate, 0)); { - rtx ret_val, return_val_rtx; - emit_label (unwind_first); + rtx ret_val, x; + /* code to deal with unwinding and looking for it again */ + emit_label (gotta_rethrow_it); ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS, 0, hard_frame_pointer_rtx); /* Set it up so that we continue inside, at the top of the loop. */ emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, top_of_loop)); #ifdef RETURN_ADDR_OFFSET - return_val_rtx = plus_constant (ret_val, -RETURN_ADDR_OFFSET); - if (return_val_rtx != ret_val) - emit_move_insn (ret_val, return_val_rtx); + x = plus_constant (ret_val, -RETURN_ADDR_OFFSET); + if (x != ret_val) + emit_move_insn (ret_val, x); +#endif + +#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE + if (DONT_ACCESS_GBLS_AFTER_EPILOGUE) + { + rtx x = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode, + "__eh_pcnthrow"), + NULL_RTX, 1, + Pmode, 0); + /* This is to get a version of throw that will throw properly. */ + emit_move_insn (validize_mem (gen_rtx (MEM, Pmode, + plus_constant (x, GET_MODE_SIZE (Pmode)))), + throw_libfunc); +#ifdef FUNCTION_OUTGOING_VALUE + emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE), + x); + emit_insn (gen_rtx (USE, VOIDmode, FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE))); +#endif + } #endif /* Fall into epilogue to unwind prologue. */ diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 378629c..06203fb 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1675,6 +1675,10 @@ build_member_call (type, name, parmlist) int dont_use_this = 0; tree basetype_path, decl; + if (type == std_node) + return build_x_function_call (do_scoped_id (name, 0), parmlist, + current_class_ref); + if (TREE_CODE (method_name) == BIT_NOT_EXPR) { method_name = TREE_OPERAND (method_name, 0); @@ -1796,6 +1800,9 @@ build_offset_ref (type, name) tree basebinfo = NULL_TREE; int dtor = 0; + if (type == std_node) + return do_scoped_id (name, 0); + if (processing_template_decl) return build_min_nt (SCOPE_REF, type, name); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 39f41cb..acb00b0 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -3005,14 +3005,6 @@ real_yylex () token_buffer[0] = '^'; token_buffer[1] = 0; } - else if (ptr->token == NAMESPACE) - { - static int warned; - if (! warned) - warning ("namespaces are mostly broken in this version of g++"); - - warned = 1; - } value = (int) ptr->token; } diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 09acad4..a8502d4 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -2052,21 +2052,6 @@ synthesize_method (fndecl) finish_function (lineno, 0, nested); - /* Do we really *want* to inline this function? */ - if (DECL_INLINE (fndecl)) - { - /* Turn off DECL_INLINE for the moment so function_cannot_inline_p - will check our size. */ - DECL_INLINE (fndecl) = 0; - - /* We say !at_eof because at the end of the file some of the rtl - for fndecl may have been allocated on the temporary obstack. - (The function_obstack is the temporary one if we're not in a - function). */ - if ((! at_eof) && function_cannot_inline_p (fndecl) == 0) - DECL_INLINE (fndecl) = 1; - } - extract_interface_info (); if (! context) pop_from_top_level (); diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 8a1ae5d..ab11230 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -390,7 +390,11 @@ extdef: | using_decl ';' { do_toplevel_using_decl ($1); } | USING NAMESPACE any_id ';' - { do_using_directive ($3); } + { + if (TREE_CODE ($3) == IDENTIFIER_NODE) + $3 = lastiddecl; + do_using_directive ($3); + } | extension extdef { pedantic = $1; } ; @@ -814,20 +818,20 @@ explicit_instantiation: { do_type_instantiation ($3, NULL_TREE); } | TEMPLATE typed_declspecs declarator { tree specs = strip_attrs ($2.t); - do_function_instantiation (specs, $3, NULL_TREE); } + do_decl_instantiation (specs, $3, NULL_TREE); } | TEMPLATE notype_declarator - { do_function_instantiation (NULL_TREE, $2, NULL_TREE); } + { do_decl_instantiation (NULL_TREE, $2, NULL_TREE); } | TEMPLATE constructor_declarator - { do_function_instantiation (NULL_TREE, $2, NULL_TREE); } + { do_decl_instantiation (NULL_TREE, $2, NULL_TREE); } | SCSPEC TEMPLATE aggr template_type { do_type_instantiation ($4, $1); } | SCSPEC TEMPLATE typed_declspecs declarator { tree specs = strip_attrs ($3.t); - do_function_instantiation (specs, $4, $1); } + do_decl_instantiation (specs, $4, $1); } | SCSPEC TEMPLATE notype_declarator - { do_function_instantiation (NULL_TREE, $3, $1); } + { do_decl_instantiation (NULL_TREE, $3, $1); } | SCSPEC TEMPLATE constructor_declarator - { do_function_instantiation (NULL_TREE, $3, $1); } + { do_decl_instantiation (NULL_TREE, $3, $1); } ; /* The TYPENAME expansions are to deal with use of a template class name as @@ -1831,13 +1835,9 @@ typespec: { $$.t = $1; $$.new_type_flag = 0; } | TYPEOF '(' expr ')' { $$.t = TREE_TYPE ($3); - $$.new_type_flag = 0; - if (pedantic && !in_system_header) - pedwarn ("ANSI C++ forbids `typeof'"); } + $$.new_type_flag = 0; } | TYPEOF '(' type_id ')' { $$.t = groktypename ($3.t); - if (pedantic && !in_system_header) - pedwarn ("ANSI C++ forbids `typeof'"); $$.new_type_flag = 0; } | SIGOF '(' expr ')' { tree type = TREE_TYPE ($3); @@ -3051,7 +3051,15 @@ nested_name_specifier_1: got_scope = $$ = TREE_TYPE ($$); } | NSNAME SCOPE - { got_scope = $$ = $1; } + { + if (TREE_CODE ($$) == IDENTIFIER_NODE) + $$ = lastiddecl; + if (TREE_CODE ($$) == NAMESPACE_DECL + && DECL_NAME ($$) == get_identifier ("std")) + got_scope = void_type_node; + else + got_scope = $$; + } | template_type SCOPE { got_scope = $$ = complete_type (TREE_TYPE ($1)); } /* These break 'const i;' diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e06fa40..7febfc6 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -274,9 +274,9 @@ push_template_decl (decl) return; } - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = perm_tree_cons - (mainargs, TREE_VALUE (current_template_parms), - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type) + = perm_tree_cons (mainargs, TREE_VALUE (current_template_parms), + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; return; } @@ -291,6 +291,8 @@ push_template_decl (decl) } else { + tree t; + if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) cp_error ("must specialize `%#T' before defining member `%#D'", ctx, decl); @@ -303,6 +305,18 @@ push_template_decl (decl) } else tmpl = DECL_TI_TEMPLATE (decl); + + if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) + t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx)); + else + t = DECL_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx)); + + if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (args)) + { + cp_error ("got %d template parameters for `%#D'", + TREE_VEC_LENGTH (args), decl); + cp_error (" but `%#T' has %d", ctx, TREE_VEC_LENGTH (t)); + } } DECL_TEMPLATE_RESULT (tmpl) = decl; @@ -1183,8 +1197,13 @@ instantiate_class_template (type) TREE_VEC_LENGTH (args), NULL_TREE); BINFO_INHERITANCE_CHAIN (elt) = binfo; - if (! uses_template_parms (type) - && TYPE_SIZE (complete_type (TREE_TYPE (elt))) == NULL_TREE) + if (! IS_AGGR_TYPE (TREE_TYPE (elt))) + cp_error + ("base type `%T' of `%T' fails to be a struct or class type", + TREE_TYPE (elt), type); + else if (! uses_template_parms (type) + && (TYPE_SIZE (complete_type (TREE_TYPE (elt))) + == NULL_TREE)) cp_error ("base class `%T' of `%T' has incomplete type", TREE_TYPE (elt), type); } @@ -1752,11 +1771,13 @@ tsubst (t, args, nargs, in_decl) return t; TREE_TYPE (t) = complete_type (type); - BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type); - BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type); - if (TYPE_BINFO_BASETYPES (type) != NULL_TREE) - BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type)); - + if (IS_AGGR_TYPE (type)) + { + BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type); + BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type); + if (TYPE_BINFO_BASETYPES (type) != NULL_TREE) + BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type)); + } return t; } { @@ -3153,7 +3174,7 @@ most_specialized_class (specs, mainargs) /* called from the parser. */ void -do_function_instantiation (declspecs, declarator, storage) +do_decl_instantiation (declspecs, declarator, storage) tree declspecs, declarator, storage; { tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE); @@ -3169,7 +3190,18 @@ do_function_instantiation (declspecs, declarator, storage) } /* If we've already seen this template instance, use it. */ - if (DECL_FUNCTION_MEMBER_P (decl)) + if (TREE_CODE (decl) == VAR_DECL) + { + result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0); + if (result && TREE_CODE (result) != VAR_DECL) + result = NULL_TREE; + } + else if (TREE_CODE (decl) != FUNCTION_DECL) + { + cp_error ("explicit instantiation of `%#D'", decl); + return; + } + else if (DECL_FUNCTION_MEMBER_P (decl)) { if (DECL_TEMPLATE_INSTANTIATION (decl)) result = decl; @@ -3220,6 +3252,12 @@ do_function_instantiation (declspecs, declarator, storage) return; } + if (! DECL_TEMPLATE_INFO (result)) + { + cp_pedwarn ("explicit instantiation of non-template `%#D'", result); + return; + } + if (flag_external_templates) return; diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 47a111b..d9b4486 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -41,6 +41,8 @@ static tree original_repo; static char *repo_name; static FILE *repo_file; +static char *old_args, *old_dir, *old_main; + extern int flag_use_repository; extern int errorcount, sorrycount; extern struct obstack temporary_obstack; @@ -198,35 +200,55 @@ save_string (s, len) return obstack_copy0 (&temporary_obstack, s, len); } +/* Parse a reasonable subset of shell quoting syntax. */ + +static char * +extract_string (pp) + char **pp; +{ + char *p = *pp; + int backquote = 0; + int inside = 0; + + for (;;) + { + char c = *p; + if (c == '\0') + break; + ++p; + if (backquote) + obstack_1grow (&temporary_obstack, c); + else if (! inside && c == ' ') + break; + else if (! inside && c == '\\') + backquote = 1; + else if (c == '\'') + inside = !inside; + else + obstack_1grow (&temporary_obstack, c); + } + + obstack_1grow (&temporary_obstack, '\0'); + *pp = p; + return obstack_finish (&temporary_obstack); +} + static char * get_base_filename (filename) char *filename; { char *p = getenv ("COLLECT_GCC_OPTIONS"); - char *output = 0; + char *output = NULL; int compiling = 0; - if (p) - while (*p) - { - char *q = p; - while (*q && *q != ' ') q++; - if (*p == '-' && p[1] == 'o') - { - p += 2; - if (p == q) - { - p++; q++; - if (*q) - while (*q && *q != ' ') q++; - } + while (p && *p) + { + char *q = extract_string (&p); - output = save_string (p, q - p); - } - else if (*p == '-' && p[1] == 'c') - compiling = 1; - if (*q) q++; - p = q; + if (strcmp (q, "-o") == 0) + output = extract_string (&p); + else if (strcmp (q, "-c") == 0) + compiling = 1; } if (compiling && output) @@ -301,8 +323,16 @@ init_repo (filename) switch (buf[0]) { case 'A': + old_args = obstack_copy0 (&permanent_obstack, buf + 2, + strlen (buf + 2)); + break; case 'D': + old_dir = obstack_copy0 (&permanent_obstack, buf + 2, + strlen (buf + 2)); + break; case 'M': + old_main = obstack_copy0 (&permanent_obstack, buf + 2, + strlen (buf + 2)); break; case 'C': case 'O': @@ -350,6 +380,7 @@ finish_repo () tree t; char *p; int repo_changed = 0; + char *dir, *args; if (! flag_use_repository) return; @@ -382,6 +413,16 @@ finish_repo () } } + dir = getpwd (); + args = getenv ("COLLECT_GCC_OPTIONS"); + + if (! repo_changed && pending_repo) + if (strcmp (old_main, main_input_filename) != 0 + || strcmp (old_dir, dir) != 0 + || (args == NULL) != (old_args == NULL) + || strcmp (old_args, args) != 0) + repo_changed = 1; + if (! repo_changed || errorcount || sorrycount) goto out; @@ -391,13 +432,9 @@ finish_repo () goto out; fprintf (repo_file, "M %s\n", main_input_filename); - - p = getpwd (); - fprintf (repo_file, "D %s\n", p); - - p = getenv ("COLLECT_GCC_OPTIONS"); - if (p != 0) - fprintf (repo_file, "A %s\n", p); + fprintf (repo_file, "D %s\n", dir); + if (args) + fprintf (repo_file, "A %s\n", args); for (t = pending_repo; t; t = TREE_CHAIN (t)) { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 13ec6dd..c73e86f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -5082,9 +5082,11 @@ build_conditional_expr (ifexp, op1, op2) result_type = build_ptrmemfunc_type (result_type); if (result_type != TREE_TYPE (op1)) - op1 = convert_and_check (result_type, op1); + op1 = convert_for_initialization + (NULL_TREE, result_type, op1, LOOKUP_NORMAL, "converting", NULL_TREE, 0); if (result_type != TREE_TYPE (op2)) - op2 = convert_and_check (result_type, op2); + op2 = convert_for_initialization + (NULL_TREE, result_type, op2, LOOKUP_NORMAL, "converting", NULL_TREE, 0); if (TREE_CONSTANT (ifexp)) return integer_zerop (ifexp) ? op2 : op1; @@ -7221,7 +7223,8 @@ c_expand_return (retval) if (TREE_CODE (whats_returned) == ADDR_EXPR) whats_returned = TREE_OPERAND (whats_returned, 0); } - if (TREE_CODE (whats_returned) == CONVERT_EXPR) + while (TREE_CODE (whats_returned) == CONVERT_EXPR + || TREE_CODE (whats_returned) == NOP_EXPR) whats_returned = TREE_OPERAND (whats_returned, 0); if (TREE_CODE (whats_returned) == ADDR_EXPR) { diff --git a/gcc/cp/xref.c b/gcc/cp/xref.c index a09ab7f..260ddd2 100644 --- a/gcc/cp/xref.c +++ b/gcc/cp/xref.c @@ -645,7 +645,7 @@ GNU_xref_member(cls, fld) filename(xf), fld->decl.linenum, d, bufa, prot, (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1), (DECL_INLINE (fld) ? 1 : 0), - (DECL_FRIEND_P(fld) ? 1 : 0), + (DECL_LANG_SPECIFIC(fld) && DECL_FRIEND_P(fld) ? 1 : 0), (DECL_VINDEX(fld) ? 1 : 0), (TREE_STATIC(fld) ? 1 : 0), pure, confg); -- cgit v1.1