// rdar://18431336 void f6(void) { char b[5]; char buf[10]; __builtin___memccpy_chk (buf, b, '\0', sizeof(b), __builtin_object_size (buf, 0)); __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), __builtin_object_size (b, 0)); // expected-warning {{'__builtin___memccpy_chk' will always overflow; destination buffer has size 5, but size argument is 10}} }
void bar (void) { b = __builtin_object_size (0, 0); a = __builtin___stpcpy_chk (0, "", b); b = __builtin_object_size (a, 0); }
char * foo (char *r, int s) { r = __builtin___stpcpy_chk (r, "abc", __builtin_object_size (r, 1)); if (s) r = __builtin___stpcpy_chk (r, "d", __builtin_object_size (r, 1)); return r; }
test2 (void) { struct B { char buf1[10]; char buf2[10]; } a; char *r, buf3[20]; int i; if (sizeof (a) != 20) return; r = buf3; for (i = 0; i < 4; ++i) { if (i == l1 - 1) r = &a.buf1[1]; else if (i == l1) r = &a.buf2[7]; else if (i == l1 + 1) r = &buf3[5]; else if (i == l1 + 2) r = &a.buf1[9]; } if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 9) abort (); r = &buf3[20]; for (i = 0; i < 4; ++i) { if (i == l1 - 1) r = &a.buf1[7]; else if (i == l1) r = &a.buf2[7]; else if (i == l1 + 1) r = &buf3[5]; else if (i == l1 + 2) r = &a.buf1[9]; } if (__builtin_object_size (r, 3) != 0) abort (); r = &buf3[1]; for (i = 0; i < 4; ++i) { if (i == l1 - 1) r = &a.buf1[6]; else if (i == l1) r = &a.buf2[4]; else if (i == l1 + 1) r = &buf3[5]; else if (i == l1 + 2) r = &a.buf1[2]; } if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6) abort (); r += 2; if (__builtin_object_size (r, 3) != sizeof (a.buf1) - 6 - 2) abort (); if (__builtin_object_size (r + 1, 3) != sizeof (a.buf1) - 6 - 3) abort (); }
// CHECK: @test17 void test17() { // CHECK: store i32 -1 gi = __builtin_object_size(gp++, 0); // CHECK: store i32 -1 gi = __builtin_object_size(gp++, 1); // CHECK: store i32 0 gi = __builtin_object_size(gp++, 2); // CHECK: store i32 0 gi = __builtin_object_size(gp++, 3); }
void test1 (void) { char buf[8]; __builtin___mempcpy_chk (buf, data, l1 ? sizeof (buf) : 4, __builtin_object_size (buf, 0)); if (__builtin___memmove_chk (buf, data, l1 ? sizeof (buf) : 4, __builtin_object_size (buf, 0)) != buf) __builtin_abort (); }
// CHECK-LABEL: @test3 void test3() { char *const buf = (char *)my_calloc(100, 5); // CHECK: store i32 500 gi = __builtin_object_size(buf, 0); // CHECK: store i32 500 gi = __builtin_object_size(buf, 1); // CHECK: store i32 500 gi = __builtin_object_size(buf, 2); // CHECK: store i32 500 gi = __builtin_object_size(buf, 3); }
// CHECK-LABEL: @test7 void test7() { struct Data *const data = my_malloc(sizeof(*data) + 5); // CHECK: store i32 9 gi = __builtin_object_size(data->pad, 0); // CHECK: store i32 3 gi = __builtin_object_size(data->pad, 1); // CHECK: store i32 9 gi = __builtin_object_size(data->pad, 2); // CHECK: store i32 3 gi = __builtin_object_size(data->pad, 3); }
// CHECK-LABEL: @test8 void test8() { // Non-const pointers aren't currently supported. void *buf = my_calloc(100, 5); // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true) gi = __builtin_object_size(buf, 0); // CHECK: @llvm.objectsize gi = __builtin_object_size(buf, 1); // CHECK: @llvm.objectsize gi = __builtin_object_size(buf, 2); // CHECK: store i32 0 gi = __builtin_object_size(buf, 3); }
// CHECK-LABEL: @test2 void test2() { void *const vp = my_malloc(gi); // CHECK: @llvm.objectsize gi = __builtin_object_size(vp, 0); void *const arr1 = my_calloc(gi, 1); // CHECK: @llvm.objectsize gi = __builtin_object_size(arr1, 0); void *const arr2 = my_calloc(1, gi); // CHECK: @llvm.objectsize gi = __builtin_object_size(arr2, 0); }
// CHECK-LABEL: @test9 void test9() { // Check to be sure that we unwrap things correctly. short *const buf0 = (my_malloc(100)); short *const buf1 = (short*)(my_malloc(100)); short *const buf2 = ((short*)(my_malloc(100))); // CHECK: store i32 100 gi = __builtin_object_size(buf0, 0); // CHECK: store i32 100 gi = __builtin_object_size(buf1, 0); // CHECK: store i32 100 gi = __builtin_object_size(buf2, 0); }
// CHECK-LABEL: @test12 void test12() { // CHECK: store i32 100 gi = __builtin_object_size(my_signed_malloc(100), 0); // CHECK: store i32 500 gi = __builtin_object_size(my_signed_calloc(100, 5), 0); void *const vp = my_signed_malloc(-2); // CHECK: @llvm.objectsize gi = __builtin_object_size(vp, 0); // N.B. These get lowered to -1 because the function calls may have // side-effects, and we can't determine the objectsize. // CHECK: store i32 -1 gi = __builtin_object_size(my_signed_malloc(-2), 0); void *const arr1 = my_signed_calloc(-2, 1); void *const arr2 = my_signed_calloc(1, -2); // CHECK: @llvm.objectsize gi = __builtin_object_size(arr1, 0); // CHECK: @llvm.objectsize gi = __builtin_object_size(arr2, 0); // CHECK: store i32 -1 gi = __builtin_object_size(my_signed_calloc(1, -2), 0); // CHECK: store i32 -1 gi = __builtin_object_size(my_signed_calloc(-2, 1), 0); }
test2 (void) { struct B { char buf1[10]; char buf2[10]; } a; char *r, buf3[20]; int i; if (sizeof (a) != 20) return; r = buf3; for (i = 0; i < 4; ++i) { if (i == l1 - 1) r = &a.buf1[1]; else if (i == l1) r = &a.buf2[7]; else if (i == l1 + 1) r = &buf3[5]; else if (i == l1 + 2) r = &a.buf1[9]; } if (__builtin_object_size (r, 1) != sizeof (buf3)) abort (); r = &buf3[20]; for (i = 0; i < 4; ++i) { if (i == l1 - 1) r = &a.buf1[7]; else if (i == l1) r = &a.buf2[7]; else if (i == l1 + 1) r = &buf3[5]; else if (i == l1 + 2) r = &a.buf1[9]; } if (__builtin_object_size (r, 1) != sizeof (buf3) - 5) abort (); r += 8; if (__builtin_object_size (r, 1) != sizeof (buf3) - 13) abort (); if (__builtin_object_size (r + 6, 1) != sizeof (buf3) - 19) abort (); }
void test1 (size_t x) { char *p = &buf[8]; size_t i; for (i = 0; i < x; ++i) p = p + 4; if (__builtin_object_size (p, 0) != sizeof (buf) - 8) abort (); }
void test4 (size_t x) { char *p = &buf[8]; size_t i; for (i = 0; i < x; ++i) p = p + 4; if (__builtin_object_size (p, 3) != 0) abort (); }
int pr28314(void) { struct { struct InvalidField a; // expected-error{{has incomplete type}} expected-note 3{{forward declaration of 'struct InvalidField'}} char b[0]; } *p; struct { struct InvalidField a; // expected-error{{has incomplete type}} char b[1]; } *p2; struct { struct InvalidField a; // expected-error{{has incomplete type}} char b[2]; } *p3; int a = 0; a += __builtin_object_size(&p->a, 0); a += __builtin_object_size(p->b, 0); a += __builtin_object_size(p2->b, 0); a += __builtin_object_size(p3->b, 0); return a; }
inline void * foo (void *x, char *y, int z) { struct S s; char b[256]; s.s = b; s.z = __builtin___sprintf_chk (s.s, 1, __builtin_object_size (s.s, 2), "Require"); if (s.z < 0) bar (u.t | c->t, "rls"); if (foo (x, s.s, s.z)) { } return (void *) 0; }
// CHECK-LABEL: @test11 void test11() { void *const vp = my_tiny_malloc(100); // CHECK: store i32 100 gi = __builtin_object_size(vp, 0); // CHECK: store i32 100 gi = __builtin_object_size(vp, 1); // CHECK: store i32 100 gi = __builtin_object_size(vp, 2); // CHECK: store i32 100 gi = __builtin_object_size(vp, 3); // N.B. This causes char overflow, but not size_t overflow, so it should be // supported. void *const arr = my_tiny_calloc(100, 5); // CHECK: store i32 500 gi = __builtin_object_size(arr, 0); // CHECK: store i32 500 gi = __builtin_object_size(arr, 1); // CHECK: store i32 500 gi = __builtin_object_size(arr, 2); // CHECK: store i32 500 gi = __builtin_object_size(arr, 3); }
// PR c++/40502 // { dg-do compile } // { dg-options "-O2" } struct A { char x[12], y[35]; }; struct B { char z[50]; }; inline void foo (char *dest, const char *__restrict src, __SIZE_TYPE__ n) { __builtin___strncpy_chk (dest, src, n, __builtin_object_size (dest, 0)); // { dg-warning "will always overflow" } } void bar (const char *, int); inline void baz (int i) { char s[128], t[32]; bar (s, 0); bar (t, i); A a; B b; foo (a.y, b.z, 36); } void test () { baz (0); }
void * memset (void *x, int y, size_t z) { return __builtin___memset_chk (x, y, z, __builtin_object_size (x, 0)); }
unsigned t2(void *d) { return __builtin_object_size(d, 2); }
unsigned t1(void *d) { return __builtin_object_size(d, 0); }
unsigned t3() { return __builtin_object_size(buf, 0); }
int f1() { return (__builtin_object_size(&a, 0) + __builtin_object_size(&a, 1) + __builtin_object_size(&a, 2) + __builtin_object_size(&a, 3)); }
int f0() { return __builtin_object_size(&a); // expected-error {{too few arguments to function}} }
int f3() { return __builtin_object_size(&a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}} }
#endif open("path", O_CREAT, 0660); open("path", 0); open("path", 0, 0); } size_t __strnlen_chk(const char *s, size_t requested_amount, size_t s_len); size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}} __attribute__((overloadable)) __asm__("strnlen_real1"); __attribute__((always_inline)) inline size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function}} __attribute__((overloadable)) __attribute__((enable_if(__builtin_object_size(s, 0) != -1, "chosen when target buffer size is known"))) { return __strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); } size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate disabled: chosen when 'maxlen' is known to be less than or equal to the buffer size}} __attribute__((overloadable)) __attribute__((enable_if(__builtin_object_size(s, 0) != -1, "chosen when target buffer size is known"))) __attribute__((enable_if(maxlen <= __builtin_object_size(s, 0), "chosen when 'maxlen' is known to be less than or equal to the buffer size"))) __asm__("strnlen_real2"); size_t strnlen(const char *s, size_t maxlen) // expected-note{{candidate function has been explicitly made unavailable}} __attribute__((overloadable))
test3 (void) { char buf4[10]; struct B { struct A a[2]; struct A b; char c[4]; char d; double e; _Complex double f; } x; double y; _Complex double z; double *dp; if (__builtin_object_size (buf4, 1) != sizeof (buf4)) abort (); if (__builtin_object_size (&buf4, 1) != sizeof (buf4)) abort (); if (__builtin_object_size (&buf4[0], 1) != sizeof (buf4)) abort (); if (__builtin_object_size (&buf4[1], 1) != sizeof (buf4) - 1) abort (); if (__builtin_object_size (&x, 1) != sizeof (x)) abort (); if (__builtin_object_size (&x.a, 1) != sizeof (x.a)) abort (); if (__builtin_object_size (&x.a[0], 1) != sizeof (x.a)) abort (); if (__builtin_object_size (&x.a[0].a, 1) != sizeof (x.a[0].a)) abort (); if (__builtin_object_size (&x.a[0].a[0], 1) != sizeof (x.a[0].a)) abort (); if (__builtin_object_size (&x.a[0].a[3], 1) != sizeof (x.a[0].a) - 3) abort (); if (__builtin_object_size (&x.a[0].b, 1) != sizeof (x.a[0].b)) abort (); if (__builtin_object_size (&x.a[1].c, 1) != sizeof (x.a[1].c)) abort (); if (__builtin_object_size (&x.a[1].c[0], 1) != sizeof (x.a[1].c)) abort (); if (__builtin_object_size (&x.a[1].c[3], 1) != sizeof (x.a[1].c) - 3) abort (); if (__builtin_object_size (&x.b, 1) != sizeof (x.b)) abort (); if (__builtin_object_size (&x.b.a, 1) != sizeof (x.b.a)) abort (); if (__builtin_object_size (&x.b.a[0], 1) != sizeof (x.b.a)) abort (); if (__builtin_object_size (&x.b.a[3], 1) != sizeof (x.b.a) - 3) abort (); if (__builtin_object_size (&x.b.b, 1) != sizeof (x.b.b)) abort (); if (__builtin_object_size (&x.b.c, 1) != sizeof (x.b.c)) abort (); if (__builtin_object_size (&x.b.c[0], 1) != sizeof (x.b.c)) abort (); if (__builtin_object_size (&x.b.c[3], 1) != sizeof (x.b.c) - 3) abort (); if (__builtin_object_size (&x.c, 1) != sizeof (x.c)) abort (); if (__builtin_object_size (&x.c[0], 1) != sizeof (x.c)) abort (); if (__builtin_object_size (&x.c[1], 1) != sizeof (x.c) - 1) abort (); if (__builtin_object_size (&x.d, 1) != sizeof (x.d)) abort (); if (__builtin_object_size (&x.e, 1) != sizeof (x.e)) abort (); if (__builtin_object_size (&x.f, 1) != sizeof (x.f)) abort (); dp = &__real__ x.f; if (__builtin_object_size (dp, 1) != sizeof (x.f) / 2) abort (); dp = &__imag__ x.f; if (__builtin_object_size (dp, 1) != sizeof (x.f) / 2) abort (); dp = &y; if (__builtin_object_size (dp, 1) != sizeof (y)) abort (); if (__builtin_object_size (&z, 1) != sizeof (z)) abort (); dp = &__real__ z; if (__builtin_object_size (dp, 1) != sizeof (z) / 2) abort (); dp = &__imag__ z; if (__builtin_object_size (dp, 1) != sizeof (z) / 2) abort (); }
test1 (void *q, int x) { struct A a; void *p = &a.a[3], *r; char var[x + 10]; struct A vara[x + 10]; if (x < 0) r = &a.a[9]; else r = &a.c[1]; if (__builtin_object_size (p, 1) != sizeof (a.a) - 3) abort (); if (__builtin_object_size (&a.c[9], 1) != sizeof (a.c) - 9) abort (); if (__builtin_object_size (q, 1) != (size_t) -1) abort (); if (__builtin_object_size (r, 1) != sizeof (a.c) - 1) abort (); if (x < 6) r = &w[2].a[1]; else r = &a.a[6]; if (__builtin_object_size (&y, 1) != sizeof (y)) abort (); if (__builtin_object_size (w, 1) != sizeof (w)) abort (); if (__builtin_object_size (&y.b, 1) != sizeof (a.b)) abort (); if (__builtin_object_size (r, 1) != sizeof (a.a) - 1) abort (); if (x < 20) r = malloc (30); else r = calloc (2, 16); if (__builtin_object_size (r, 1) != 2 * 16) abort (); if (x < 20) r = malloc (30); else r = calloc (2, 14); if (__builtin_object_size (r, 1) != 30) abort (); if (x < 30) r = malloc (sizeof (a)); else r = &a.a[3]; if (__builtin_object_size (r, 1) != sizeof (a)) abort (); r = memcpy (r, "a", 2); if (__builtin_object_size (r, 1) != sizeof (a)) abort (); r = memcpy (r + 2, "b", 2) + 2; if (__builtin_object_size (r, 1) != sizeof (a) - 4) abort (); r = &a.a[4]; r = memset (r, 'a', 2); if (__builtin_object_size (r, 1) != sizeof (a.a) - 4) abort (); r = memset (r + 2, 'b', 2) + 2; if (__builtin_object_size (r, 1) != sizeof (a.a) - 8) abort (); r = &a.a[1]; r = strcpy (r, "ab"); if (__builtin_object_size (r, 1) != sizeof (a.a) - 1) abort (); r = strcpy (r + 2, "cd") + 2; if (__builtin_object_size (r, 1) != sizeof (a.a) - 5) abort (); if (__builtin_object_size (exta, 1) != (size_t) -1) abort (); if (__builtin_object_size (exta + 10, 1) != (size_t) -1) abort (); if (__builtin_object_size (&exta[5], 1) != (size_t) -1) abort (); if (__builtin_object_size (extb, 1) != sizeof (extb)) abort (); if (__builtin_object_size (extb + 10, 1) != sizeof (extb) - 10) abort (); if (__builtin_object_size (&extb[5], 1) != sizeof (extb) - 5) abort (); if (__builtin_object_size (extc, 1) != (size_t) -1) abort (); if (__builtin_object_size (extc + 10, 1) != (size_t) -1) abort (); if (__builtin_object_size (&extc[5], 1) != (size_t) -1) abort (); if (__builtin_object_size (&extc->a, 1) != (size_t) -1) abort (); if (__builtin_object_size (&(extc + 10)->b, 1) != (size_t) -1) abort (); if (__builtin_object_size (&extc[5].c[3], 1) != (size_t) -1) abort (); if (__builtin_object_size (var, 1) != (size_t) -1) abort (); if (__builtin_object_size (var + 10, 1) != (size_t) -1) abort (); if (__builtin_object_size (&var[5], 1) != (size_t) -1) abort (); if (__builtin_object_size (vara, 1) != (size_t) -1) abort (); if (__builtin_object_size (vara + 10, 1) != (size_t) -1) abort (); if (__builtin_object_size (&vara[5], 1) != (size_t) -1) abort (); if (__builtin_object_size (&vara[0].a, 1) != sizeof (vara[0].a)) abort (); if (__builtin_object_size (&vara[10].a[0], 1) != sizeof (vara[0].a)) abort (); if (__builtin_object_size (&vara[5].a[4], 1) != sizeof (vara[0].a) - 4) abort (); if (__builtin_object_size (&vara[5].b, 1) != sizeof (vara[0].b)) abort (); if (__builtin_object_size (&vara[7].c[7], 1) != sizeof (vara[0].c) - 7) abort (); if (__builtin_object_size (zerol, 1) != 0) abort (); if (__builtin_object_size (&zerol, 1) != 0) abort (); if (__builtin_object_size (&zerol[0], 1) != 0) abort (); if (__builtin_object_size (zerol[0].a, 1) != 0) abort (); if (__builtin_object_size (&zerol[0].a[0], 1) != 0) abort (); if (__builtin_object_size (&zerol[0].b, 1) != 0) abort (); if (__builtin_object_size ("abcdefg", 1) != sizeof ("abcdefg")) abort (); if (__builtin_object_size ("abcd\0efg", 1) != sizeof ("abcd\0efg")) abort (); if (__builtin_object_size (&"abcd\0efg", 1) != sizeof ("abcd\0efg")) abort (); if (__builtin_object_size (&"abcd\0efg"[0], 1) != sizeof ("abcd\0efg")) abort (); if (__builtin_object_size (&"abcd\0efg"[4], 1) != sizeof ("abcd\0efg") - 4) abort (); if (__builtin_object_size ("abcd\0efg" + 5, 1) != sizeof ("abcd\0efg") - 5) abort (); if (__builtin_object_size (L"abcdefg", 1) != sizeof (L"abcdefg")) abort (); r = (char *) L"abcd\0efg"; if (__builtin_object_size (r + 2, 1) != sizeof (L"abcd\0efg") - 2) abort (); }
static char *__inline_strcpy_chk (char *dest, const char *src) { return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1)); }