This is the mail archive of the 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

> From: "Zack Weinberg" <>
> Date: Thu, 07 Aug 2003 17:48:49 -0700

> Geoff Keating <> 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.

Note that this is a change of behaviour; before, this used to cause
'x' to refer to the static variable throughout the translation unit.
This would make a difference if it's 'extern const int'.

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

Yes, you're certainly allowed to have the same tag defined in two
different translation units with different values.  It's undefined
behaviour to declare the same object (as determined in this case by the
linkage rules) with incompatible types.  I am not, however, sure
whether or not this particular example counts as a declaration with
incompatible types; at the end of the translation unit, they are
incompatible, but not at the point of the declaration.

Yes, it's undefined behaviour if 'x' was actually called with that
definition of struct foo visible... although, again, I'm not sure
what happens if you call it when the structure is still incomplete.

> I'll think about this a bit more.


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

Oh, I remember now.  Yes, that seems right.

- Geoffrey Keating <>

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