From a58942422c0b4b60efa76fd7261961c1d4ea612a Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Mon, 1 May 1995 21:36:30 +0000 Subject: [PATCH] 68th Cygnus<->FSF merge From-SVN: r9555 --- gcc/cp/ChangeLog | 94 +++++++++++++++++++++++++++++++++++++++++++++++ gcc/cp/call.c | 84 +++++++++++++++++++++++++++--------------- gcc/cp/decl.c | 73 ++++++++++++++++++++++++++++++++++-- gcc/cp/decl2.c | 2 + gcc/cp/expr.c | 9 +++-- gcc/cp/gxxint.texi | 11 ++++++ gcc/cp/lex.c | 7 ++-- gcc/cp/method.c | 106 ++++++++++++++++++++--------------------------------- gcc/cp/parse.y | 64 +++++++++++++++----------------- gcc/cp/pt.c | 4 +- gcc/cp/typeck.c | 35 ++++++++++++++++-- gcc/cp/typeck2.c | 39 ++++---------------- 12 files changed, 351 insertions(+), 177 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f11cf72..8347b18 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,97 @@ +Fri Apr 28 07:58:41 1995 Jason Merrill + + * lex.c (cons_up_default_function): Fix linkage of #pragma + implemented functions. + +Thu Apr 27 16:56:24 1995 Jason Merrill + + * method.c (build_overload_name): Simplify and fix repeated type + folding. + + * decl.c (grokdeclarator): Prohibit pointers to void or reference + members. + +Thu Apr 27 09:49:07 1995 Mike Stump + + * typeck2.c (process_init_constructor): Make sure initializers are + fully digested. + +Thu Apr 27 01:11:55 1995 Jason Merrill + + * lex.c (cons_up_default_function): Always defer synthesis. + +Thu Apr 27 00:20:37 1995 Jason Merrill + + * decl2.c (mark_inline_for_output): Don't play with pending_inline + stuff. + +Wed Apr 26 17:48:24 1995 Jason Merrill + + * call.c (user_harshness): New function; like build_type_conversion, + but doesn't actually build anything. + (compute_conversion_costs): Use it instead of build_type_conversion. + +Wed Apr 26 17:11:25 1995 Jason Merrill + + * typeck.c (build_function_call_real): Improve error message for + calling a non-function. + + * method.c (hack_identifier): Lose check for calling a data member. + +Wed Apr 26 16:59:13 1995 Mike Stump + + * typeck2.c (build_functional_cast): Remove very old cruft. + Seems like good code is generated without it. + +Wed Apr 26 00:47:16 1995 Jason Merrill + + * method.c (do_build_assign_ref): Fix handling of anonymous unions. + (do_build_copy_constructor): Ditto. + + * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch. + + * decl.c (push_switch): New function. + (pop_switch): Ditto. + (define_case_label): Check for jumping over initialization. + + * call.c (build_method_call): Check for an inline function being + called before its definition has been seen. + * typeck.c (build_function_call_real): Ditto. + + * decl.c (duplicate_decls): Check for a function being redeclared + inline after its address has been taken. + + * typeck.c (build_conditional_expr): Handle related class lvalues. + +Tue Apr 25 13:20:45 1995 Jason Merrill + + * pt.c (do_pending_expansions): Don't expand unused templates. + + * parse.y (component_decl): Accept a lone semicolon. + +Tue Apr 25 00:25:56 1995 Jason Merrill + + * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the + object parameter anymore. + + * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns. + +Mon Apr 24 12:35:48 1995 Jason Merrill + + * parse.y (simple_stmt, decl case): Clear prefix_attributes. + (lang_extdef): Ditto. + + * parse.y (maybe_parmlist): New rule for use in declarators where + this could either be a list of expressions or parameters. Calls + suspend_momentary before deciding which. + (direct_after_type_declarator): Use it. + (complex_direct_notype_declarator): Use it. + + * pt.c (tsubst): Propagate attributes const and noreturn. + + * typeck.c (build_modify_expr): If warn_synth, call build_opfncall + before doing the default thing. + Thu Apr 27 21:49:36 1995 Doug Evans * typeck.c (common_type): Call lookup_attribute instead of diff --git a/gcc/cp/call.c b/gcc/cp/call.c index fa92ed8..6779c84 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -586,6 +586,47 @@ convert_harshness (type, parmtype, parm) } int +user_harshness (type, parmtype, parm) + register tree type, parmtype; + tree parm; +{ + tree conv; + tree winner = NULL_TREE; + int code; + + { + tree typename = build_typename_overload (type); + if (lookup_fnfields (TYPE_BINFO (parmtype), typename, 0)) + return 0; + } + + for (conv = lookup_conversions (parmtype); conv; conv = TREE_CHAIN (conv)) + { + struct harshness_code tmp; + + if (winner && TREE_PURPOSE (winner) == TREE_PURPOSE (conv)) + continue; + + if (tmp = convert_harshness (type, TREE_VALUE (conv), NULL_TREE), + tmp.code < USER_CODE) + { + if (winner) + return EVIL_CODE; + else + { + winner = conv; + code = tmp.code; + } + } + } + + if (winner) + return code; + + return -1; +} + +int can_convert (to, from) tree to, from; { @@ -884,30 +925,14 @@ compute_conversion_costs (function, tta_in, cp, arglen) if (TYPE_LANG_SPECIFIC (actual_type) && TYPE_HAS_CONVERSION (actual_type)) { - tree conv; - /* Don't issue warnings since we're only groping - around for the right answer, we haven't yet - committed to going with this solution. */ - int old_inhibit_warnings = inhibit_warnings; - - inhibit_warnings = 1; - conv = build_type_conversion - (CALL_EXPR, formal_type, TREE_VALUE (tta), 0); - inhibit_warnings = old_inhibit_warnings; - - if (conv) + int extra = user_harshness (formal_type, actual_type); + + if (extra == EVIL_CODE) + win += 2; + else if (extra >= 0) { - if (conv == error_mark_node - || (TREE_CODE (TREE_VALUE (ttf)) == REFERENCE_TYPE - && ! TYPE_READONLY (TREE_VALUE (TREE_VALUE (ttf))) - && ! lvalue_p (conv))) - win += 2; - else - { - win++; - if (TREE_CODE (conv) != CALL_EXPR) - extra_conversions = 1; - } + win++; + extra_conversions = extra; } } } @@ -1789,11 +1814,7 @@ build_method_call (instance, name, parms, basetype_path, flags) } else { - if (TREE_CODE (instance) != CALL_EXPR -#ifdef PCC_STATIC_STRUCT_RETURN - && TREE_CODE (instance) != RTL_EXPR -#endif - ) + if (TREE_CODE (instance) != CALL_EXPR) my_friendly_abort (125); if (TYPE_NEEDS_CONSTRUCTING (basetype)) instance = build_cplus_new (basetype, instance, 0); @@ -2397,13 +2418,16 @@ build_method_call (instance, name, parms, basetype_path, flags) #if 1 /* Is it a synthesized method that needs to be synthesized? */ if (DECL_ARTIFICIAL (function) && ! flag_no_inline - && DECL_SAVED_INSNS (function) == 0 - && ! TREE_ASM_WRITTEN (function) + && ! DECL_INITIAL (function) /* Kludge: don't synthesize for default args. */ && current_function_decl) synthesize_method (function); #endif + if (pedantic && DECL_THIS_INLINE (function) && ! DECL_ARTIFICIAL (function) + && ! DECL_INITIAL (function) && ! DECL_PENDING_INLINE_INFO (function)) + cp_pedwarn ("inline function `%#D' called before definition", function); + fntype = TREE_TYPE (function); if (TREE_CODE (fntype) == POINTER_TYPE) fntype = TREE_TYPE (fntype); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 74dca4f..dcabbd2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2315,6 +2315,11 @@ duplicate_decls (newdecl, olddecl) olddecl); } } + + if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl) + && TREE_ADDRESSABLE (olddecl)) + cp_pedwarn ("`%#D' was used before it was declared inline", + newdecl); } /* These bits are logically part of the type for non-functions. */ else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) @@ -3660,6 +3665,30 @@ define_label (filename, line, name) } } +struct cp_switch +{ + struct binding_level *level; + struct cp_switch *next; +}; + +static struct cp_switch *switch_stack; + +void +push_switch () +{ + struct cp_switch *p + = (struct cp_switch *) oballoc (sizeof (struct cp_switch)); + p->level = current_binding_level; + p->next = switch_stack; + switch_stack = p; +} + +void +pop_switch () +{ + switch_stack = switch_stack->next; +} + /* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */ /* XXX Note decl is never actually used. (bpk) */ void @@ -3667,19 +3696,46 @@ define_case_label (decl) tree decl; { tree cleanup = last_cleanup_this_contour (); + struct binding_level *b = current_binding_level; + int identified = 0; + if (cleanup) { static int explained = 0; - cp_error_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup)); - error ("where case label appears here"); + cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup)); + warning ("where case label appears here"); if (!explained) { - error ("(enclose actions of previous case statements requiring"); - error ("destructors in their own binding contours.)"); + warning ("(enclose actions of previous case statements requiring"); + warning ("destructors in their own binding contours.)"); explained = 1; } } + for (; b && b != switch_stack->level; b = b->level_chain) + { + tree new_decls = b->names; + for (; new_decls; new_decls = TREE_CHAIN (new_decls)) + { + if (TREE_CODE (new_decls) == VAR_DECL + /* Don't complain about crossing initialization + of internal entities. They can't be accessed, + and they should be cleaned up + by the time we get to the label. */ + && ! DECL_ARTIFICIAL (new_decls) + && ((DECL_INITIAL (new_decls) != NULL_TREE + && DECL_INITIAL (new_decls) != error_mark_node) + || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) + { + if (! identified) + error ("jump to case label"); + identified = 1; + cp_error_at (" crosses initialization of `%#D'", + new_decls); + } + } + } + /* After labels, make any new cleanups go into their own new (temporary) binding contour. */ @@ -8428,6 +8484,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, raises) continue; } + if (TREE_CODE (type) == OFFSET_TYPE + && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE + || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE)) + { + cp_error ("cannot declare pointer to `%#T' member", + TREE_TYPE (type)); + type = TREE_TYPE (type); + } + /* Merge any constancy or volatility into the target type for the pointer. */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 5952d85..6e4ad20 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2078,6 +2078,7 @@ mark_inline_for_output (decl) return; my_friendly_assert (TREE_PERMANENT (decl), 363); DECL_SAVED_INLINE (decl) = 1; +#if 0 if (DECL_PENDING_INLINE_INFO (decl) != 0 && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu) { @@ -2097,6 +2098,7 @@ mark_inline_for_output (decl) } DECL_PENDING_INLINE_INFO (decl) = 0; } +#endif saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines); } diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index c6630cb..c722dcb 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -151,8 +151,9 @@ cplus_expand_expr (exp, target, tmode, modifier) extern int flag_access_control; int old_ac = flag_access_control; - tree init = build (RTL_EXPR, type, 0, return_target); + tree init = build_decl (VAR_DECL, 0, type); TREE_ADDRESSABLE (init) = 1; + DECL_RTL (init) = return_target; flag_access_control = 0; expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); @@ -160,8 +161,10 @@ cplus_expand_expr (exp, target, tmode, modifier) if (TYPE_NEEDS_DESTRUCTOR (type)) { - init = build (RTL_EXPR, build_reference_type (type), 0, - XEXP (return_target, 0)); + init = build_decl (VAR_DECL, 0, + build_reference_type (type)); + DECL_RTL (init) = XEXP (return_target, 0); + init = maybe_build_cleanup (convert_from_reference (init)); if (init != NULL_TREE) expand_expr (init, 0, 0, 0); diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi index cb3beab..68623b2 100644 --- a/gcc/cp/gxxint.texi +++ b/gcc/cp/gxxint.texi @@ -1321,6 +1321,17 @@ main() @} @end example +@section Linkage +The linkage code in g++ is horribly twisted in order to meet two design goals: + +1) Avoid unnecessary emission of inlines and vtables. + +2) Support pedantic assemblers like the one in AIX. + +To meet the first goal, we defer emission of inlines and vtables until +the end of the translation unit, where we can decide whether or not they +are needed, and how to emit them if they are. + @node Concept Index, , Free Store, Top @section Concept Index diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 7c6b791..0585787 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -1797,13 +1797,13 @@ cons_up_default_function (type, full_name, kind) if (CLASSTYPE_INTERFACE_KNOWN (type)) { DECL_INTERFACE_KNOWN (fn) = 1; - DECL_EXTERNAL (fn) = (CLASSTYPE_INTERFACE_ONLY (type) - || ! flag_implement_inlines); - TREE_STATIC (fn) = ! DECL_EXTERNAL (fn); + DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type) + && flag_implement_inlines); } else DECL_NOT_REALLY_EXTERN (fn) = 1; +#if 0 /* When on-the-fly synthesis works properly, remove the second and third conditions here. */ if (flag_keep_inline_functions @@ -1822,6 +1822,7 @@ cons_up_default_function (type, full_name, kind) store_pending_inline (fn, t); } else +#endif mark_inline_for_output (fn); #ifdef DEBUG_DEFAULT_FUNCTIONS diff --git a/gcc/cp/method.c b/gcc/cp/method.c index ddf65b1..1e26e20 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -562,44 +562,30 @@ build_overload_name (parmtypes, begin, end) only_one: - if (! nofold) + if (! nofold && ! just_one) { - if (! just_one) - /* Every argument gets counted. */ - typevec[maxtype++] = parmtype; + /* Every argument gets counted. */ + typevec[maxtype++] = parmtype; - if (TREE_USED (parmtype)) + if (TREE_USED (parmtype) && parmtype == typevec[maxtype-2]) { - if (! just_one && parmtype == typevec[maxtype-2]) - nrepeats++; - else - { - if (nrepeats) - flush_repeats (parmtype); - if (! just_one && TREE_CHAIN (parmtypes) - && parmtype == TREE_VALUE (TREE_CHAIN (parmtypes))) - nrepeats++; - else - { - int tindex = 0; - - while (typevec[tindex] != parmtype) - tindex++; - OB_PUTC ('T'); - icat (tindex); - if (tindex > 9) - OB_PUTC ('_'); - } - } + nrepeats++; goto next; } + if (nrepeats) flush_repeats (typevec[maxtype-2]); - if (! just_one - /* Only cache types which take more than one character. */ - && (parmtype != TYPE_MAIN_VARIANT (parmtype) - || (TREE_CODE (parmtype) != INTEGER_TYPE - && TREE_CODE (parmtype) != REAL_TYPE))) + + if (TREE_USED (parmtype)) + { + flush_repeats (parmtype); + goto next; + } + + /* Only cache types which take more than one character. */ + if (parmtype != TYPE_MAIN_VARIANT (parmtype) + || (TREE_CODE (parmtype) != INTEGER_TYPE + && TREE_CODE (parmtype) != REAL_TYPE)) TREE_USED (parmtype) = 1; } @@ -1496,23 +1482,7 @@ hack_identifier (value, name, yychar) return error_mark_node; } TREE_USED (current_class_decl) = 1; - if (yychar == '(') - if (! ((TYPE_LANG_SPECIFIC (type) - && TYPE_OVERLOADS_CALL_EXPR (type)) - || (TREE_CODE (type) == REFERENCE_TYPE - && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) - && TYPE_OVERLOADS_CALL_EXPR (TREE_TYPE (type)))) - && TREE_CODE (type) != FUNCTION_TYPE - && TREE_CODE (type) != METHOD_TYPE - && !TYPE_PTRMEMFUNC_P (type) - && (TREE_CODE (type) != POINTER_TYPE - || (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE - && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE))) - { - error ("component `%s' is not a method", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } + /* Mark so that if we are in a constructor, and then find that this field was initialized by a base initializer, we can emit an error message. */ @@ -2094,32 +2064,34 @@ do_build_copy_constructor (fndecl) for (; fields; fields = TREE_CHAIN (fields)) { tree name, init, t; - if (TREE_CODE (fields) != FIELD_DECL) + tree field = fields; + + if (TREE_CODE (field) != FIELD_DECL) continue; - if (DECL_NAME (fields)) + if (DECL_NAME (field)) { - if (VFIELD_NAME_P (DECL_NAME (fields))) + if (VFIELD_NAME_P (DECL_NAME (field))) continue; - if (VBASE_NAME_P (DECL_NAME (fields))) + if (VBASE_NAME_P (DECL_NAME (field))) continue; /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } - else if ((t = TREE_TYPE (fields)) != NULL_TREE + else if ((t = TREE_TYPE (field)) != NULL_TREE && TREE_CODE (t) == UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) && TYPE_FIELDS (t) != NULL_TREE) - fields = largest_union_member (t); + field = largest_union_member (t); else continue; - init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); + init = build (COMPONENT_REF, TREE_TYPE (field), parm, field); init = build_tree_list (NULL_TREE, init); current_member_init_list - = tree_cons (DECL_NAME (fields), init, current_member_init_list); + = tree_cons (DECL_NAME (field), init, current_member_init_list); } current_member_init_list = nreverse (current_member_init_list); current_base_init_list = nreverse (current_base_init_list); @@ -2171,29 +2143,31 @@ do_build_assign_ref (fndecl) for (; fields; fields = TREE_CHAIN (fields)) { tree comp, init, t; - if (TREE_CODE (fields) != FIELD_DECL) + tree field = fields; + + if (TREE_CODE (field) != FIELD_DECL) continue; - if (DECL_NAME (fields)) + if (DECL_NAME (field)) { - if (VFIELD_NAME_P (DECL_NAME (fields))) + if (VFIELD_NAME_P (DECL_NAME (field))) continue; - if (VBASE_NAME_P (DECL_NAME (fields))) + if (VBASE_NAME_P (DECL_NAME (field))) continue; /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (fields)) != fields) + if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) continue; } - else if ((t = TREE_TYPE (fields)) != NULL_TREE + else if ((t = TREE_TYPE (field)) != NULL_TREE && TREE_CODE (t) == UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)) && TYPE_FIELDS (t) != NULL_TREE) - fields = largest_union_member (t); + field = largest_union_member (t); else continue; - comp = build (COMPONENT_REF, TREE_TYPE (fields), C_C_D, fields); - init = build (COMPONENT_REF, TREE_TYPE (fields), parm, fields); + comp = build (COMPONENT_REF, TREE_TYPE (field), C_C_D, field); + init = build (COMPONENT_REF, TREE_TYPE (field), parm, field); expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 46eb2b4..d700592 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -25,20 +25,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ all derivations; this is applied before the explicit action, if one is given. Keep this in mind when reading the actions. */ -/* Also note: this version contains experimental exception - handling features. They could break, change, disappear, - or otherwise exhibit volatile behavior. Don't depend on - me (Michael Tiemann) to protect you from any negative impact - this may have on your professional, personal, or spiritual life. - - NEWS FLASH: This version now supports the exception handling - syntax of Stroustrup's 2nd edition, if -fansi-exceptions is given. - THIS IS WORK IN PROGRESS!!! The type of the 'throw' and the - 'catch' much match EXACTLY (no inheritance support or coercions). - Also, throw-specifications of functions don't work. - Destructors aren't called correctly. Etc, etc. --Per Bothner. - */ - %{ /* Cause the `yydebug' variable to be defined. */ #define YYDEBUG 1 @@ -251,7 +237,7 @@ empty_parms () %type object aggr %type new delete /* %type primary_no_id */ -%type nonmomentary_expr +%type nonmomentary_expr maybe_parmlist %type forhead.2 initdcl0 notype_initdcl0 member_init_list %type template_header template_parm_list template_parm %type template_type_parm @@ -346,7 +332,8 @@ lang_extdef: { if (pending_lang_change) do_pending_lang_change(); } extdef { if (! global_bindings_p () && ! pseudo_global_level_p()) - pop_everything (); } + pop_everything (); + prefix_attributes = NULL_TREE; } ; extdef: @@ -2600,7 +2587,6 @@ component_decl_list: $$ = $2; } } - | component_decl_list ';' ; component_decl: @@ -2614,6 +2600,8 @@ component_decl: { $$ = finish_method ($$); } | fn.def2 '{' /* nodecls compstmt */ { $$ = finish_method ($$); } + | ';' + { $$ = NULL_TREE; } ; component_decl_1: @@ -2796,12 +2784,27 @@ nonempty_type_quals: /* These rules must follow the rules for function declarations and component declarations. That way, longer rules are preferred. */ +suspend_mom: + { $$ = suspend_momentary (); } + /* An expression which will not live on the momentary obstack. */ nonmomentary_expr: - { $$ = suspend_momentary (); } expr + suspend_mom expr { resume_momentary ((int) $1); $$ = $2; } ; +/* An expression which will not live on the momentary obstack. */ +maybe_parmlist: + suspend_mom '(' nonnull_exprlist ')' + { resume_momentary ((int) $1); $$ = $3; } + | suspend_mom '(' parmlist ')' + { resume_momentary ((int) $1); $$ = $3; } + | suspend_mom LEFT_RIGHT + { resume_momentary ((int) $1); $$ = empty_parms (); } + | suspend_mom '(' error ')' + { resume_momentary ((int) $1); $$ = NULL_TREE; } + ; + /* A declarator that is allowed only after an explicit typespec. */ /* may all be followed by prec '.' */ after_type_declarator: @@ -2843,14 +2846,8 @@ nested_type: ; direct_after_type_declarator: - direct_after_type_declarator '(' nonnull_exprlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_after_type_declarator '(' parmlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_after_type_declarator LEFT_RIGHT type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } - | direct_after_type_declarator '(' error ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } + direct_after_type_declarator maybe_parmlist type_quals %prec '.' + { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); } | direct_after_type_declarator '[' nonmomentary_expr ']' { $$ = build_parse_node (ARRAY_REF, $$, $3); } | direct_after_type_declarator '[' ']' @@ -2900,14 +2897,8 @@ complex_notype_declarator: ; complex_direct_notype_declarator: - direct_notype_declarator '(' nonnull_exprlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_notype_declarator '(' parmlist ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, $3, $5); } - | direct_notype_declarator LEFT_RIGHT type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, empty_parms (), $3); } - | direct_notype_declarator '(' error ')' type_quals %prec '.' - { $$ = build_parse_node (CALL_EXPR, $$, NULL_TREE, NULL_TREE); } + direct_notype_declarator maybe_parmlist type_quals %prec '.' + { $$ = build_parse_node (CALL_EXPR, $$, $2, $3); } | '(' complex_notype_declarator ')' { $$ = $2; } | direct_notype_declarator '[' nonmomentary_expr ']' @@ -3192,7 +3183,8 @@ stmt: simple_stmt: decl - { finish_stmt (); } + { finish_stmt (); + prefix_attributes = NULL_TREE; } | expr ';' { tree expr = $1; @@ -3294,12 +3286,14 @@ simple_stmt: | SWITCH .pushlevel '(' condition ')' { emit_line_note (input_filename, lineno); c_expand_start_case ($4); + push_switch (); /* Don't let the tree nodes for $4 be discarded by clear_momentary during the parsing of the next stmt. */ push_momentary (); } implicitly_scoped_stmt { expand_end_case ($4); pop_momentary (); + pop_switch (); expand_end_bindings (getdecls (), kept_level_p (), 1); poplevel (kept_level_p (), 1, 0); pop_momentary (); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9d6266f..8c995a8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1452,6 +1452,8 @@ tsubst (t, args, nargs, in_decl) DECL_INTERFACE_KNOWN (r) = 0; DECL_INLINE (r) = DECL_INLINE (t); DECL_THIS_INLINE (r) = DECL_THIS_INLINE (t); + TREE_READONLY (r) = TREE_READONLY (t); + TREE_THIS_VOLATILE (r) = TREE_THIS_VOLATILE (t); { #if 0 /* Maybe later. -jason */ struct tinst_level *til = tinst_for_decl(); @@ -2412,7 +2414,7 @@ do_pending_expansions () If `interface', ext ref. */ if (CLASSTYPE_INTERFACE_KNOWN (context)) DECIDE (!CLASSTYPE_INTERFACE_ONLY (context)); -#if 0 /* This doesn't get us stuff needed only by the file initializer. */ +#if 1 /* This doesn't get us stuff needed only by the file initializer. */ DECIDE (TREE_USED (t)); #else /* This compiles too much stuff, but that's probably better in most cases than never compiling the stuff we need. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index afdd357..8580c9b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -51,6 +51,7 @@ static tree convert_sequence (); static tree get_delta_difference PROTO((tree, tree, int)); extern rtx original_result_rtx; +extern int warn_synth; /* Return the target type of TYPE, which meas return T for: T*, T&, T[], T (...), and otherwise, just T. */ @@ -2359,6 +2360,12 @@ build_function_call_real (function, params, require_complete, flags) pedwarn ("ANSI C++ forbids calling `main' from within program"); } + if (pedantic && DECL_THIS_INLINE (function) && ! DECL_INITIAL (function) + && ! DECL_ARTIFICIAL (function) + && ! DECL_PENDING_INLINE_INFO (function)) + cp_pedwarn ("inline function `%#D' called before definition", + function); + /* Differs from default_conversion by not setting TREE_ADDRESSABLE (because calling an inline function does not mean the function needs to be separately compiled). */ @@ -2403,7 +2410,7 @@ build_function_call_real (function, params, require_complete, flags) && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE) || is_method)) { - error ("called object is not a function"); + cp_error ("`%E' cannot be used as a function", function); return error_mark_node; } @@ -4617,9 +4624,21 @@ build_conditional_expr (ifexp, op1, op2) code2 = TREE_CODE (type2); } + if (code1 == RECORD_TYPE && code2 == RECORD_TYPE + && real_lvalue_p (op1) && real_lvalue_p (op2) + && comptypes (type1, type2, -1)) + { + type1 = build_reference_type (type1); + type2 = build_reference_type (type2); + result_type = common_type (type1, type2); + op1 = convert_to_reference (result_type, op1, CONV_IMPLICIT, + LOOKUP_NORMAL, NULL_TREE); + op2 = convert_to_reference (result_type, op2, CONV_IMPLICIT, + LOOKUP_NORMAL, NULL_TREE); + } /* Quickly detect the usual case where op1 and op2 have the same type after promotion. */ - if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) + else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) { if (type1 == type2) result_type = type1; @@ -4814,7 +4833,8 @@ build_conditional_expr (ifexp, op1, op2) if (TREE_CONSTANT (ifexp)) return integer_zerop (ifexp) ? op2 : op1; - return fold (build (COND_EXPR, result_type, ifexp, op1, op2)); + return convert_from_reference + (fold (build (COND_EXPR, result_type, ifexp, op1, op2))); } /* Handle overloading of the ',' operator when needed. Otherwise, @@ -5630,7 +5650,14 @@ build_modify_expr (lhs, modifycode, rhs) cp_error ("`%T' does not define operator=", lhstype); else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (lhstype) && TYPE_MAIN_VARIANT (lhstype) == TYPE_MAIN_VARIANT (TREE_TYPE (newrhs))) - /* Do the default thing */; + { + if (warn_synth) + /* If we care about this, do overload resolution. */ + build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, + lhs, rhs, make_node (NOP_EXPR)); + + /* Do the default thing */; + } else { result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 1c719aa..e69ada4 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -975,6 +975,13 @@ process_init_constructor (type, init, elts) tree tail1 = tail; next1 = digest_init (TYPE_MAIN_VARIANT (TREE_TYPE (type)), TREE_VALUE (tail), &tail1); + if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)) + && TYPE_MAIN_VARIANT (TREE_TYPE (type)) != TYPE_MAIN_VARIANT (TREE_TYPE (next1))) + { + /* The fact this needs to be done suggests this code needs + to be totally rewritten. */ + next1 = convert_for_initialization (NULL_TREE, TREE_TYPE (type), next1, LOOKUP_NORMAL, "initialization", NULL_TREE, 0); + } my_friendly_assert (tail1 == 0 || TREE_CODE (tail1) == TREE_LIST, 319); if (tail == tail1 && len < 0) @@ -1529,37 +1536,7 @@ build_functional_cast (exp, parms) if (expr_as_ctor == error_mark_node) return error_mark_node; - if (current_function_decl) - return build_cplus_new (type, expr_as_ctor, 1); - - { - register tree parm = TREE_OPERAND (expr_as_ctor, 1); - - /* Initializers for static variables and parameters have - to handle doing the initialization and cleanup themselves. */ - my_friendly_assert (TREE_CODE (expr_as_ctor) == CALL_EXPR, 322); -#if 0 - /* The following assertion fails in cases where we are initializing - a static member variable of a particular instance of a template - class with a call to a constructor of the given instance, as in: - - TMPL object = TMPL(); - - Curiously, the assertion does not fail if we do the same thing - for a static member of a non-template class, as in: - - T object = T(); - - I can't see why we should care here whether or not the initializer - expression involves a call to `new', so for the time being, it - seems best to just avoid doing this assertion. */ - my_friendly_assert (TREE_CALLS_NEW (TREE_VALUE (parm)), 323); -#endif - TREE_VALUE (parm) = NULL_TREE; - expr_as_ctor = build_indirect_ref (expr_as_ctor, NULL_PTR); - TREE_HAS_CONSTRUCTOR (expr_as_ctor) = 1; - } - return expr_as_ctor; + return build_cplus_new (type, expr_as_ctor, 1); } /* Return the character string for the name that encodes the -- 2.7.4