[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-sparse
Subject:    sparse infinitely loops on =?koi8-r?Q?=22?=*a++=?koi8-r?Q?=22?=
From:       Alexey Dobriyan <adobriyan () mail ! ru>
Date:       2004-11-29 19:17:17
Message-ID: E1CYr1R-000Bvd-00.adobriyan-mail-ru () f32 ! mail ! ru
[Download RAW message or body]

Fed gcc 3.4 testsuite to sparse. On some tests it starts infinitely looping. Cut
down one of them to very minimal:
==================================================
void f(void)
{
        int *a;

        *a++;	/*
		  *(a = a + 1); also infinite loop
		  *(b = a + 1); -- ok
		 */
}
==================================================

Starting from 1.1023 this test would trigger the following assertion:

$ ./check ../sparse-crash/t1_infinite.c
check: simplify.c:154: remove_usage: Assertion `deleted == 1' failed.
Aborted

Starting from 1.1038 failed assertion transformed to infinite loop due to
changes in delete_ptr_list_entry.

============================================================================
--- 1.1022/simplify.c     2004-11-27 06:25:30 +00:00
+++ 1.1023/simplify.c     2004-11-27 06:26:44 +00:00
@@ -409,6 +409,8 @@
 static int simplify_memop(struct instruction *insn)
 {
        pseudo_t addr = insn->src;
+       pseudo_t new, off;
+
        if (addr->type == PSEUDO_REG) {
                struct instruction *def = addr->def;
                if (def->opcode == OP_SETVAL && def->src) {
@@ -416,8 +418,25 @@
                        use_pseudo(def->src, &insn->src);
                        return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
                }
+               if (def->opcode == OP_ADD) {
+                       new = def->src1;
+                       off = def->src2;
+                       if (constant(off))
+                               goto offset;
+                       new = off;
+                       off = def->src1;
+                       if (constant(off))
+                               goto offset;
+                       return 0;
+               }
        }
        return 0;
+
+offset:
+       insn->offset += off->value;
+       use_pseudo(new, &insn->src);
+       remove_usage(addr, &insn->src);
+       return REPEAT_CSE | REPEAT_SYMBOL_CLEANUP;
 }

 int simplify_instruction(struct instruction *insn)
============================================================================

After "if (... == OP_ADD)" "new" and "addr" are the same. The we add pseudo,
next line remove it, and finally set right flags for cleanup_and_cse to call
all chain once again (well, that's how I understood pseudo tricks).

#0    simplify_memop		at simplify.c:431
#1 in simplify_instruction	at simplify.c:467
#2 in clean_up_one_instruction	at cse.c:47
#3 in clean_up_insns		at cse.c:120
#4 in cleanup_and_cse		at cse.c:325

Any thoughts on how to fix this?

	Alexey

-
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic