On Tue, 23 Jul 2019 at 23:22, Jeffrey Walton <noloader@xxxxxxxxx> wrote: > > We caught a bug report from the openSUSE folks. They are building with > LTO and -flto=6, and the new build flags generate ODR violations in > our library. > > For example, this class: This isn't a class, it's a class template. What are the template arguments used when you get an error? > template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> > class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> > { > public: > typedef KEY_CLASS KeyClass; > virtual ~TF_ObjectImpl() {} > const KeyClass & GetKey() const {return m_trapdoorFunction;} > KeyClass & AccessKey() {return m_trapdoorFunction;} > private: > KeyClass m_trapdoorFunction; > }; > > Produces ODR findings when using LTO like: > > pubkey.h:640:26: warning: type ‘struct TF_ObjectImpl’ violates the C++ > One Definition Rule [-Wodr] > class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> > ... > pubkey.h:640:26: note: a different type is defined in another translation unit > class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> > ... > pubkey.h:651:11: note: the first difference of corresponding > definitions is field ‘m_trapdoorFunction’ > KeyClass m_trapdoorFunction; > > When I remove the typedef and use KEY_CLASS directly: > > template <class BASE, class SCHEME_OPTIONS, class KEY_CLASS> > class TF_ObjectImpl : public TF_ObjectImplBase<BASE, SCHEME_OPTIONS, KEY_CLASS> > { > public: > // typedef KEY_CLASS KeyClass; > virtual ~TF_ObjectImpl() {} > const KeyClass & GetKey() const {return m_trapdoorFunction;} > KeyClass & AccessKey() {return m_trapdoorFunction;} > private: > KEY_CLASS m_trapdoorFunction; > }; > > Then the finding goes away. > > As far as I know, this is boilerplate templated C++ code. There is no > cpu specific or platform specific code involved. > > My first question is, should a class-scope typedef like used above effect ODR? No. > The problem above on occurs on ARM. i686, x86_64 and Aarch64 are OK > and do not generate findings. Someone on Stack Overflow claimed the > ARM compiler was correct, and the other platforms missed the finding. No, that's not what they said. They said that the answer to "Is it expected that using LTO would uncover ODR violations in a C++ library?" is yes. That's a general statement, not specific to this instance. > My second question is, should I expect different behaviors for the > compiler on different platforms? Yes. Different platforms have different ABIs and linking conventions, so differences are normal. Different platforms are different. > My final question is, which platform is correct? Is ARM correct and > the others incorrect; or is ARM incorrect and the others correct? You haven't shown how the template is instantiated, but I don't think using a typedef instead of the template parameter should affect anything here, so the ODR warning on ARM looks incorrect.