aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2012-04-19 13:29:29 +0000
committerMichael Matz <matz@gcc.gnu.org>2012-04-19 13:29:29 +0000
commit314b662a3a636250eda24be515fb34c34140fb6a (patch)
tree8f69ea3822d53cbb5ee137c295bc3fb2dec89d98 /gcc
parent7c98ec605d9c9d2bbb6d431016ebe74a73f0a522 (diff)
downloadgcc-314b662a3a636250eda24be515fb34c34140fb6a.zip
gcc-314b662a3a636250eda24be515fb34c34140fb6a.tar.gz
gcc-314b662a3a636250eda24be515fb34c34140fb6a.tar.bz2
re PR c/52977 (internal compiler error: Segmentation fault with `-x c-header' or `-x cxx-header' option)
PR middle-end/52977 * tree.h (VECTOR_CST_NELTS): Use part number of types again. (struct tree_vector): Adjust GTY length. * tree.c (make_vector_stat): Don't set VECTOR_CST_NELTS. * gengtype.c (struct walk_type_data): Add in_record_p and loopcounter members. (walk_type, <TYPE_POINTER, TYPE_ARRAY>): Handle case where our caller emitted the length calulation already. (walk_type, <TYPE_UNION, TYPE_STRUCT>): Emit length calculations From-SVN: r186593
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/gengtype.c92
-rw-r--r--gcc/tree.c1
-rw-r--r--gcc/tree.h5
4 files changed, 98 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0dca933..1f27b62 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2012-04-19 Michael Matz <matz@suse.de>
+
+ PR middle-end/52977
+ * tree.h (VECTOR_CST_NELTS): Use part number of types again.
+ (struct tree_vector): Adjust GTY length.
+ * tree.c (make_vector_stat): Don't set VECTOR_CST_NELTS.
+
+ * gengtype.c (struct walk_type_data): Add in_record_p and loopcounter
+ members.
+ (walk_type, <TYPE_POINTER, TYPE_ARRAY>): Handle case where our
+ caller emitted the length calulation already.
+ (walk_type, <TYPE_UNION, TYPE_STRUCT>): Emit length calculations
+ before handling any of the fields for structs.
+
2012-04-19 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53031
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index fa45392..abafaa9 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -2291,6 +2291,8 @@ struct walk_type_data
const char *reorder_fn;
bool needs_cast_p;
bool fn_wants_lvalue;
+ bool in_record_p;
+ int loopcounter;
};
/* Print a mangled name representing T to OF. */
@@ -2592,7 +2594,7 @@ walk_type (type_p t, struct walk_type_data *d)
}
else
{
- int loopcounter = d->counter++;
+ int loopcounter = d->loopcounter;
const char *oldval = d->val;
const char *oldprevval3 = d->prev_val[3];
char *newval;
@@ -2602,7 +2604,10 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
"", loopcounter, loopcounter);
- output_escaped_param (d, length, "length");
+ if (!d->in_record_p)
+ output_escaped_param (d, length, "length");
+ else
+ oprintf (d->of, "l%d", loopcounter);
oprintf (d->of, "); i%d++) {\n", loopcounter);
d->indent += 2;
d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
@@ -2624,7 +2629,7 @@ walk_type (type_p t, struct walk_type_data *d)
case TYPE_ARRAY:
{
- int loopcounter = d->counter++;
+ int loopcounter;
const char *oldval = d->val;
char *newval;
@@ -2633,6 +2638,11 @@ walk_type (type_p t, struct walk_type_data *d)
if (t->u.a.p->kind == TYPE_SCALAR)
break;
+ if (length)
+ loopcounter = d->loopcounter;
+ else
+ loopcounter = d->counter++;
+
/* When walking an array, compute the length and store it in a
local variable before walking the array elements, instead of
recomputing the length expression each time through the loop.
@@ -2643,13 +2653,16 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*s{\n", d->indent, "");
d->indent += 2;
oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
- oprintf (d->of, "%*ssize_t l%d = (size_t)(",
- d->indent, "", loopcounter);
- if (length)
- output_escaped_param (d, length, "length");
- else
- oprintf (d->of, "%s", t->u.a.len);
- oprintf (d->of, ");\n");
+ if (!d->in_record_p || !length)
+ {
+ oprintf (d->of, "%*ssize_t l%d = (size_t)(",
+ d->indent, "", loopcounter);
+ if (length)
+ output_escaped_param (d, length, "length");
+ else
+ oprintf (d->of, "%s", t->u.a.len);
+ oprintf (d->of, ");\n");
+ }
oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
d->indent, "",
@@ -2678,6 +2691,9 @@ walk_type (type_p t, struct walk_type_data *d)
const int union_p = t->kind == TYPE_UNION;
int seen_default_p = 0;
options_p o;
+ int lengths_seen = 0;
+ int endcounter;
+ bool any_length_seen = false;
if (!t->u.s.line.file)
error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag);
@@ -2713,6 +2729,45 @@ walk_type (type_p t, struct walk_type_data *d)
d->indent += 2;
oprintf (d->of, "%*s{\n", d->indent, "");
}
+
+ for (f = t->u.s.fields; f; f = f->next)
+ {
+ options_p oo;
+ int skip_p = 0;
+ const char *fieldlength = NULL;
+
+ d->reorder_fn = NULL;
+ for (oo = f->opt; oo; oo = oo->next)
+ if (strcmp (oo->name, "skip") == 0)
+ skip_p = 1;
+ else if (strcmp (oo->name, "length") == 0
+ && oo->kind == OPTION_STRING)
+ fieldlength = oo->info.string;
+
+ if (skip_p)
+ continue;
+ if (fieldlength)
+ {
+ lengths_seen++;
+ d->counter++;
+ if (!union_p)
+ {
+ if (!any_length_seen)
+ {
+ oprintf (d->of, "%*s{\n", d->indent, "");
+ d->indent += 2;
+ }
+ any_length_seen = true;
+
+ oprintf (d->of, "%*ssize_t l%d = (size_t)(",
+ d->indent, "", d->counter - 1);
+ output_escaped_param (d, fieldlength, "length");
+ oprintf (d->of, ");\n");
+ }
+ }
+ }
+ endcounter = d->counter;
+
for (f = t->u.s.fields; f; f = f->next)
{
options_p oo;
@@ -2721,6 +2776,7 @@ walk_type (type_p t, struct walk_type_data *d)
int skip_p = 0;
int default_p = 0;
int use_param_p = 0;
+ const char *fieldlength = NULL;
char *newval;
d->reorder_fn = NULL;
@@ -2741,6 +2797,9 @@ walk_type (type_p t, struct walk_type_data *d)
else if (strncmp (oo->name, "use_param", 9) == 0
&& (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
use_param_p = 1;
+ else if (strcmp (oo->name, "length") == 0
+ && oo->kind == OPTION_STRING)
+ fieldlength = oo->info.string;
if (skip_p)
continue;
@@ -2774,16 +2833,24 @@ walk_type (type_p t, struct walk_type_data *d)
"field `%s' is missing `tag' or `default' option",
f->name);
+ if (fieldlength)
+ {
+ d->loopcounter = endcounter - lengths_seen--;
+ }
+
d->line = &f->line;
d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
d->opt = f->opt;
d->used_length = false;
+ d->in_record_p = !union_p;
if (union_p && use_param_p && d->param == NULL)
oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
else
walk_type (f->type, d);
+ d->in_record_p = false;
+
free (newval);
if (union_p)
@@ -2808,6 +2875,11 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*s}\n", d->indent, "");
d->indent -= 2;
}
+ if (any_length_seen)
+ {
+ d->indent -= 2;
+ oprintf (d->of, "%*s}\n", d->indent, "");
+ }
}
break;
diff --git a/gcc/tree.c b/gcc/tree.c
index 7a71c24..b0d52b2 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1329,7 +1329,6 @@ make_vector_stat (unsigned len MEM_STAT_DECL)
TREE_SET_CODE (t, VECTOR_CST);
TREE_CONSTANT (t) = 1;
- VECTOR_CST_NELTS (t) = len;
return t;
}
diff --git a/gcc/tree.h b/gcc/tree.h
index 6bfc29e..e719be2 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1534,14 +1534,13 @@ struct GTY(()) tree_complex {
};
/* In a VECTOR_CST node. */
-#define VECTOR_CST_NELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.length)
+#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
#define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
struct GTY(()) tree_vector {
struct tree_typed typed;
- unsigned length;
- tree GTY ((length ("%h.length"))) elts[1];
+ tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
};
#include "symtab.h"