> On 06/17/2013 09:35 AM, Jan Hubicka wrote: > >To get meaningful warnings, we need to know what decls/types are subject > >to ODR. Do you think you can make C++ FE to drop a flag so middle-end know? > >We can LTO ODR and non-ODR languages together. > > Basically everything in C++ is subject to the ODR. There are two > cases: either there can be only one definition anywhere (e.g. normal > variables and functions, anything local to such a function) or all > definitions need to be identical.
Does ODR hold also for extern "C" declarations in C++? > > In C, you can treat all structurally identical types as the same, right? Sort of. Currently we have two notions of equivalency of types 1) TYPE_CANONICAL that is strictly merged by structural equivalence. The equivalency is defined by gimple_canonical_types_compatible_p and is very conservative (i.e. ignores type names for example) This is what drives most of backend and aliasing machinery. Having false equivalences leads to worse TBAA, false nonequivalences leads to wrong code due to aliasing. 2) Richard's type (and now tree) merging. This merging is conservative on what is considered to be equivalent type and compare pretty much everything in the in-memory type representaion (i.e. names, modifiers, BINFOs, stuff that matters for debug or devirt machinery) false equivalences leads to loss of debug info quality and false devirtualizations, false nonequivalences leads to explossions of memory use and streaming time for Firefox or any other huge LTO build. At least this is my understanding, Richard know more ;) ODR adds third notion of equivalency that should sit strictly in between and in fact perhaps for ODR types we can make 1)=2)=ODR unless ODR is obviously violated. What we need a flag for is to know whether type originates from C++ FE or something else. While we can add the flag at streaming time, I guess it would be easier if we had TYPE_ODR/DECL_ODR flag and it was set by C++ FE itself so it was easilly available everywhere in the middle-end. If we want ODR violation warning, I think in first cut we could warn out when types are same by ODR predicate, they are flagged as ODR types and they are not having same CANONICAL types. In next step we can sort out other reasons they are not merged by Richard's merging code but stil equivalent in C++ sense. There are easy cases to list - i.e. we will not merge class type from unit that defines the keyed method with class type from other unit since the associated binfo will differ in types of the declarations (DECL_EXTERNAL versus TREE_PUBLIC+STATIC). I am sure there are many more such situations. I also expect that by looking into these cases we can refine 2) definition of equivalency. > > The common subset of those would be treating everything with the > same structure and the same name/context as identical. > > Hmm, it occurs to me that you should check that your patch does the > right thing with anonymous namespaces: a class in an anonymous > namespace is not the same as a class with the same name in an > anonymous namespace in another translation unit. The C++ front end > clears TREE_PUBLIC on the TYPE_STUB_DECL (TYPE_MAIN_VARIANT of such > types to indicate that they are local to that TU. OK, thanks! I naively assumed that checking DECL_NAME for NULL is enough here. I will fix this. Honza