Commit 314b662a by Michael Matz Committed by Michael Matz

re PR c/52977 (internal compiler error: Segmentation fault with `-x c-header' or…

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
parent 7c98ec60
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> 2012-04-19 Richard Guenther <rguenther@suse.de>
PR tree-optimization/53031 PR tree-optimization/53031
......
...@@ -2291,6 +2291,8 @@ struct walk_type_data ...@@ -2291,6 +2291,8 @@ struct walk_type_data
const char *reorder_fn; const char *reorder_fn;
bool needs_cast_p; bool needs_cast_p;
bool fn_wants_lvalue; bool fn_wants_lvalue;
bool in_record_p;
int loopcounter;
}; };
/* Print a mangled name representing T to OF. */ /* Print a mangled name representing T to OF. */
...@@ -2592,7 +2594,7 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2592,7 +2594,7 @@ walk_type (type_p t, struct walk_type_data *d)
} }
else else
{ {
int loopcounter = d->counter++; int loopcounter = d->loopcounter;
const char *oldval = d->val; const char *oldval = d->val;
const char *oldprevval3 = d->prev_val[3]; const char *oldprevval3 = d->prev_val[3];
char *newval; char *newval;
...@@ -2602,7 +2604,10 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -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, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent, oprintf (d->of, "%*sfor (i%d = 0; i%d != (size_t)(", d->indent,
"", loopcounter, loopcounter); "", 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); oprintf (d->of, "); i%d++) {\n", loopcounter);
d->indent += 2; d->indent += 2;
d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter); d->val = newval = xasprintf ("%s[i%d]", oldval, loopcounter);
...@@ -2624,7 +2629,7 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2624,7 +2629,7 @@ walk_type (type_p t, struct walk_type_data *d)
case TYPE_ARRAY: case TYPE_ARRAY:
{ {
int loopcounter = d->counter++; int loopcounter;
const char *oldval = d->val; const char *oldval = d->val;
char *newval; char *newval;
...@@ -2633,6 +2638,11 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2633,6 +2638,11 @@ walk_type (type_p t, struct walk_type_data *d)
if (t->u.a.p->kind == TYPE_SCALAR) if (t->u.a.p->kind == TYPE_SCALAR)
break; break;
if (length)
loopcounter = d->loopcounter;
else
loopcounter = d->counter++;
/* When walking an array, compute the length and store it in a /* When walking an array, compute the length and store it in a
local variable before walking the array elements, instead of local variable before walking the array elements, instead of
recomputing the length expression each time through the loop. recomputing the length expression each time through the loop.
...@@ -2643,13 +2653,16 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2643,13 +2653,16 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*s{\n", d->indent, ""); oprintf (d->of, "%*s{\n", d->indent, "");
d->indent += 2; d->indent += 2;
oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter); oprintf (d->of, "%*ssize_t i%d;\n", d->indent, "", loopcounter);
oprintf (d->of, "%*ssize_t l%d = (size_t)(", if (!d->in_record_p || !length)
d->indent, "", loopcounter); {
if (length) oprintf (d->of, "%*ssize_t l%d = (size_t)(",
output_escaped_param (d, length, "length"); d->indent, "", loopcounter);
else if (length)
oprintf (d->of, "%s", t->u.a.len); output_escaped_param (d, length, "length");
oprintf (d->of, ");\n"); 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", oprintf (d->of, "%*sfor (i%d = 0; i%d != l%d; i%d++) {\n",
d->indent, "", d->indent, "",
...@@ -2678,6 +2691,9 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2678,6 +2691,9 @@ walk_type (type_p t, struct walk_type_data *d)
const int union_p = t->kind == TYPE_UNION; const int union_p = t->kind == TYPE_UNION;
int seen_default_p = 0; int seen_default_p = 0;
options_p o; options_p o;
int lengths_seen = 0;
int endcounter;
bool any_length_seen = false;
if (!t->u.s.line.file) if (!t->u.s.line.file)
error_at_line (d->line, "incomplete structure `%s'", t->u.s.tag); 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) ...@@ -2713,6 +2729,45 @@ walk_type (type_p t, struct walk_type_data *d)
d->indent += 2; d->indent += 2;
oprintf (d->of, "%*s{\n", d->indent, ""); 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) for (f = t->u.s.fields; f; f = f->next)
{ {
options_p oo; options_p oo;
...@@ -2721,6 +2776,7 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2721,6 +2776,7 @@ walk_type (type_p t, struct walk_type_data *d)
int skip_p = 0; int skip_p = 0;
int default_p = 0; int default_p = 0;
int use_param_p = 0; int use_param_p = 0;
const char *fieldlength = NULL;
char *newval; char *newval;
d->reorder_fn = NULL; d->reorder_fn = NULL;
...@@ -2741,6 +2797,9 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2741,6 +2797,9 @@ walk_type (type_p t, struct walk_type_data *d)
else if (strncmp (oo->name, "use_param", 9) == 0 else if (strncmp (oo->name, "use_param", 9) == 0
&& (oo->name[9] == '\0' || ISDIGIT (oo->name[9]))) && (oo->name[9] == '\0' || ISDIGIT (oo->name[9])))
use_param_p = 1; use_param_p = 1;
else if (strcmp (oo->name, "length") == 0
&& oo->kind == OPTION_STRING)
fieldlength = oo->info.string;
if (skip_p) if (skip_p)
continue; continue;
...@@ -2774,16 +2833,24 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2774,16 +2833,24 @@ walk_type (type_p t, struct walk_type_data *d)
"field `%s' is missing `tag' or `default' option", "field `%s' is missing `tag' or `default' option",
f->name); f->name);
if (fieldlength)
{
d->loopcounter = endcounter - lengths_seen--;
}
d->line = &f->line; d->line = &f->line;
d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name); d->val = newval = xasprintf ("%s%s%s", oldval, dot, f->name);
d->opt = f->opt; d->opt = f->opt;
d->used_length = false; d->used_length = false;
d->in_record_p = !union_p;
if (union_p && use_param_p && d->param == NULL) if (union_p && use_param_p && d->param == NULL)
oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, ""); oprintf (d->of, "%*sgcc_unreachable ();\n", d->indent, "");
else else
walk_type (f->type, d); walk_type (f->type, d);
d->in_record_p = false;
free (newval); free (newval);
if (union_p) if (union_p)
...@@ -2808,6 +2875,11 @@ walk_type (type_p t, struct walk_type_data *d) ...@@ -2808,6 +2875,11 @@ walk_type (type_p t, struct walk_type_data *d)
oprintf (d->of, "%*s}\n", d->indent, ""); oprintf (d->of, "%*s}\n", d->indent, "");
d->indent -= 2; d->indent -= 2;
} }
if (any_length_seen)
{
d->indent -= 2;
oprintf (d->of, "%*s}\n", d->indent, "");
}
} }
break; break;
......
...@@ -1329,7 +1329,6 @@ make_vector_stat (unsigned len MEM_STAT_DECL) ...@@ -1329,7 +1329,6 @@ make_vector_stat (unsigned len MEM_STAT_DECL)
TREE_SET_CODE (t, VECTOR_CST); TREE_SET_CODE (t, VECTOR_CST);
TREE_CONSTANT (t) = 1; TREE_CONSTANT (t) = 1;
VECTOR_CST_NELTS (t) = len;
return t; return t;
} }
......
...@@ -1534,14 +1534,13 @@ struct GTY(()) tree_complex { ...@@ -1534,14 +1534,13 @@ struct GTY(()) tree_complex {
}; };
/* In a VECTOR_CST node. */ /* 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_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX]) #define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
struct GTY(()) tree_vector { struct GTY(()) tree_vector {
struct tree_typed typed; struct tree_typed typed;
unsigned length; tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
tree GTY ((length ("%h.length"))) elts[1];
}; };
#include "symtab.h" #include "symtab.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment