aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1996-10-31 17:08:58 +0000
committerMike Stump <mrs@gcc.gnu.org>1996-10-31 17:08:58 +0000
commit691c003dccd336c1350119b2f7d4b54c46e2a5fb (patch)
treef482dabe3bf5332dad7f8b35b91fd4b491d5841f /gcc/cp
parentcced4d25eadca69195cc6f854b4e67a981a0faae (diff)
downloadgcc-691c003dccd336c1350119b2f7d4b54c46e2a5fb.zip
gcc-691c003dccd336c1350119b2f7d4b54c46e2a5fb.tar.gz
gcc-691c003dccd336c1350119b2f7d4b54c46e2a5fb.tar.bz2
90th Cygnus<->FSF quick merge
From-SVN: r13082
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog28
-rw-r--r--gcc/cp/call.c4
-rw-r--r--gcc/cp/class.c21
-rw-r--r--gcc/cp/decl2.c3
-rw-r--r--gcc/cp/typeck.c176
5 files changed, 98 insertions, 134 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1c95b3b..b5cf22a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 9ae201c..80258c0 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 60b2cff..28391dc 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -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. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 0775bb2..4bd06a3 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -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);
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1e09c28..4c876f6 100644
--- a/gcc/cp/typeck.c
+++ b/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 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);
+
+ /* 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)
{
- /* 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;
+ /* Avoid warning about control reaching end of function. */
+ expand_null_return ();
+ return;
}
- if (retval == error_mark_node)
- return;
}
- emit_queue ();
-
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);
+ /* Here RETVAL is CURRENT_CLASS_PTR, so there's nothing to do. */
+ expand_goto (ctor_label);
}
- else
+
+ if (retval && retval != result)
{
- /* 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);
+ result = build (INIT_EXPR, TREE_TYPE (result), result, retval);
+ TREE_SIDE_EFFECTS (result) = 1;
}
-
- 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);
+ expand_return (result);
+ current_function_returns_value = 1;
}
/* Start a C switch statement, testing expression EXP.