> Hi.
> 
> The patch is attempt to fix ICE which I see in ODR violation warning.
> I think the proper fix is to use TYPE_MAIN_VARIANT(t1) instead of t1
> in the problematic condition.
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin
> 
> gcc/ChangeLog:
> 
> 2019-11-27  Martin Liska  <mli...@suse.cz>
> 
>       PR lto/92609
>       * ipa-devirt.c (warn_types_mismatch): Use TYPE_MAIN_VARIANT
>       consistently.
> 
> gcc/testsuite/ChangeLog:
> 
> 2019-11-27  Martin Liska  <mli...@suse.cz>
> 
>       PR lto/92609
>       * g++.dg/lto/pr92609_0.C: New test.
>       * g++.dg/lto/pr92609_1.C: New test.
OK,
thanks!
Honza
> ---
>  gcc/ipa-devirt.c                     | 25 ++++----
>  gcc/testsuite/g++.dg/lto/pr92609_0.C | 88 ++++++++++++++++++++++++++++
>  gcc/testsuite/g++.dg/lto/pr92609_1.C | 58 ++++++++++++++++++
>  3 files changed, 159 insertions(+), 12 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/lto/pr92609_0.C
>  create mode 100644 gcc/testsuite/g++.dg/lto/pr92609_1.C
> 
> 

> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
> index c158d3c968d..0b2475ca292 100644
> --- a/gcc/ipa-devirt.c
> +++ b/gcc/ipa-devirt.c
> @@ -986,21 +986,24 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, 
> location_t loc2)
>  
>    /* It is a quite common bug to reference anonymous namespace type in
>       non-anonymous namespace class.  */
> -  if ((type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
> -       && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
> -      || (type_with_linkage_p (TYPE_MAIN_VARIANT (t2))
> -       && type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t2))))
> +  tree mt1 = TYPE_MAIN_VARIANT (t1);
> +  tree mt2 = TYPE_MAIN_VARIANT (t2);
> +  if ((type_with_linkage_p (mt1)
> +       && type_in_anonymous_namespace_p (mt1))
> +      || (type_with_linkage_p (mt2)
> +       && type_in_anonymous_namespace_p (mt2)))
>      {
> -      if (!type_with_linkage_p (TYPE_MAIN_VARIANT (t1))
> -       || !type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t1)))
> +      if (!type_with_linkage_p (mt1)
> +       || !type_in_anonymous_namespace_p (mt1))
>       {
>         std::swap (t1, t2);
> +       std::swap (mt1, mt2);
>         std::swap (loc_t1, loc_t2);
>       }
> -      gcc_assert (TYPE_NAME (t1)
> -               && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL);
> -      tree n1 = TYPE_NAME (t1);
> -      tree n2 = TYPE_NAME (t2) ? TYPE_NAME (t2) : NULL;
> +      gcc_assert (TYPE_NAME (mt1)
> +               && TREE_CODE (TYPE_NAME (mt1)) == TYPE_DECL);
> +      tree n1 = TYPE_NAME (mt1);
> +      tree n2 = TYPE_NAME (mt2) ? TYPE_NAME (mt2) : NULL;
>  
>        if (TREE_CODE (n1) == TYPE_DECL)
>       n1 = DECL_NAME (n1);
> @@ -1023,8 +1026,6 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, 
> location_t loc2)
>               "the incompatible type defined in another translation unit");
>        return;
>      }
> -  tree mt1 = TYPE_MAIN_VARIANT (t1);
> -  tree mt2 = TYPE_MAIN_VARIANT (t2);
>    /* If types have mangled ODR names and they are different, it is most
>       informative to output those.
>       This also covers types defined in different namespaces.  */
> diff --git a/gcc/testsuite/g++.dg/lto/pr92609_0.C 
> b/gcc/testsuite/g++.dg/lto/pr92609_0.C
> new file mode 100644
> index 00000000000..3cce1811d1e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/lto/pr92609_0.C
> @@ -0,0 +1,88 @@
> +// PR lto/92609
> +// { dg-lto-do link }
> +// { dg-lto-options { { -fPIC -flto } } }
> +// { dg-require-effective-target shared }
> +// { dg-require-effective-target fpic }
> +// { dg-extra-ld-options "-shared" }
> +
> +namespace std {
> +inline namespace __cxx11 {}
> +template < typename _Default > struct __detector { using type = _Default; };
> +template < typename _Default, template < typename > class >
> +using __detected_or = __detector< _Default >;
> +template < typename _Default, template < typename > class _Op >
> +using __detected_or_t = typename __detected_or< _Default, _Op >::type;
> +template < typename > class allocator;
> +template < class > struct char_traits;
> +namespace __cxx11 {
> +template < typename _CharT, typename = char_traits< _CharT >,
> +           typename = allocator< _CharT > >
> +class basic_string;
> +}
> +struct __allocator_traits_base {
> +  template < typename _Tp > using __pointer = typename _Tp::pointer;
> +};
> +struct allocator_traits : __allocator_traits_base {
> +  using pointer = __detected_or_t< char *, __pointer >;
> +};
> +} // std
> +struct rebind {
> +  typedef std::allocator_traits other;
> +};
> +namespace std {
> +namespace __cxx11 {
> +template < typename, typename, typename > class basic_string {
> +  struct _Alloc_hider {
> +    rebind::other::pointer _M_p;
> +  } _M_dataplus;
> +  unsigned long _M_string_length;
> +  enum { _S_local_capacity = 15 };
> +  union {
> +    char _M_local_buf[_S_local_capacity + 1];
> +    unsigned long _M_allocated_capacity;
> +  };
> +};
> +} // __cxx11
> +template < typename _Tp > class __uniq_ptr_impl {
> +  template < typename _Up > struct _Ptr { using type = _Up *; };
> +
> +public:
> +  using pointer = typename _Ptr< _Tp >::type;
> +};
> +template < typename _Tp > class unique_ptr {
> +public:
> +  using pointer = typename __uniq_ptr_impl< _Tp >::pointer;
> +  unique_ptr(pointer);
> +};
> +} // std
> +class wxRefCounter;
> +class wxObject {
> +  virtual wxRefCounter CreateRefData();
> +  wxRefCounter *m_refData;
> +};
> +class wxGDIObject : wxObject {};
> +class wxFontBase : wxGDIObject {};
> +class wxFont : wxFontBase {};
> +class VisualTool {
> +protected:
> +  VisualTool(int *, int *);
> +};
> +class OpenGLText;
> +class VisualToolCross : VisualTool {
> +  std::unique_ptr< OpenGLText > gl_text;
> +  VisualToolCross();
> +};
> +class OpenGLText { // { dg-lto-warning "7: type 'struct OpenGLText' violates 
> the C\\+\\+ One Definition Rule" }
> +  float r, g, b, a;
> +  int fontSize;
> +  bool fontBold;
> +  bool fontItalics;
> +  std::basic_string< char > fontFace;
> +  wxFont font;
> +  int glyphs;
> +};
> +int VisualToolCross_parent;
> +int VisualToolCross_context;
> +VisualToolCross::VisualToolCross()
> +    : VisualTool(&VisualToolCross_parent, &VisualToolCross_context),
> +      gl_text(0) {}
> diff --git a/gcc/testsuite/g++.dg/lto/pr92609_1.C 
> b/gcc/testsuite/g++.dg/lto/pr92609_1.C
> new file mode 100644
> index 00000000000..4c65a6a4600
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/lto/pr92609_1.C
> @@ -0,0 +1,58 @@
> +namespace std {
> +inline namespace __cxx11 {}
> +template < typename _Default > struct __detector { using type = _Default; };
> +template < typename _Default, template < typename > class >
> +using __detected_or = __detector< _Default >;
> +template < typename _Default, template < typename > class _Op >
> +using __detected_or_t = typename __detected_or< _Default, _Op >::type;
> +template < typename > class allocator;
> +template < class > struct char_traits;
> +namespace __cxx11 {
> +template < typename _CharT, typename = char_traits< _CharT >,
> +           typename = allocator< _CharT > >
> +class basic_string;
> +}
> +struct __allocator_traits_base {
> +  template < typename _Tp > using __pointer = typename _Tp::pointer;
> +};
> +struct allocator_traits : __allocator_traits_base {
> +  using pointer = __detected_or_t< char *, __pointer >;
> +};
> +namespace __cxx11 {
> +template < typename, typename, typename > class basic_string {
> +  struct _Alloc_hider {
> +    allocator_traits::pointer _M_p;
> +  } _M_dataplus;
> +  unsigned long _M_string_length;
> +  enum { _S_local_capacity = 15 };
> +  union {
> +    char _M_local_buf[_S_local_capacity + 1];
> +    unsigned long _M_allocated_capacity;
> +  };
> +};
> +} // __cxx11
> +} // std
> +class wxRefCounter;
> +class wxObject {
> +  virtual int GetClassInfo();
> +  wxRefCounter *m_refData;
> +};
> +class wxGDIObject : wxObject {};
> +class wxFontBase : wxGDIObject {};
> +class wxFont : wxFontBase {};
> +template < class > class map {};
> +namespace {
> +struct OpenGLTextGlyph;
> +}
> +typedef map< OpenGLTextGlyph > glyphMap;
> +class OpenGLText {
> +  float r, g, b, a;
> +  int fontSize;
> +  bool fontBold;
> +  bool fontItalics;
> +  std::basic_string< char > fontFace;
> +  wxFont font;
> +  glyphMap glyphs;
> +  OpenGLText();
> +};
> +OpenGLText::OpenGLText() {}
> 

Reply via email to