This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ICE in change_address at emit_rtl.c


On Sat, Nov 24, 2001 at 11:37:01PM +0100, Gabriel Dos Reis wrote:
> Mark Mitchell <mark@codesourcery.com> writes:
> | A solution I have advocated in the past is to have ERROR_MARK_TYPE,
> | ERROR_MARK_DECL, etc.  This would help, since using DECL_ARTIFICIAL,
> | say, on the ERROR_MARK_DECL would work.
> | 
> | Neil's approach is possible as well.
> | 
> | Neil is right that the current strategy actually makes GCC harder
> | to work on, and does little to improve reliability.
> 
> I share Neil's sentiment. 
> 
> What worries is the alternative he's proposing.  My personnal view is
> to have ERROR_MARK_XXX for TYPE, DECL and such in order to enhance
> the tree type system and maintainability.  But Neil is proposing to
> get rid of those nodes.

I think it's fruitless to argue over precisely how we'll make this work
better without sitting down and going through the code, but we should
be able to lay down some design principles - and whatever winds up
fulfilling them, will be the right thing.  So here's what I think we
ought to be going for:

1. Language independent code never sees ill-formed trees.  The front end
is responsible for replacing erroneous input with harmless constructs.
"Harmless" means "won't cause anything downstream to crash, and needs
no special casing."  How exactly we implement that is open to discussion,
but answers to the remaining questions may affect this.

1a. Within language dependent code, ill-formed trees should have as short
lifetimes as possible.  For instance, the code which generates statement-
level trees should be able to rely on the expression parser to produce only
well-formed expressions.

2. As few spurious errors reported to the user as possible.  This is one
place where ERROR_MARK_NODE really falls down.  Consider these ill-formed
declarations:

double int number;
typedef struct foo foo_t[;

These will both provoke error cascades in the current compiler, mainly
because 'number' and 'foo_t' don't get entered into the symbol table,
so we issue errors every time they are used, even if the use would have
been valid given a valid declaration.  What we need here is a way of saying,
well, we know "number" is a scalar non-pointer variable so we'll let the user
do things with it that would be acceptable of such variables.  It's harder to
say what foo_t is supposed to be - but we can say that a forward declaration
of struct foo has happened, and it will probably be okay to treat foo_t
as a typedef for struct foo.

We also need to do better recovering from parser errors - here I think the
additional power of recursive descent should eliminate the problem, and we
don't need any funky data structures.  But take that typedef as an example
of what needs to be handled - there is no construct which contains a
semicolon inside square brackets (without further nesting) so we should
_not_ parse the rest of the file as if we are inside square brackets, which
is (very close to) what happens right now.

3. Make efforts to get back in sync and continue processing the rest of the
file.  At the very least, errors in one top level construct should not
propagate outside that construct.  We may, of course, have to prevent
later operations from digging too deeply inside that construct.  For instance,

inline int foo(void) { syntax error; }

should become "extern int foo(void);" for purpose of further processing.

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]