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: intermodule and comptypes - need some help


Geoff Keating <geoffk@geoffk.org> writes:

>> The basic concept is, there's a scope (currently called
>> external_scope) which holds all TREE_PUBLIC declarations and possibly
>> some other things.  This scope is 'outer' to the file scope, and
>> persists across translation units.  Declarations in there are
>> invisible until a duplicate declaration of the same thing is
>> encountered.
>> 
>> The details are complicated, but I think the result winds up being
>> more straightforward and less buggy than what we have now.  If, that
>> is, I can make it work.
>
> I considered that, but stopped when I discovered
>
> extern int x;
> static int x = 2;
>
> We might want to consider banning that (it does produce a warning
> now), but I suspect someone relies on it.

This is easy to handle - whether or not we want to ban it.  (At
present I am producing an unconditional warning, no more.)  The
trick is that visibility is decoupled from presence in the ->names
list of each scope.

If these appear in two different translation units (but both
at file scope) the static declaration will simply shadow the
external declaration - probably don't even want to generate a
-Wshadow warning.

If they appear in the same translation unit, then the external
declaration is put into the externals scope, but made visible 
in the file scope.  When processing the static declaration,
pushdecl notices the external decl already visible, issues a
warning, and shadows it with the static.

> ====================t1.c
> struct foo;
> extern void x (struct foo *);
> struct foo {
>   int a, b;
> };
> ====================t2.c
> struct foo {
>   double d;
> };
> void x (struct foo *y)
> {
>   y->d = 0;
> }
> ====================
>
> This is invalid code, I think, but whether it is or is not it does make
> the implementation tricky: if it's valid, you want to keep information
> about 't1.c::struct foo' out of t2.c, and if it's invalid you want to
> detect the error even if t2.c is compiled first.

Hm.  I think it's just undefined behavior if foo were to be called
from t1.c with that definition of struct foo visible.  We do _not_
want to issue diagnostics if x in t1 were static, for instance.

I'll think about this a bit more.

>> Thanks for the hint.  The predicate I wrote *should* work, then?
>
> I think it would be a good thing if we arranged for it to work, yes.

Ok.

>> and, using your hint, I think I've tracked it to BLOCK_SUPERCONTEXT of
>> the block that's DECL_INITIAL of each translation_unit_decl not
>> getting initialized properly.  The types being handed to my predicate
>> *seem* to have the right TYPE_CONTEXTs.
>
> Is there a mistake in that paragraph?  I didn't think
> translation_unit_decls have DECL_INITIAL...

Didn't you *invent* TRANSLATION_UNIT_DECL?

This is what my c_reset_state looks like now:

   /* Pop the global scope.  */
   if (current_scope != global_scope)
       current_scope = global_scope;
   file_scope_decl = current_file_decl;
   DECL_INITIAL (file_scope_decl) = poplevel (1, 0, 0);
+  BLOCK_SUPERCONTEXT (DECL_INITIAL (file_scope_decl)) = file_scope_decl;
   truly_local_externals = NULL_TREE;

Adding that line makes me able to get through an --enable-intermodule,
C only bootstrap.  I'll post the patch shortly.

zw


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