flags &= ~OEP_ADDRESS_OF;
return OP_SAME (0);
- case REALPART_EXPR:
case IMAGPART_EXPR:
+ /* Require the same offset. */
+ if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
+ TYPE_SIZE (TREE_TYPE (arg1)),
+ flags & ~OEP_ADDRESS_OF))
+ return 0;
+
+ /* Fallthru. */
+ case REALPART_EXPR:
case VIEW_CONVERT_EXPR:
return OP_SAME (0);
case ARRAY_REF:
case ARRAY_RANGE_REF:
- /* Operands 2 and 3 may be null.
- Compare the array index by value if it is constant first as we
- may have different types but same value here. */
if (!OP_SAME (0))
return 0;
flags &= ~OEP_ADDRESS_OF;
+ /* Compare the array index by value if it is constant first as we
+ may have different types but same value here. */
return ((tree_int_cst_equal (TREE_OPERAND (arg0, 1),
TREE_OPERAND (arg1, 1))
|| OP_SAME (1))
&& OP_SAME_WITH_NULL (2)
- && OP_SAME_WITH_NULL (3));
+ && OP_SAME_WITH_NULL (3)
+ /* Compare low bound and element size as with OEP_ADDRESS_OF
+ we have to account for the offset of the ref. */
+ && (TREE_TYPE (TREE_OPERAND (arg0, 0))
+ == TREE_TYPE (TREE_OPERAND (arg1, 0))
+ || (operand_equal_p (array_ref_low_bound
+ (CONST_CAST_TREE (arg0)),
+ array_ref_low_bound
+ (CONST_CAST_TREE (arg1)), flags)
+ && operand_equal_p (array_ref_element_size
+ (CONST_CAST_TREE (arg0)),
+ array_ref_element_size
+ (CONST_CAST_TREE (arg1)),
+ flags))));
case COMPONENT_REF:
/* Handle operand 2 the same as for ARRAY_REF. Operand 0
--- /dev/null
+// { dg-do run }
+template <typename _Tp, long _Nm> struct A {
+ typedef _Tp _Type[_Nm];
+ static _Tp &_S_ref(const _Type &p1, int p2) {
+ return const_cast<_Tp &>(p1[p2]);
+ }
+};
+template <typename _Tp, long _Nm> struct B {
+ typedef A<_Tp, _Nm> _AT_Type;
+ typename _AT_Type::_Type _M_elems;
+ _Tp &operator[](long p1) const { return _AT_Type::_S_ref(_M_elems, p1); }
+};
+int t;
+void foo(int p1, int &p2) {
+ if ((t & 1) == 0) {
+ if (p1 != 1)
+ __builtin_abort();
+ if (p2 != 2)
+ __builtin_abort();
+ }
+ t++;
+}
+__attribute__((noinline))
+ void test1(const B<int, 2> &p1) { foo(p1[0], p1[1]); }
+ void test(B<B<int, 2>, 2> &p1) {
+ test1(p1[0]);
+ test1(p1[1]);
+ foo(p1[0][0], p1[0][1]);
+ }
+int main() {
+ B<B<int, 2>, 2> t;
+ t[0][0] = 1;
+ t[0][1] = 2;
+ test(t);
+}