[cfe-dev] Type::isIncompleteType()...

Neil Booth neil at daikokuya.co.uk
Mon Feb 11 01:49:19 PST 2008

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 at 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.


More information about the cfe-dev mailing list