Chris Lattner wrote:-
>I don't think it necessarily makes sense to expect extra diagnostics
>in any particular situation; once something is erroneous there are
>many reasonable recovery strategies. I think my cfe just ignores
>the foo declaration as if it didn't exist, for example. Another
>quite reasonable strategy would be to have a member foo in the
>structure but flag it erroneous; this would mean uses of foo wouldn't
>get diagnostics about no such member.
In this specific case (a single malformed field in a struct) I agree
with Neil: it's best to just recover by dropping that one field decl,
or change it into a decl with a valid type (in the case of function,
make it a pointer to function) which is probably even better. In
certain parts of type analysis we try really hard to turn an erroneous
type into a valid one.
As everyone knows, there is a tradeoff here: the more you try to
"infer" what the user meant, the more likely it is that your guess can
trigger a cascade of errors. In this specific case, I think that
turning a function into a pointer to function is unlikely to do that
though.
That said, Steve's idea might still be a good one. In what other
cases can a struct decl be marked erroneous?
Actually my cfe does what I said second above: it has foo as a
member that is flagged erroneous. I put a lot of effort into
"clean" recovery; as far as possible I wanted something erroneous
to only cause a single complaint. So for example, compiling
struct S {
int a;
int foo();
};
struct S s;
void bar (void) { s.bar = s.foo = &s.a; }
gives the following:
neil@duron:~$ ~/src/cfe/cfe /tmp/bug.c
"/tmp/bug.c", line 3: error: members may not have function type
int foo();
^
"/tmp/bug.c", line 8: error: structure "S" has no member "bar"
void bar (void) { s.bar = s.foo = &s.a; }
^
2 errors found compiling "/tmp/bug.c".
Here you see that it knows bar is not a member and that foo is a
member, and that is doesn't complain about the type of the assignment
to foo (or bar) because foo's type is erroneous.
So rather than give an invalid construct a valid type, I remember
it as erroneous and suppress further diagnostics. With a bit of
effort this can be done in a non-intrusive way, and I find it slightly
preferable to giving a valid type that can cause further diagnostics.
Neil.