[Bug c++/89698] [7/8/9 Regression] Run-time error due to optimization of field access after cast at -Os/-O2 and higher

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Wed Mar 13 10:34:00 GMT 2019


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89698

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
So the issue may be that

operand_equal_p (*(struct A *) VIEW_CONVERT_EXPR<void *>(vp),
                 *(struct B *) VIEW_CONVERT_EXPR<void *>(vp), 0) == 1

where for INDIRECT_REF we just do

        case INDIRECT_REF:
          if (!(flags & OEP_ADDRESS_OF)
              && (TYPE_ALIGN (TREE_TYPE (arg0))
                  != TYPE_ALIGN (TREE_TYPE (arg1))))
            return 0;
          flags &= ~OEP_ADDRESS_OF;
          return OP_SAME (0);

and OP_SAME happily strips the pointer nop-conversion.  For MEM_REF we do

        case MEM_REF:
          if (!(flags & OEP_ADDRESS_OF))
            {
...
              /* Verify that access happens in similar types.  */
              if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)))
                return 0;
              /* Verify that accesses are TBAA compatible.  */
              if (!alias_ptr_types_compatible_p
                    (TREE_TYPE (TREE_OPERAND (arg0, 1)),
                     TREE_TYPE (TREE_OPERAND (arg1, 1)))
                  || (MR_DEPENDENCE_CLIQUE (arg0)
                      != MR_DEPENDENCE_CLIQUE (arg1))
                  || (MR_DEPENDENCE_BASE (arg0)
                      != MR_DEPENDENCE_BASE (arg1)))
                return 0;

so even a basic check that the dereferences access compatible types would
fix this.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 269641)
+++ gcc/fold-const.c    (working copy)
@@ -3220,10 +3220,16 @@ operand_equal_p (const_tree arg0, const_
       switch (TREE_CODE (arg0))
        {
        case INDIRECT_REF:
-         if (!(flags & OEP_ADDRESS_OF)
-             && (TYPE_ALIGN (TREE_TYPE (arg0))
-                 != TYPE_ALIGN (TREE_TYPE (arg1))))
-           return 0;
+         if (!(flags & OEP_ADDRESS_OF))
+           {
+             if (TYPE_ALIGN (TREE_TYPE (arg0))
+                 != TYPE_ALIGN (TREE_TYPE (arg1)))
+               return 0;
+             /* Verify that the access types are compatible.  */
+             if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0))
+                 != TYPE_MAIN_VARIANT (TREE_TYPE (arg1)))
+               return 0;
+           }
          flags &= ~OEP_ADDRESS_OF;
          return OP_SAME (0);


More information about the Gcc-bugs mailing list