* 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
$(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)
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
#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
#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),
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
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;
#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))
(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) \
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 *'
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;
+ }
}
}
{
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;
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)))
{
{
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;
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;
}
}
+ import_export_vtable (vars, ctype, 1);
+
if (write_virtuals >= 0
&& ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (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);
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
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);
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;
}
%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
%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
/* 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;
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;
;
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 ();
/* 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);
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; }
;
}
;
-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
;
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))
| 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; }
| '('
;
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);
/* 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)
;
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);
/* 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 ();
;
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);
/* 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 ();
{ $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
;
+maybe_init:
+ %prec EMPTY /* empty */
+ { $$ = NULL_TREE; }
+ | '=' init
+ { $$ = $2; }
+
init:
expr_no_commas %prec '='
| '{' '}'
{
$$ = 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); }
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
;
;
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;
;
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;
;
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);
;
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);
;
full_parm:
- parm
- { $$ = build_tree_list (NULL_TREE, $$); }
- | parm '=' init
- { $$ = build_tree_list ($3, $$); }
+ parm maybe_init
+ { $$ = build_tree_list ($2, $$); }
;
parm:
}
;
-maybe_raises:
+exception_specification_opt:
%prec EMPTY /* empty */
{ $$ = NULL_TREE; }
| THROW '(' ansi_raise_identifiers ')' %prec EMPTY
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]))
{
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);
}
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
}
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;
}
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");
}
}
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. */