http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57385

            Bug ID: 57385
           Summary: [tree-ssa] Possible segfault in
                    fully_constant_vn_reference_p
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: aivchenk at gmail dot com
                CC: aivchenk at gmail dot com

The following code crashes android ndk gcc-4.6 on 64 bit windows with segfault 
on at least -O1:

int c;

void foo(int f)
{
    int wbi=-1;
    c = (f ? "012346000000000000":"01345:000000006008")[wbi];
}

However, potentially it can appear on trunk as well: the reason for this is
that in fully_constant_vn_reference_p we have a bound violation:

1303|       if (arg0->opcode == STRING_CST
1304|           && (TYPE_MODE (op->type)
1305|               == TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0->op0))))
1306|           && GET_MODE_CLASS (TYPE_MODE (op->type)) == MODE_INT
1307|           && GET_MODE_SIZE (TYPE_MODE (op->type)) == 1
1308|           && compare_tree_int (op->op0, TREE_STRING_LENGTH (arg0->op0)) <
0)
1309|         return build_int_cst_type (op->type,
1310+>                                   (TREE_STRING_POINTER (arg0->op0)
1311|                                     [TREE_INT_CST_LOW (op->op0)]));

here the TREE_INT_CST_LOW (op->op0) is 0xffffffff ("wbi" from the code snippet
above and int_cst.low is unsigned). but here:

1308|           && compare_tree_int (op->op0, TREE_STRING_LENGTH (arg0->op0)) <
0)

compare_tree_int thinks that op->op0 equals to "-1" and so the check for bound
violation passes.

I think we need to add another check that op->op0 is not less than zero here.

Reply via email to