90th Cygnus<->FSF quick merge

From-SVN: r13082
This commit is contained in:
Mike Stump 1996-10-31 17:08:58 +00:00
parent cced4d25ea
commit 691c003dcc
5 changed files with 101 additions and 137 deletions

View File

@ -1,3 +1,31 @@
Mon Oct 28 12:45:05 1996 Jeffrey A Law (law@cygnus.com)
* typeck.c (signed_or_unsigned_type): If the given type already
as the correct signedness, then just return it.
* typeck.c ({un,}signed_type): If can't do anything, call
signed_or_unsigned_type.
Thu Oct 24 14:21:59 1996 Bob Manson <manson@charmed.cygnus.com>
* decl2.c (copy_assignment_arg_p): Don't buy the farm if
current_class_type is NULL.
Wed Oct 23 00:43:10 1996 Jason Merrill <jason@gerbil.cygnus.com>
* class.c (finish_struct_1): Avoid empty structs by adding a field
so layout_type gets the mode right.
* typeck.c (c_expand_return): Drastically simplify.
Mon Oct 21 22:34:02 1996 Jason Merrill <jason@yorick.cygnus.com>
* typeck.c (decay_conversion): Handle overloaded methods.
Fri Oct 18 16:03:48 1996 Jason Merrill <jason@yorick.cygnus.com>
* call.c (build_over_call): A TARGET_EXPR has side-effects.
Thu Oct 17 11:31:59 1996 Mike Stump <mrs@cygnus.com>
* cvt.c (convert_to_pointer_force): Add code to support pointer to

View File

@ -5099,7 +5099,9 @@ build_over_call (fn, convs, args, flags)
{
val = build (VAR_DECL, DECL_CONTEXT (fn));
layout_decl (val, 0);
return build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0);
val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0);
TREE_SIDE_EFFECTS (val) = 1;
return val;
}
}
else if (! real_lvalue_p (arg)

View File

@ -3051,6 +3051,7 @@ finish_struct_1 (t, warn_anon)
tree t_binfo = TYPE_BINFO (t);
tree access_decls = NULL_TREE;
int aggregate = 1;
int empty = 1;
if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
pedwarn ("anonymous class type not used to declare any objects");
@ -3215,7 +3216,10 @@ finish_struct_1 (t, warn_anon)
GNU_xref_member (current_class_name, x);
if (TREE_CODE (x) == FIELD_DECL)
DECL_PACKED (x) |= TYPE_PACKED (t);
{
DECL_PACKED (x) |= TYPE_PACKED (t);
empty = 0;
}
/* Handle access declarations. */
if (TREE_CODE (x) == USING_DECL)
@ -3767,6 +3771,7 @@ finish_struct_1 (t, warn_anon)
else
fields = vfield;
#endif
empty = 0;
vfields = chainon (vfields, CLASSTYPE_AS_LIST (t));
}
@ -3836,18 +3841,22 @@ finish_struct_1 (t, warn_anon)
/* Don't re-use old size. */
DECL_SIZE (base_layout_decl) = NULL_TREE;
}
else if (empty)
{
/* C++: do not let empty structures exist. */
tree decl = build_lang_field_decl
(FIELD_DECL, NULL_TREE, char_type_node);
TREE_CHAIN (decl) = TYPE_FIELDS (t);
TYPE_FIELDS (t) = decl;
}
layout_type (t);
finish_struct_anon (t);
if (n_baseclasses)
if (n_baseclasses || empty)
TYPE_FIELDS (t) = TREE_CHAIN (TYPE_FIELDS (t));
/* C++: do not let empty structures exist. */
if (integer_zerop (TYPE_SIZE (t)))
TYPE_SIZE (t) = TYPE_SIZE (char_type_node);
/* Set the TYPE_DECL for this type to contain the right
value for DECL_OFFSET, so that we can use it as part
of a COMPONENT_REF for multiple inheritance. */

View File

@ -1672,6 +1672,9 @@ copy_assignment_arg_p (parmtype, virtualp)
tree parmtype;
int virtualp;
{
if (current_class_type == NULL_TREE)
return 0;
if (TREE_CODE (parmtype) == REFERENCE_TYPE)
parmtype = TREE_TYPE (parmtype);

View File

@ -1210,7 +1210,8 @@ unsigned_type (type)
return unsigned_intHI_type_node;
if (type1 == intQI_type_node)
return unsigned_intQI_type_node;
return type;
return signed_or_unsigned_type (1, type);
}
/* Return a signed type the same as TYPE in other respects. */
@ -1238,7 +1239,8 @@ signed_type (type)
return intHI_type_node;
if (type1 == unsigned_intQI_type_node)
return intQI_type_node;
return type;
return signed_or_unsigned_type (0, type);
}
/* Return a type the same as TYPE except unsigned or
@ -1249,8 +1251,10 @@ signed_or_unsigned_type (unsignedp, type)
int unsignedp;
tree type;
{
if (! INTEGRAL_TYPE_P (type))
if (! INTEGRAL_TYPE_P (type)
|| TREE_UNSIGNED (type) == unsignedp)
return type;
if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node))
return unsignedp ? unsigned_char_type_node : signed_char_type_node;
if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
@ -1445,6 +1449,12 @@ decay_conversion (exp)
type = TREE_TYPE (type);
code = TREE_CODE (type);
if (type == unknown_type_node)
{
cp_pedwarn ("assuming & on overloaded member function");
return build_unary_op (ADDR_EXPR, exp, 0);
}
}
if (code == REFERENCE_TYPE)
@ -7018,7 +7028,6 @@ c_expand_return (retval)
extern tree dtor_label, ctor_label;
tree result = DECL_RESULT (current_function_decl);
tree valtype = TREE_TYPE (result);
int returns_value = 1;
if (TREE_THIS_VOLATILE (current_function_decl))
warning ("function declared `noreturn' has a `return' statement");
@ -7074,20 +7083,20 @@ c_expand_return (retval)
else if (DECL_CONSTRUCTOR_P (current_function_decl)
&& retval != current_class_ptr)
{
error ("return from a constructor: use `this = ...' instead");
if (flag_this_is_variable)
error ("return from a constructor: use `this = ...' instead");
else
error ("return from a constructor");
retval = current_class_ptr;
}
if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE)
{
current_function_returns_null = 1;
/* We do this here so we'll avoid a warning about how the function
"may or may not return a value" in finish_function. */
returns_value = 0;
if (retval)
if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
pedwarn ("`return' with a value, in function returning void");
expand_return (retval);
return;
}
/* Add some useful error checking for C++. */
else if (TREE_CODE (valtype) == REFERENCE_TYPE)
@ -7168,143 +7177,56 @@ c_expand_return (retval)
(3) If an X(X&) constructor is defined, the return
value must be returned via that. */
/* If we're returning in a register, we can't initialize the
return value from a TARGET_EXPR. */
if (TREE_CODE (retval) == TARGET_EXPR
&& TYPE_MAIN_VARIANT (TREE_TYPE (retval)) == TYPE_MAIN_VARIANT (valtype)
&& ! current_function_returns_struct)
retval = expand_target_expr (retval);
if (retval == result
/* Watch out for constructors, which "return" aggregates
via initialization, but which otherwise "return" a pointer. */
|| DECL_CONSTRUCTOR_P (current_function_decl))
/* It's already done for us. */;
else if (TYPE_MODE (TREE_TYPE (retval)) == VOIDmode)
{
/* This is just an error--it's already been reported. */
if (TYPE_SIZE (valtype) == NULL_TREE)
return;
if (TYPE_MODE (valtype) != BLKmode
&& any_pending_cleanups (1))
retval = get_temp_regvar (valtype, retval);
}
else if (IS_AGGR_TYPE (valtype) && current_function_returns_struct)
{
expand_aggr_init (result, retval, 0, LOOKUP_ONLYCONVERTING);
expand_cleanups_to (NULL_TREE);
DECL_INITIAL (result) = NULL_TREE;
pedwarn ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
}
else
{
if (TYPE_MODE (valtype) == VOIDmode)
{
if (TYPE_MODE (TREE_TYPE (result)) != VOIDmode
&& warn_return_type)
warning ("return of void value in function returning non-void");
expand_expr_stmt (retval);
retval = 0;
result = 0;
}
else if (TYPE_MODE (valtype) != BLKmode
&& any_pending_cleanups (1))
{
retval = get_temp_regvar (valtype, retval);
expand_cleanups_to (NULL_TREE);
result = 0;
}
else
{
/* We already did this above, don't do it again. */
if (TREE_CODE (valtype) != REFERENCE_TYPE)
retval = convert_for_initialization (result, valtype, retval,
LOOKUP_NORMAL,
"return", NULL_TREE, 0);
DECL_INITIAL (result) = NULL_TREE;
}
if (retval == error_mark_node)
return;
}
/* We already did this above for refs, don't do it again. */
if (TREE_CODE (valtype) != REFERENCE_TYPE)
retval = convert_for_initialization (NULL_TREE, valtype, retval,
LOOKUP_NORMAL,
"return", NULL_TREE, 0);
emit_queue ();
/* We can't initialize a register from a NEW_EXPR. */
if (! current_function_returns_struct
&& TREE_CODE (retval) == TARGET_EXPR
&& TREE_CODE (TREE_OPERAND (retval, 0)) == NEW_EXPR)
retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval,
TREE_OPERAND (retval, 0));
if (retval == error_mark_node)
{
/* Avoid warning about control reaching end of function. */
expand_null_return ();
return;
}
}
if (retval != NULL_TREE
&& TREE_CODE_CLASS (TREE_CODE (retval)) == 'd'
&& cond_stack == 0 && loop_stack == 0 && case_stack == 0)
current_function_return_value = retval;
if (result)
if (ctor_label && TREE_CODE (ctor_label) != ERROR_MARK)
{
/* Everything's great--RETVAL is in RESULT. */
if (original_result_rtx)
{
store_expr (result, original_result_rtx, 0);
expand_cleanups_to (NULL_TREE);
use_variable (DECL_RTL (result));
if (ctor_label && TREE_CODE (ctor_label) != ERROR_MARK)
expand_goto (ctor_label);
else
expand_null_return ();
}
else if (retval && retval != result)
{
/* Clear this out so the later call to decl_function_context
won't end up bombing on us. */
if (DECL_CONTEXT (result) == error_mark_node)
DECL_CONTEXT (result) = NULL_TREE;
/* Here is where we finally get RETVAL into RESULT.
`expand_return' does the magic of protecting
RESULT from cleanups. */
retval = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (result),
retval));
/* This part _must_ come second, because expand_return looks for
the INIT_EXPR as the toplevel node only. :-( */
retval = build (INIT_EXPR, TREE_TYPE (result), result, retval);
TREE_SIDE_EFFECTS (retval) = 1;
expand_return (retval);
}
else
expand_return (result);
}
else
{
/* We may still need to put RETVAL into RESULT. */
result = DECL_RESULT (current_function_decl);
if (original_result_rtx)
{
/* Here we have a named return value that went
into memory. We can compute RETVAL into that. */
if (retval)
expand_assignment (result, retval, 0, 0);
else
store_expr (result, original_result_rtx, 0);
result = make_tree (TREE_TYPE (result), original_result_rtx);
}
else if (ctor_label && TREE_CODE (ctor_label) != ERROR_MARK)
{
/* Here RETVAL is CURRENT_CLASS_PTR, so there's nothing to do. */
expand_goto (ctor_label);
}
else if (retval)
{
/* Here is where we finally get RETVAL into RESULT.
`expand_return' does the magic of protecting
RESULT from cleanups. */
result = build (INIT_EXPR, TREE_TYPE (result), result, retval);
TREE_SIDE_EFFECTS (result) = 1;
expand_return (result);
}
else if (TYPE_MODE (TREE_TYPE (result)) != VOIDmode)
expand_return (result);
/* Here RETVAL is CURRENT_CLASS_PTR, so there's nothing to do. */
expand_goto (ctor_label);
}
current_function_returns_value = returns_value;
/* One way to clear out cleanups that EXPR might
generate. Note that this code will really be
dead code, but that is ok--cleanups that were
needed were handled by the magic of `return'. */
expand_cleanups_to (NULL_TREE);
if (retval && retval != result)
{
result = build (INIT_EXPR, TREE_TYPE (result), result, retval);
TREE_SIDE_EFFECTS (result) = 1;
}
expand_return (result);
current_function_returns_value = 1;
}
/* Start a C switch statement, testing expression EXP.