> On 05/10/2015 12:33 PM, Jan Hubicka wrote:
> >This is properly honored by C++ FE but other FEs are bit random, which in 
> >turn
> >confuses type_in_anonymous_namespace_p predicate that leads to flase 
> >poistives
> >on type mismatch warnings.  I used to be able to get around by checking only
> >C++ types at LTO time, but with type checking in lto-symtab I can not, 
> >because
> >I do want to compare type compatibility cross translation units and cross 
> >languages
> >and we have no reliable way to say what type originated as C++ and what did 
> >not.
> 
> I think we should, as only C++ declarations are subject to the ODR.
> C has different (structural) compatibility rules, and I think they
> should apply when comparing C and C++ types.
> 
> Since C struct names have no linkage, I don't think it's right to
> set TREE_PUBLIC on them.

Yes, I need safe way to tell what type is subject to ODR and what is not.
I am not quite sure what is the best approach here. This is what the code is 
doing
currently:

To detect ODR types at LTO time I use combination of presence of mangled name
and type_in_anonymous_namespace_p check. (The idea is that we do not really need
to mangle anonymous type as we do not need to deal with cross-module merging.):

odr_type_p (const_tree t)
{
  if (type_in_anonymous_namespace_p (t))
    return true;
  /* We do not have this information when not in LTO, but we do not need
     to care, since it is used only for type merging.  */
  gcc_assert (in_lto_p || flag_lto);

  return (TYPE_NAME (t)
          && (DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (t))));
}
bool
type_in_anonymous_namespace_p (const_tree t)
{
  /* TREE_PUBLIC of TYPE_STUB_DECL may not be properly set for
     bulitin types; those have CONTEXT NULL.  */
  if (!TYPE_CONTEXT (t))
    return false;
  return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)));
}

the catch is that type_in_anonymous_namespace_p returns true for some C types.
The TYPE_CONTEXT test is already hack as I run into cases of pre-streamed LTO
types to get injected into C++ classes (i.e. if you refere to int, LTO
streaming will replace C++ int with TREE_PUBLIC (TYPE_STUB_DECL (t)) by its own
int that is !TREE_PUBLIC (TYPE_STUB_DECL (t)).  The hack to avoid builtin types
made type_in_anonymous_namespace_p to work well in cases I needed for class
types. (I believe it is because C builds record with
 TREE_PUBLIC (TYPE_STUB_DECL (t))=1 but it is a while I checked this)

We could certainly just add a flag TYPE_ODR_P that says "this type is
controlled by odr rule".  I considered that but it is generally not so nice
to introduce new flags and it seemed to me that because C
standard allows to match all types cross-module on structural basis, it makes
sense to consider them all as having public linkage because they are
"accessible from outside this translation unit." as tree.h defines the flag.

I would be happy with TYPE_ODR_P or any other solution that looks better.

Honza

> 
> Jason

Reply via email to