mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-21 23:51:18 +08:00
90th Cygnus<->FSF quick merge
From-SVN: r13082
This commit is contained in:
parent
cced4d25ea
commit
691c003dcc
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
||||
|
182
gcc/cp/typeck.c
182
gcc/cp/typeck.c
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user