diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a092c8db65b61353e2d5c26e13eb93e4563cf9a8..df22c23039381493e67c2e50594147af25d61fc7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -10,6 +10,59 @@ Wed Jan 25 15:02:09 1995 David S. Miller (davem@nadzieja.rutgers.edu) * class.c (instantiate_type): Change error message text. * typeck2.c (store_init_value): Likewise. +Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * decl2.c (reparse_decl_as_expr): Support being called without a + type argument. + + * parse.y (primary): Add '(' expr_or_declarator ')'. Adds 4 r/r + conflicts. Sigh. + +Fri Feb 17 12:02:06 1995 Mike Stump <mrs@cygnus.com> + + * parse.y (template_def, fndef, fn.def1, return_init, condition, + initdcl0, initdcl, notype_initdcl0, nomods_initdcl0, + component_decl_1, after_type_component_declarator0, + notype_component_declarator0, after_type_component_declarator, + notype_component_declarator, after_type_component_declarator, + full_parm, maybe_raises, exception_specification_opt): Fix up, + include exception_specification_opt maybeasm maybe_attribute and + maybe_init if missing. Rename maybe_raises to + exception_specification_opt to match draft wording. Use maybe_init + to simplify rules. + +Fri Feb 17 01:54:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs + built for news of scalar types. + +Thu Feb 16 17:48:28 1995 Jason Merrill <jason@phydeaux.cygnus.com> + + * typeck.c (build_binary_op_nodefault): Update code for warning + about signed/unsigned comparisons from C frontend. Realize that the + code in the C frontend is, if anything, even more bogus. Fix it. + (build_binary_op): Undo default_conversion if it wasn't useful. + + * typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for + PRE*CREMENT_EXPR. + + * decl2.c (import_export_vtable): Don't try the vtable hack + if the class doesn't have any real non-inline virtual functions. + (finish_vtable_vardecl): Don't bother trying to find a non-inline + virtual function in a non-polymorphic class. + (finish_prevtable_vardecl): Ditto. + + * decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN. + + * cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5. + + * init.c (expand_virtual_init): Always call assemble_external. + + * class.c (build_vfn_ref): Always call assemble_external. + (build_vtable): Always call import_export_vtable. + (prepare_fresh_vtable): Ditto. + (add_virtual_function): Don't bother setting TREE_ADDRESSABLE. + Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com> * class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in index ab3f58b9e12bfffe46cf52d66033cbeedca94c9c..2e5f0136c68cf6442089c31ed52805939880f166 100644 --- a/gcc/cp/Makefile.in +++ b/gcc/cp/Makefile.in @@ -196,12 +196,12 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h $(PARSE_H) : $(PARSE_C) $(PARSE_C) : $(srcdir)/parse.y - @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts. + @echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts. cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o parse.c parse.y cd $(srcdir); grep '^#define[ ]*YYEMPTY' parse.c >>parse.h #$(PARSE_C) $(PARSE_H) : stamp-parse ; @true #stamp-parse: $(srcdir)/parse.y -# @echo expect 1 shift/reduce confict and 34 reduce/reduce conflicts. +# @echo expect 1 shift/reduce confict and 39 reduce/reduce conflicts. # $(BISON) $(BISONFLAGS) -d $(srcdir)/parse.y # grep '^#define[ ]*YYEMPTY' y.tab.c >>y.tab.h # $(srcdir)/../move-if-change y.tab.c $(PARSE_C) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b5edebd54591de9abcfe6246a04f0aead1739231..b0332e9af76716852734eac0ce64a456329964aa 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -478,8 +478,7 @@ build_vfn_ref (ptr_to_instptr, instance, idx) vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), NULL_PTR); } - if (!flag_vtable_thunks) - assemble_external (vtbl); + assemble_external (vtbl); aref = build_array_ref (vtbl, idx); /* Save the intermediate result in a SAVE_EXPR so we don't have to @@ -552,8 +551,7 @@ build_vtable (binfo, type) #endif /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - if (! flag_vtable_thunks) - import_export_vtable (decl, type); + import_export_vtable (decl, type, 0); IDENTIFIER_GLOBAL_VALUE (name) = decl = pushdecl_top_level (decl); /* Initialize the association list for this type, based @@ -699,8 +697,7 @@ prepare_fresh_vtable (binfo, for_type) #endif /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - if (! flag_vtable_thunks) - import_export_vtable (new_decl, for_type); + import_export_vtable (new_decl, for_type, 0); if (TREE_VIA_VIRTUAL (binfo)) my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo), @@ -803,9 +800,6 @@ add_virtual_function (pending_virtuals, has_virtual, fndecl, t) fndecl); #endif - if (!flag_vtable_thunks) - TREE_ADDRESSABLE (fndecl) = CLASSTYPE_VTABLE_NEEDS_WRITING (t); - /* If the virtual function is a redefinition of a prior one, figure out in which base class the new definition goes, and if necessary, make a fresh virtual function table diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4cb8af9e90ef8d0098004782549c513772bd3787..27b616aee0a1e0d7cfc8e1ffcc2b871a9333b1b2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -954,10 +954,9 @@ struct lang_decl_flags unsigned saved_inline : 1; unsigned use_template : 2; - unsigned interface_known : 1; unsigned declared_static : 1; unsigned nonconverting : 1; - unsigned dummy : 5; + unsigned dummy : 6; tree access; tree context; @@ -1131,7 +1130,7 @@ struct lang_decl #if 0 /* Same, but tells if this field is private in current context. */ -#define DECL_PRIVATE(NODE) (DECL_LANG_FLAG_5 (NODE)) +#define DECL_PRIVATE(NODE) (FOO) /* Same, but tells if this field is private in current context. */ #define DECL_PROTECTED(NODE) (DECL_LANG_FLAG_6 (NODE)) @@ -1337,8 +1336,7 @@ struct lang_decl (CLASSTYPE_USE_TEMPLATE(NODE) = 3) /* We know what we're doing with this decl now. */ -#define DECL_INTERFACE_KNOWN(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.interface_known) +#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE) /* This decl was declared to have internal linkage. */ #define DECL_DECLARED_STATIC(NODE) \ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 32090e974a6a6ec9cfbcb134c1dd4192ee0ff958..b38f1db079ca66d87dbb3a27accbd629c735ea3d 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -144,10 +144,8 @@ int warn_implicit = 1; int warn_ctor_dtor_privacy = 1; /* True if we want to implement vtbvales using "thunks". - The default is off now, but will be on later. + The default is off now, but will be on later. */ - Also causes output of vtables to be controlled by whether - we seen the class's first non-inline virtual function. */ int flag_vtable_thunks; /* Nonzero means give string constants the type `const char *' @@ -2466,23 +2464,61 @@ mark_vtable_entries (decl) it's public in this file or in another one. */ void -import_export_vtable (decl, type) - tree decl, type; +import_export_vtable (decl, type, final) + tree decl, type; + int final; { - if (write_virtuals >= 2 - || CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - { - if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); - } - } - else if (write_virtuals != 0) + if (DECL_INTERFACE_KNOWN (decl)) + return; + + /* +e0 or +e1 */ + if (write_virtuals < 2 && write_virtuals != 0) { TREE_PUBLIC (decl) = 1; if (write_virtuals < 0) DECL_EXTERNAL (decl) = 1; + DECL_INTERFACE_KNOWN (decl) = 1; + } + else if (CLASSTYPE_INTERFACE_KNOWN (type)) + { + TREE_PUBLIC (decl) = 1; + DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); + DECL_INTERFACE_KNOWN (decl) = 1; + } + else + { + /* We can only do this optimization if we have real non-inline + virtual functions in our class, or if we come from a template. */ + + int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); + + if (! found && ! final) + { + /* This check only works before the method definitions are seen, + since DECL_INLINE may get bashed. */ + tree method; + for (method = CLASSTYPE_METHODS (type); method != NULL_TREE; + method = DECL_NEXT_METHOD (method)) + if (DECL_VINDEX (method) != NULL_TREE && ! DECL_INLINE (method) + && ! DECL_ABSTRACT_VIRTUAL_P (method)) + { + found = 1; + break; + } + } + + if (final || ! found) + { + TREE_PUBLIC (decl) = 0; + DECL_EXTERNAL (decl) = 0; + DECL_INTERFACE_KNOWN (decl) = 1; + } + else + { + TREE_PUBLIC (decl) = 1; + DECL_EXTERNAL (decl) = 1; + DECL_INTERFACE_KNOWN (decl) = 0; + } } } @@ -2506,9 +2542,8 @@ finish_prevtable_vardecl (prev, vars) { tree ctype = DECL_CONTEXT (vars); import_export_template (ctype); - import_export_vtable (vars, ctype); - if (CLASSTYPE_INTERFACE_UNKNOWN (ctype)) + if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)) { tree method; for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; @@ -2520,13 +2555,13 @@ finish_prevtable_vardecl (prev, vars) SET_CLASSTYPE_INTERFACE_KNOWN (ctype); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method); CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method); - TREE_PUBLIC (vars) = 1; - DECL_EXTERNAL (vars) = DECL_EXTERNAL (method); break; } } } + import_export_vtable (vars, ctype, 1); + if (write_virtuals >= 0 && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) { @@ -2549,9 +2584,8 @@ finish_vtable_vardecl (prev, vars) { tree ctype = DECL_CONTEXT (vars); import_export_template (ctype); - import_export_vtable (vars, ctype); - if (CLASSTYPE_INTERFACE_UNKNOWN (ctype)) + if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)) { tree method; for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE; @@ -2563,8 +2597,6 @@ finish_vtable_vardecl (prev, vars) SET_CLASSTYPE_INTERFACE_KNOWN (ctype); CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method); CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method); - TREE_PUBLIC (vars) = 1; - DECL_EXTERNAL (vars) = DECL_EXTERNAL (method); if (flag_rtti) cp_warning ("compiler error: rtti entry for `%T' decided too late", ctype); break; @@ -2572,6 +2604,8 @@ finish_vtable_vardecl (prev, vars) } } + import_export_vtable (vars, ctype, 1); + if (write_virtuals >= 0 && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars))) { @@ -2612,7 +2646,7 @@ finish_vtable_vardecl (prev, vars) rest_of_decl_compilation (vars, NULL_PTR, 1, 1); } - else if (TREE_USED (vars) && flag_vtable_thunks) + else if (TREE_USED (vars)) assemble_external (vars); /* We know that PREV must be non-zero here. */ TREE_CHAIN (prev) = TREE_CHAIN (vars); @@ -3230,8 +3264,11 @@ tree reparse_decl_as_expr (type, decl) tree type, decl; { - decl = build_tree_list (NULL_TREE, reparse_decl_as_expr1 (decl)); - return build_functional_cast (type, decl); + decl = reparse_decl_as_expr1 (decl); + if (type) + return build_functional_cast (type, build_tree_list (NULL_TREE, decl)); + else + return decl; } /* This is something of the form `int (*a)' that has turned out to be a diff --git a/gcc/cp/init.c b/gcc/cp/init.c index cf8b0e7772a19825cf20c0754d3fe8a62174b45d..63a909cb457835a87e59fd8d58fae9ed8aa3fb85 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -730,8 +730,7 @@ expand_virtual_init (binfo, decl) vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0); vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); - if (!flag_vtable_thunks) - assemble_external (vtbl); + assemble_external (vtbl); TREE_USED (vtbl) = 1; vtbl = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (vtbl)), vtbl); decl = convert_pointer_to_real (vtype_binfo, decl); @@ -3093,6 +3092,7 @@ build_new (placement, decl, init, use_global_new) rval = build (COMPOUND_EXPR, TREE_TYPE (rval), build_modify_expr (deref, NOP_EXPR, init), rval); + TREE_NO_UNUSED_WARNING (rval) = 1; TREE_SIDE_EFFECTS (rval) = 1; TREE_CALLS_NEW (rval) = 1; } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 102ca63e131b81ab070c04d7aca361aa021577b1..b85ffc9d49926cf38c0c9a5f5fb96c8195ebe715 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -205,7 +205,7 @@ empty_parms () %type <ttype> declmods typespec typespecqual_reserved %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual %type <itype> initdecls notype_initdecls initdcl /* C++ modification */ -%type <ttype> init initlist maybeasm +%type <ttype> init initlist maybeasm maybe_init %type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers %type <ttype> maybe_attribute attributes attribute attribute_list attrib %type <ttype> any_word @@ -244,7 +244,7 @@ empty_parms () %type <ttype> class_head base_class_list %type <itype> base_class_access_list %type <ttype> base_class maybe_base_class_list base_class.1 -%type <ttype> maybe_raises ansi_raise_identifier ansi_raise_identifiers +%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers %type <ttype> component_declarator0 %type <ttype> forhead.1 operator_name %type <ttype> object aggr @@ -495,7 +495,7 @@ template_def: /* declare $2 as template name with $1 parm list */ } | template_header /* notype_initdcl0 ';' */ - notype_declarator maybe_raises maybeasm maybe_attribute + notype_declarator exception_specification_opt maybeasm maybe_attribute fn_tmpl_end { tree d; @@ -512,7 +512,7 @@ template_def: resume_momentary (momentary); } | template_header typed_declspecs /*initdcl0*/ - declarator maybe_raises maybeasm maybe_attribute + declarator exception_specification_opt maybeasm maybe_attribute fn_tmpl_end { tree d; @@ -649,17 +649,17 @@ fndef: ; fn.def1: - typed_declspecs declarator maybe_raises + typed_declspecs declarator exception_specification_opt { if (! start_function ($$, $2, $3, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } - | declmods notype_declarator maybe_raises + | declmods notype_declarator exception_specification_opt { if (! start_function ($$, $2, $3, 0)) YYERROR1; reinit_parse_for_function (); $$ = NULL_TREE; } - | notype_declarator maybe_raises + | notype_declarator exception_specification_opt { if (! start_function (NULL_TREE, $$, $2, 0)) YYERROR1; reinit_parse_for_function (); @@ -672,7 +672,7 @@ fn.def1: /* more C++ complexity. See component_decl for a comment on the reduce/reduce conflict introduced by these rules. */ fn.def2: - typed_declspecs '(' parmlist ')' type_quals maybe_raises + typed_declspecs '(' parmlist ')' type_quals exception_specification_opt { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5); $$ = start_method (TREE_CHAIN ($1), $$, $6); @@ -682,18 +682,18 @@ fn.def2: if (yychar == YYEMPTY) yychar = YYLEX; reinit_parse_for_method (yychar, $$); } - | typed_declspecs LEFT_RIGHT type_quals maybe_raises + | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3); $$ = start_method (TREE_CHAIN ($1), $$, $4); goto rest_of_mdef; } - | typed_declspecs declarator maybe_raises + | typed_declspecs declarator exception_specification_opt { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } - | declmods notype_declarator maybe_raises + | declmods notype_declarator exception_specification_opt { $$ = start_method ($$, $2, $3); goto rest_of_mdef; } - | notype_declarator maybe_raises + | notype_declarator exception_specification_opt { $$ = start_method (NULL_TREE, $$, $2); goto rest_of_mdef; } ; @@ -705,10 +705,8 @@ return_id: RETURN IDENTIFIER } ; -return_init: return_id - { store_return_init ($<ttype>$, NULL_TREE); } - | return_id '=' init - { store_return_init ($<ttype>$, $3); } +return_init: return_id maybe_init + { store_return_init ($<ttype>$, $2); } | return_id '(' nonnull_exprlist ')' { store_return_init ($<ttype>$, $3); } | return_id LEFT_RIGHT @@ -962,7 +960,7 @@ xcond: ; condition: - type_specifier_seq declarator maybe_raises maybeasm maybe_attribute '=' + type_specifier_seq declarator exception_specification_opt maybeasm maybe_attribute '=' { { tree d; for (d = getdecls (); d; d = TREE_CHAIN (d)) @@ -1334,12 +1332,21 @@ primary: | string { $$ = combine_strings ($$); } | '(' expr ')' - { char class = TREE_CODE_CLASS (TREE_CODE ($2)); + { char class; + $$ = $2; + class = TREE_CODE_CLASS (TREE_CODE ($$)); + if (class == 'e' || class == '1' + || class == '2' || class == '<') + /* This inhibits warnings in truthvalue_conversion. */ + C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } + | '(' expr_or_declarator ')' + { char class; + $$ = reparse_decl_as_expr (NULL_TREE, $2); + class = TREE_CODE_CLASS (TREE_CODE ($$)); if (class == 'e' || class == '1' || class == '2' || class == '<') /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); - $$ = $2; } + C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } | '(' error ')' { $$ = error_mark_node; } | '(' @@ -1948,7 +1955,7 @@ maybeasm: ; initdcl0: - declarator maybe_raises maybeasm maybe_attribute '=' + declarator exception_specification_opt maybeasm maybe_attribute '=' { current_declspecs = $<ttype>0; if (TREE_CODE (current_declspecs) != TREE_LIST) current_declspecs = get_decl_list (current_declspecs); @@ -1966,7 +1973,7 @@ initdcl0: /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $<itype>5; } - | declarator maybe_raises maybeasm maybe_attribute + | declarator exception_specification_opt maybeasm maybe_attribute { tree d; current_declspecs = $<ttype>0; if (TREE_CODE (current_declspecs) != TREE_LIST) @@ -1985,20 +1992,20 @@ initdcl0: ; initdcl: - declarator maybe_raises maybeasm maybe_attribute '=' + declarator exception_specification_opt maybeasm maybe_attribute '=' { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); cplus_decl_attributes ($<ttype>$, $4); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); } - | declarator maybe_raises maybeasm maybe_attribute + | declarator exception_specification_opt maybeasm maybe_attribute { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, $2); cplus_decl_attributes ($<ttype>$, $4); finish_decl ($<ttype>$, NULL_TREE, $3, 0, 0); } ; notype_initdcl0: - notype_declarator maybe_raises maybeasm maybe_attribute '=' + notype_declarator exception_specification_opt maybeasm maybe_attribute '=' { current_declspecs = $<ttype>0; $<itype>5 = suspend_momentary (); $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, $2); @@ -2007,7 +2014,7 @@ notype_initdcl0: /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $<itype>5; } - | notype_declarator maybe_raises maybeasm maybe_attribute + | notype_declarator exception_specification_opt maybeasm maybe_attribute { tree d; current_declspecs = $<ttype>0; $$ = suspend_momentary (); @@ -2017,7 +2024,7 @@ notype_initdcl0: ; nomods_initdcl0: - notype_declarator maybe_raises maybeasm maybe_attribute '=' + notype_declarator exception_specification_opt maybeasm maybe_attribute '=' { current_declspecs = NULL_TREE; $<itype>5 = suspend_momentary (); $<ttype>$ = start_decl ($1, current_declspecs, 1, $2); @@ -2026,7 +2033,7 @@ nomods_initdcl0: /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_decl ($<ttype>6, $7, $3, 0, LOOKUP_ONLYCONVERTING); $$ = $<itype>5; } - | notype_declarator maybe_raises maybeasm maybe_attribute + | notype_declarator exception_specification_opt maybeasm maybe_attribute { tree d; current_declspecs = NULL_TREE; $$ = suspend_momentary (); @@ -2094,6 +2101,12 @@ identifiers_or_typenames: { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } ; +maybe_init: + %prec EMPTY /* empty */ + { $$ = NULL_TREE; } + | '=' init + { $$ = $2; } + init: expr_no_commas %prec '=' | '{' '}' @@ -2593,8 +2606,8 @@ component_decl_1: { $$ = grok_x_components ($$, $2); } - | notype_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, NULL_TREE, $2, NULL_TREE, $3); + | notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, NULL_TREE, $2, $5, $3); cplus_decl_attributes ($$, $4); } | ':' expr_no_commas { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } @@ -2609,16 +2622,16 @@ component_decl_1: should "A::foo" be declared as a function or "A::bar" as a data member? In other words, is "bar" an after_type_declarator or a parmlist? */ - | typed_declspecs '(' parmlist ')' type_quals + | typed_declspecs '(' parmlist ')' type_quals exception_specification_opt maybeasm maybe_attribute maybe_init { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), $3, $5); - $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, - NULL_TREE); } - | typed_declspecs LEFT_RIGHT type_quals + $$ = grokfield ($$, TREE_CHAIN ($1), $6, $9, $7); + cplus_decl_attributes ($$, $8); } + | typed_declspecs LEFT_RIGHT type_quals exception_specification_opt maybeasm maybe_attribute maybe_init { $$ = build_parse_node (CALL_EXPR, TREE_VALUE ($1), empty_parms (), $3); - $$ = grokfield ($$, TREE_CHAIN ($1), NULL_TREE, NULL_TREE, - NULL_TREE); } + $$ = grokfield ($$, TREE_CHAIN ($1), $4, $7, $5); + cplus_decl_attributes ($$, $6); } | using_decl ; @@ -2664,13 +2677,9 @@ component_declarator: ; after_type_component_declarator0: - after_type_declarator maybe_raises maybeasm maybe_attribute - { current_declspecs = $<ttype>0; - $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init + after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init { current_declspecs = $<ttype>0; - $$ = grokfield ($$, current_declspecs, $2, $6, $3); + $$ = grokfield ($$, current_declspecs, $2, $5, $3); cplus_decl_attributes ($$, $4); } | TYPENAME ':' expr_no_commas maybe_attribute { current_declspecs = $<ttype>0; @@ -2679,13 +2688,9 @@ after_type_component_declarator0: ; notype_component_declarator0: - notype_declarator maybe_raises maybeasm maybe_attribute - { current_declspecs = $<ttype>0; - $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | notype_declarator maybe_raises maybeasm maybe_attribute '=' init + notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init { current_declspecs = $<ttype>0; - $$ = grokfield ($$, current_declspecs, $2, $6, $3); + $$ = grokfield ($$, current_declspecs, $2, $5, $3); cplus_decl_attributes ($$, $4); } | IDENTIFIER ':' expr_no_commas maybe_attribute { current_declspecs = $<ttype>0; @@ -2698,11 +2703,8 @@ notype_component_declarator0: ; after_type_component_declarator: - after_type_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | after_type_declarator maybe_raises maybeasm maybe_attribute '=' init - { $$ = grokfield ($$, current_declspecs, $2, $6, $3); + after_type_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, current_declspecs, $2, $5, $3); cplus_decl_attributes ($$, $4); } | TYPENAME ':' expr_no_commas maybe_attribute { $$ = grokbitfield ($$, current_declspecs, $3); @@ -2710,11 +2712,8 @@ after_type_component_declarator: ; notype_component_declarator: - notype_declarator maybe_raises maybeasm maybe_attribute - { $$ = grokfield ($$, current_declspecs, $2, NULL_TREE, $3); - cplus_decl_attributes ($$, $4); } - | notype_declarator maybe_raises maybeasm maybe_attribute '=' init - { $$ = grokfield ($$, current_declspecs, $2, $6, $3); + notype_declarator exception_specification_opt maybeasm maybe_attribute maybe_init + { $$ = grokfield ($$, current_declspecs, $2, $5, $3); cplus_decl_attributes ($$, $4); } | IDENTIFIER ':' expr_no_commas maybe_attribute { $$ = grokbitfield ($$, current_declspecs, $3); @@ -3702,10 +3701,8 @@ named_parm: ; full_parm: - parm - { $$ = build_tree_list (NULL_TREE, $$); } - | parm '=' init - { $$ = build_tree_list ($3, $$); } + parm maybe_init + { $$ = build_tree_list ($2, $$); } ; parm: @@ -3748,7 +3745,7 @@ bad_parm: } ; -maybe_raises: +exception_specification_opt: %prec EMPTY /* empty */ { $$ = NULL_TREE; } | THROW '(' ansi_raise_identifiers ')' %prec EMPTY diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d36fa8d1ac856d7d8f928044a9d344a7d99f5aca..b21bbe94567fbced996377bdec94850397d22047 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2723,8 +2723,9 @@ build_binary_op (code, arg1, arg2, convert_p) if (convert_p) { - args[0] = default_conversion (args[0]); - args[1] = default_conversion (args[1]); + tree args_save [2]; + args[0] = args_save [0] = default_conversion (args[0]); + args[1] = args_save [1] = default_conversion (args[1]); if (type_unknown_p (args[0])) { @@ -2780,6 +2781,11 @@ build_binary_op (code, arg1, arg2, convert_p) error ("ambiguous pointer conversion"); args[convert_index] = try; } + + if (args[0] == args_save[0]) + args[0] = arg1; + if (args[1] == args_save[1]) + args[1] = arg2; } return build_binary_op_nodefault (code, args[0], args[1], code); } @@ -3457,19 +3463,34 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) if (short_compare && extra_warnings) { + int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0)); + int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1)); + + tree comp_type = TREE_TYPE (op0); + int unsignedp0, unsignedp1; tree primop0 = get_narrower (op0, &unsignedp0); tree primop1 = get_narrower (op1, &unsignedp1); - /* Warn if signed and unsigned are being compared in a size larger - than their original size, as this will always fail. */ - - if (unsignedp0 != unsignedp1 - && (TYPE_PRECISION (TREE_TYPE (primop0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (primop1)) - < TYPE_PRECISION (result_type))) - warning ("comparison between promoted unsigned and signed"); + /* Give warnings for comparisons between signed and unsigned + quantities that may fail. Do not warn if the signed quantity + is an unsuffixed integer literal (or some static constant + expression involving such literals) and it is positive. + Do not warn if the comparison is being done in a signed type, + since the signed type will only be chosen if it can represent + all the values of the unsigned type. */ + /* Do the checking based on the original operand trees, so that + casts will be considered, but default promotions won't be. */ + if (TREE_UNSIGNED (comp_type) + && ((op0_signed + && (TREE_CODE (op0) != INTEGER_CST + || (TREE_CODE (op0) == INTEGER_CST + && INT_CST_LT (op0, integer_zero_node)))) + || (op1_signed + && (TREE_CODE (op1) != INTEGER_CST + || (TREE_CODE (op1) == INTEGER_CST + && INT_CST_LT (op1, integer_zero_node)))))) + warning ("comparison between signed and unsigned"); /* Warn if two unsigned values are being compared in a size larger than their original size, and one (and only one) is the @@ -3509,7 +3530,7 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) } bits = TYPE_PRECISION (TREE_TYPE (primop)); - if (bits < TYPE_PRECISION (result_type) + if (bits < TYPE_PRECISION (comp_type) && bits < HOST_BITS_PER_LONG && unsignedp) { mask = (~ (HOST_WIDE_INT) 0) << bits; @@ -3519,9 +3540,9 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) } else if (unsignedp0 && unsignedp1 && (TYPE_PRECISION (TREE_TYPE (primop0)) - < TYPE_PRECISION (result_type)) + < TYPE_PRECISION (comp_type)) && (TYPE_PRECISION (TREE_TYPE (primop1)) - < TYPE_PRECISION (result_type))) + < TYPE_PRECISION (comp_type))) warning ("comparison of promoted ~unsigned with unsigned"); } } @@ -4120,15 +4141,6 @@ build_unary_op (code, xarg, noconvert) TREE_OPERAND (arg, 1), 1); } - /* For &(++foo), we are really taking the address of the variable - being acted upon by the increment/decrement operator. ARM $5.3.1 - However, according to ARM $5.2.5, we don't allow postfix ++ and - --, since the prefix operators return lvalues, but the postfix - operators do not. */ - if (TREE_CODE (arg) == PREINCREMENT_EXPR - || TREE_CODE (arg) == PREDECREMENT_EXPR) - arg = TREE_OPERAND (arg, 0); - /* Uninstantiated types are all functions. Taking the address of a function is a no-op, so just return the argument. */