1 /* Test to verify that a strlen() call with a pointer to a dynamic type 2 doesn't make assumptions based on the static type of the original 3 pointer. See g++.dg/init/strlen.C for the corresponding C++ test. */ 4 5 struct A { int i; char a[1]; void (*p)(); }; 6 struct B { char a[sizeof (struct A) - __builtin_offsetof (struct A, a)]; }; 7 8 __attribute__ ((noipa)) void init(char * d,const char * s)9init (char *d, const char *s) 10 { 11 __builtin_strcpy (d, s); 12 } 13 14 struct B b; 15 16 __attribute__ ((noipa)) void test_dynamic_type(struct A * p)17test_dynamic_type (struct A *p) 18 { 19 /* The following call is undefined because it writes past the end 20 of the p->a subobject, but the corresponding GIMPLE considers 21 it valid and there's apparently no way to distinguish invalid 22 cases from ones like it that might be valid. If/when GIMPLE 23 changes to make this possible this test can be removed. */ 24 char *q = (char*)__builtin_memcpy (p->a, &b, sizeof b); 25 26 init (q, "foobar"); 27 28 if (6 != __builtin_strlen (q)) 29 __builtin_abort(); 30 } 31 main(void)32int main (void) 33 { 34 struct A *p = (struct A*)__builtin_malloc (sizeof *p); 35 test_dynamic_type (p); 36 return 0; 37 } 38