aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/expr.c11
-rw-r--r--gcc/function.c3
-rw-r--r--gcc/tree.c16
-rw-r--r--gcc/tree.h4
5 files changed, 41 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0abf7f5..9ce13da 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2000-03-13 Jason Merrill <jason@casey.cygnus.com>
+
+ * function.c (put_var_into_stack): Use type_for_mode to calculate
+ part_type. Use MEM_SET_IN_STRUCT_P.
+ * expr.c (store_field): Handle CONCAT.
+ (store_constructor): Use fields_length.
+ * tree.c (fields_length): New fn.
+ * tree.h: Declare it.
+
2000-03-13 Zack Weinberg <zack@wolery.cumb.org>
* Makefile.in (LIBCPP_OBJS): Add cpplex.o.
diff --git a/gcc/expr.c b/gcc/expr.c
index 671255e..5ba5ee6 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4151,7 +4151,7 @@ store_constructor (exp, target, align, cleared, size)
clear the whole structure first. */
else if (size > 0
&& ((list_length (CONSTRUCTOR_ELTS (exp))
- != list_length (TYPE_FIELDS (type)))
+ != fields_length (type))
|| mostly_zeros_p (exp)))
{
if (! cleared)
@@ -4758,6 +4758,15 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
return blk_object;
}
+ if (GET_CODE (target) == CONCAT)
+ {
+ /* We're storing into a struct containing a single __complex. */
+
+ if (bitpos != 0)
+ abort ();
+ return store_expr (exp, target, 0);
+ }
+
/* If the structure is in a register or if the component
is a bit field, we cannot use addressing to access it.
Use bit-field techniques or SUBREG to store in it. */
diff --git a/gcc/function.c b/gcc/function.c
index 1ffb821..318d16b 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1383,7 +1383,7 @@ put_var_into_stack (decl)
/* A CONCAT contains two pseudos; put them both in the stack.
We do it so they end up consecutive. */
enum machine_mode part_mode = GET_MODE (XEXP (reg, 0));
- tree part_type = TREE_TYPE (TREE_TYPE (decl));
+ tree part_type = type_for_mode (part_mode, 0);
#ifdef FRAME_GROWS_DOWNWARD
/* Since part 0 should have a lower address, do it second. */
put_reg_into_stack (function, XEXP (reg, 1), part_type, part_mode,
@@ -1409,6 +1409,7 @@ put_var_into_stack (decl)
PUT_CODE (reg, MEM);
MEM_VOLATILE_P (reg) = MEM_VOLATILE_P (XEXP (reg, 0));
MEM_ALIAS_SET (reg) = get_alias_set (decl);
+ MEM_SET_IN_STRUCT_P (reg, AGGREGATE_TYPE_P (TREE_TYPE (decl)));
/* The two parts are in memory order already.
Use the lower parts address as ours. */
diff --git a/gcc/tree.c b/gcc/tree.c
index a415946..d52179c 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2004,6 +2004,22 @@ list_length (t)
return len;
}
+/* Returns the number of FIELD_DECLs in TYPE. */
+
+int
+fields_length (type)
+ tree type;
+{
+ tree t = TYPE_FIELDS (type);
+ int count = 0;
+
+ for (; t; t = TREE_CHAIN (t))
+ if (TREE_CODE (t) == FIELD_DECL)
+ ++count;
+
+ return count;
+}
+
/* Concatenate two chains of nodes (chained through TREE_CHAIN)
by modifying the last node in chain 1 to point to chain 2.
This is the Lisp primitive `nconc'. */
diff --git a/gcc/tree.h b/gcc/tree.h
index faa4a90..5d4bdff 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1930,6 +1930,10 @@ extern tree nreverse PARAMS ((tree));
extern int list_length PARAMS ((tree));
+/* Returns the number of FIELD_DECLs in a type. */
+
+extern int fields_length PARAMS ((tree));
+
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */
extern int integer_zerop PARAMS ((tree));