Viewing file: 20000906-1.c (1.76 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* { dg-do run } */
/* Testcase distilled from glibc's nss_parse_service_list in nss/nsswitch.c It can't be distilled further. Fails with `-O2' for i[3456]86. */
/* this simulates a bounded-pointer type. */ struct ucharp { unsigned char *v, *l, *h; };
/* this simulates bounded-pointer check prior to pointer dereference. */ #define AREF(var, idx) ((((((((var).v+(idx)) < (var).l) \ || (((var).v+(idx)+1) > (var).h))) \ && (__builtin_trap (), 0)), \ (var).v)[(idx)])
struct list { struct list *next; };
struct list * alloc_list (void) { static struct list l; return &l; }
int one = 1;
void foo (struct ucharp cp, struct ucharp lp, struct list **nextp) { while (1) { struct list *list; while (AREF (lp, 0) && AREF (cp, AREF (lp, 0))) ++lp.v; list = alloc_list (); while (AREF (cp, AREF (lp, 0))) ++lp.v; if (AREF (lp, 0) == one) do ++lp.v; while (AREF (lp, 0) && AREF (cp, AREF (lp, 0))); /* The above AREF (cp, ...) fails because the pseudo created to hold cp.v holds garbage, having never been set. The easiest way to see the problem is to compile wiht `-O2 -da' then look at *.09.loop. Search for something like this:
Hoisted regno 183 r/o from (mem/s:SI (reg:SI 16 argp) 10) Replaced reg 91, deleting init_insn (213).
Now, look for the use of reg 91, which has no set. */
*nextp = list; nextp = &list->next; if (!*lp.v) break; } }
extern void exit (int);
int main (void) { static unsigned char cp0[] = "\0\0\0\0"; struct ucharp cp = { cp0, cp0, cp0 + sizeof (cp0) };
static unsigned char lp0[] = "\1\1\0\0"; struct ucharp lp = { lp0, lp0, lp0 + sizeof (lp0) };
struct list list; struct list *nextp = &list;
foo (cp, lp, &nextp);
exit (0); }
|