From: Siddhesh Poyarekar <siddhesh@gotplt.org>
To: Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
Cc: gcc-patches@gcc.gnu.org, jakub@redhat.com
Subject: Re: [PATCH v2] tree-object-size: Support strndup and strdup
Date: Fri, 4 Nov 2022 09:47:29 -0400 [thread overview]
Message-ID: <0519cbc0-31f4-5ae2-0e44-cef59a563a49@gotplt.org> (raw)
In-Reply-To: <CAAgBjMmcHQt8uhZSvWKE18_yVRYwE8sCM_Yg0Eb4a4v1XDRx0Q@mail.gmail.com>
On 2022-11-04 09:43, Prathamesh Kulkarni wrote:
> On Fri, 4 Nov 2022 at 18:18, Siddhesh Poyarekar <siddhesh@gotplt.org> wrote:
>>
>> Use string length of input to strdup to determine the usable size of the
>> resulting object. Avoid doing the same for strndup since there's a
>> chance that the input may be too large, resulting in an unnecessary
>> overhead or worse, the input may not be NULL terminated, resulting in a
>> crash where there would otherwise have been none.
>>
>> gcc/ChangeLog:
>>
>> * tree-object-size.cc (todo): New variable.
>> (object_sizes_execute): Use it.
>> (strdup_object_size): New function.
>> (call_object_size): Use it.
>>
>> gcc/testsuite/ChangeLog:
>>
>> * gcc.dg/builtin-dynamic-object-size-0.c (test_strdup,
>> test_strndup, test_strdup_min, test_strndup_min): New tests.
>> (main): Call them.
>> * gcc.dg/builtin-dynamic-object-size-1.c: Silence overread
>> warnings.
>> * gcc.dg/builtin-dynamic-object-size-2.c: Likewise.
>> * gcc.dg/builtin-dynamic-object-size-3.c: Likewise.
>> * gcc.dg/builtin-dynamic-object-size-4.c: Likewise.
>> * gcc.dg/builtin-object-size-1.c: Silence overread warnings.
>> Declare free, strdup and strndup.
>> (test11): New test.
>> (main): Call it.
>> * gcc.dg/builtin-object-size-2.c: Silence overread warnings.
>> Declare free, strdup and strndup.
>> (test9): New test.
>> (main): Call it.
>> * gcc.dg/builtin-object-size-3.c: Silence overread warnings.
>> Declare free, strdup and strndup.
>> (test11): New test.
>> (main): Call it.
>> * gcc.dg/builtin-object-size-4.c: Silence overread warnings.
>> Declare free, strdup and strndup.
>> (test9): New test.
>> (main): Call it.
>> ---
>> Tested:
>>
>> - x86_64 bootstrap and testsuite run
>> - i686 build and testsuite run
>> - ubsan bootstrap
>>
>> .../gcc.dg/builtin-dynamic-object-size-0.c | 43 +++++++++
>> .../gcc.dg/builtin-dynamic-object-size-1.c | 2 +-
>> .../gcc.dg/builtin-dynamic-object-size-2.c | 2 +-
>> .../gcc.dg/builtin-dynamic-object-size-3.c | 2 +-
>> .../gcc.dg/builtin-dynamic-object-size-4.c | 2 +-
>> gcc/testsuite/gcc.dg/builtin-object-size-1.c | 94 +++++++++++++++++-
>> gcc/testsuite/gcc.dg/builtin-object-size-2.c | 94 +++++++++++++++++-
>> gcc/testsuite/gcc.dg/builtin-object-size-3.c | 95 ++++++++++++++++++-
>> gcc/testsuite/gcc.dg/builtin-object-size-4.c | 94 +++++++++++++++++-
>> gcc/tree-object-size.cc | 84 +++++++++++++++-
>> 10 files changed, 502 insertions(+), 10 deletions(-)
>>
>> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
>> index 01a280b2d7b..4f1606a486b 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
>> @@ -479,6 +479,40 @@ test_loop (int *obj, size_t sz, size_t start, size_t end, int incr)
>> return __builtin_dynamic_object_size (ptr, 0);
>> }
>>
>> +/* strdup/strndup. */
>> +
>> +size_t
>> +__attribute__ ((noinline))
>> +test_strdup (const char *in)
>> +{
>> + char *res = __builtin_strdup (in);
>> + return __builtin_dynamic_object_size (res, 0);
>> +}
>> +
>> +size_t
>> +__attribute__ ((noinline))
>> +test_strndup (const char *in, size_t bound)
>> +{
>> + char *res = __builtin_strndup (in, bound);
>> + return __builtin_dynamic_object_size (res, 0);
>> +}
>> +
>> +size_t
>> +__attribute__ ((noinline))
>> +test_strdup_min (const char *in)
>> +{
>> + char *res = __builtin_strdup (in);
>> + return __builtin_dynamic_object_size (res, 2);
>> +}
>> +
>> +size_t
>> +__attribute__ ((noinline))
>> +test_strndup_min (const char *in, size_t bound)
>> +{
>> + char *res = __builtin_strndup (in, bound);
>> + return __builtin_dynamic_object_size (res, 2);
>> +}
>> +
>> /* Other tests. */
>>
>> struct TV4
>> @@ -651,6 +685,15 @@ main (int argc, char **argv)
>> int *t = test_pr105736 (&val3);
>> if (__builtin_dynamic_object_size (t, 0) != -1)
>> FAIL ();
>> + const char *str = "hello world";
>> + if (test_strdup (str) != __builtin_strlen (str) + 1)
>> + FAIL ();
>> + if (test_strndup (str, 4) != 5)
>> + FAIL ();
>> + if (test_strdup_min (str) != __builtin_strlen (str) + 1)
>> + FAIL ();
>> + if (test_strndup_min (str, 4) != 1)
>> + FAIL ();
>>
>> if (nfails > 0)
>> __builtin_abort ();
>> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
>> index 7cc8b1c9488..8f17c8edcaf 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> #define __builtin_object_size __builtin_dynamic_object_size
>> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
>> index 267dbf48ca7..3677782ff1c 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> #define __builtin_object_size __builtin_dynamic_object_size
>> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
>> index fb9dc56da7e..5b6987b7773 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> #define __builtin_object_size __builtin_dynamic_object_size
>> diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
>> index 870548b4206..9d796224e96 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> #define __builtin_object_size __builtin_dynamic_object_size
>> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
>> index b772e2da9b9..c6e5b4c29f8 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> typedef __SIZE_TYPE__ size_t;
>> @@ -7,10 +7,13 @@ extern void abort (void);
>> extern void exit (int);
>> extern void *malloc (size_t);
>> extern void *calloc (size_t, size_t);
>> +extern void free (void *);
>> extern void *alloca (size_t);
>> extern void *memcpy (void *, const void *, size_t);
>> extern void *memset (void *, int, size_t);
>> extern char *strcpy (char *, const char *);
>> +extern char *strdup (const char *);
>> +extern char *strndup (const char *, size_t);
>>
>> struct A
>> {
>> @@ -629,6 +632,94 @@ test10 (void)
>> }
>> }
>>
>> +/* Tests for strdup/strndup. */
>> +size_t
>> +__attribute__ ((noinline))
>> +test11 (void)
>> +{
>> + int i = 0;
>> + const char *ptr = "abcdefghijklmnopqrstuvwxyz";
>> + char *res = strndup (ptr, 21);
>> + if (__builtin_object_size (res, 0) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr, 32);
>> + if (__builtin_object_size (res, 0) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 0) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + char *ptr2 = malloc (64);
>> + strcpy (ptr2, ptr);
>> +
>> + res = strndup (ptr2, 21);
>> + if (__builtin_object_size (res, 0) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 32);
>> + if (__builtin_object_size (res, 0) != 33)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 128);
>> + if (__builtin_object_size (res, 0) != 64)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr2);
>> +#ifdef __builtin_object_size
>> + if (__builtin_object_size (res, 0) != 27)
>> +#else
>> + if (__builtin_object_size (res, 0) != (size_t) -1)
>> +#endif
>> + abort ();
>> + free (res);
>> + free (ptr2);
>> +
>> + ptr = "abcd\0efghijklmnopqrstuvwxyz";
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 0) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 24);
>> + if (__builtin_object_size (res, 0) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 2);
>> + if (__builtin_object_size (res, 0) != 3)
>> + abort ();
>> + free (res);
>> +
>> + res = strdup (&ptr[4]);
>> + if (__builtin_object_size (res, 0) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 4);
>> + if (__builtin_object_size (res, 0) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 1);
>> + if (__builtin_object_size (res, 0) != 1)
>> + abort ();
>> + free (res);
>> +}
>> +
>> int
>> main (void)
>> {
>> @@ -644,5 +735,6 @@ main (void)
>> test8 ();
>> test9 (1);
>> test10 ();
>> + test11 ();
>> exit (0);
>> }
>> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
>> index 2729538da17..639a83cfd39 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> typedef __SIZE_TYPE__ size_t;
>> @@ -7,10 +7,13 @@ extern void abort (void);
>> extern void exit (int);
>> extern void *malloc (size_t);
>> extern void *calloc (size_t, size_t);
>> +extern void free (void *);
>> extern void *alloca (size_t);
>> extern void *memcpy (void *, const void *, size_t);
>> extern void *memset (void *, int, size_t);
>> extern char *strcpy (char *, const char *);
>> +extern char *strdup (const char *);
>> +extern char *strndup (const char *, size_t);
>>
>> struct A
>> {
>> @@ -544,6 +547,94 @@ test8 (unsigned cond)
>> #endif
>> }
>>
>> +/* Tests for strdup/strndup. */
>> +size_t
>> +__attribute__ ((noinline))
>> +test9 (void)
>> +{
>> + const char *ptr = "abcdefghijklmnopqrstuvwxyz";
>> + char *res = strndup (ptr, 21);
>> + if (__builtin_object_size (res, 1) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr, 32);
>> + if (__builtin_object_size (res, 1) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 1) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + char *ptr2 = malloc (64);
>> + strcpy (ptr2, ptr);
>> +
>> + res = strndup (ptr2, 21);
>> + if (__builtin_object_size (res, 1) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 32);
>> + if (__builtin_object_size (res, 1) != 33)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 128);
>> + if (__builtin_object_size (res, 1) != 64)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr2);
>> +#ifdef __builtin_object_size
>> + if (__builtin_object_size (res, 1) != 27)
>> +#else
>> + if (__builtin_object_size (res, 1) != (size_t) -1)
>> +#endif
>> + abort ();
>> +
>> + free (res);
>> + free (ptr2);
>> +
>> + ptr = "abcd\0efghijklmnopqrstuvwxyz";
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 1) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 24);
>> + if (__builtin_object_size (res, 1) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 2);
>> + if (__builtin_object_size (res, 1) != 3)
>> + abort ();
>> + free (res);
>> +
>> + res = strdup (&ptr[4]);
>> + if (__builtin_object_size (res, 1) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 4);
>> + if (__builtin_object_size (res, 1) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 1);
>> + if (__builtin_object_size (res, 1) != 1)
>> + abort ();
>> + free (res);
>> +}
>> +
>> int
>> main (void)
>> {
>> @@ -557,5 +648,6 @@ main (void)
>> test6 ();
>> test7 ();
>> test8 (1);
>> + test9 ();
>> exit (0);
>> }
>> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
>> index 44a99189776..ff4f1747334 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> typedef __SIZE_TYPE__ size_t;
>> @@ -7,10 +7,13 @@ extern void abort (void);
>> extern void exit (int);
>> extern void *malloc (size_t);
>> extern void *calloc (size_t, size_t);
>> +extern void free (void *);
>> extern void *alloca (size_t);
>> extern void *memcpy (void *, const void *, size_t);
>> extern void *memset (void *, int, size_t);
>> extern char *strcpy (char *, const char *);
>> +extern char *strdup (const char *);
>> +extern char *strndup (const char *, size_t);
>>
>> struct A
>> {
>> @@ -636,6 +639,95 @@ test10 (void)
>> }
>> }
>>
>> +/* Tests for strdup/strndup. */
>> +size_t
>> +__attribute__ ((noinline))
>> +test11 (void)
>> +{
>> + const char *ptr = "abcdefghijklmnopqrstuvwxyz";
>> + char *res = strndup (ptr, 21);
>> + if (__builtin_object_size (res, 2) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr, 32);
>> + if (__builtin_object_size (res, 2) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 2) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + char *ptr2 = malloc (64);
>> + strcpy (ptr2, ptr);
>> +
>> + res = strndup (ptr2, 21);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 32);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 128);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr2);
>> +
>> +#ifdef __builtin_object_size
>> + if (__builtin_object_size (res, 2) != 27)
>> +#else
>> + if (__builtin_object_size (res, 2) != 1)
>> +#endif
>> + abort ();
>> +
>> + free (res);
>> + free (ptr2);
>> +
>> + ptr = "abcd\0efghijklmnopqrstuvwxyz";
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 2) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 24);
>> + if (__builtin_object_size (res, 2) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 2);
>> + if (__builtin_object_size (res, 2) != 3)
>> + abort ();
>> + free (res);
>> +
>> + res = strdup (&ptr[4]);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 4);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 1);
>> + if (__builtin_object_size (res, 2) != 1)
>> + abort ();
>> + free (res);
>> +}
>> +
>> int
>> main (void)
>> {
>> @@ -651,5 +743,6 @@ main (void)
>> test8 ();
>> test9 (1);
>> test10 ();
>> + test11 ();
>> exit (0);
>> }
>> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
>> index b9fddfed036..4c007c364b7 100644
>> --- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
>> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
>> @@ -1,5 +1,5 @@
>> /* { dg-do run } */
>> -/* { dg-options "-O2" } */
>> +/* { dg-options "-O2 -Wno-stringop-overread" } */
>> /* { dg-require-effective-target alloca } */
>>
>> typedef __SIZE_TYPE__ size_t;
>> @@ -7,10 +7,13 @@ extern void abort (void);
>> extern void exit (int);
>> extern void *malloc (size_t);
>> extern void *calloc (size_t, size_t);
>> +extern void free (void *);
>> extern void *alloca (size_t);
>> extern void *memcpy (void *, const void *, size_t);
>> extern void *memset (void *, int, size_t);
>> extern char *strcpy (char *, const char *);
>> +extern char *strdup (const char *);
>> +extern char *strndup (const char *, size_t);
>>
>> struct A
>> {
>> @@ -517,6 +520,94 @@ test8 (unsigned cond)
>> #endif
>> }
>>
>> +/* Tests for strdup/strndup. */
>> +size_t
>> +__attribute__ ((noinline))
>> +test9 (void)
>> +{
>> + const char *ptr = "abcdefghijklmnopqrstuvwxyz";
>> + char *res = strndup (ptr, 21);
>> + if (__builtin_object_size (res, 3) != 22)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr, 32);
>> + if (__builtin_object_size (res, 3) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 3) != 27)
>> + abort ();
>> +
>> + free (res);
>> +
>> + char *ptr2 = malloc (64);
>> + strcpy (ptr2, ptr);
>> +
>> + res = strndup (ptr2, 21);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 32);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strndup (ptr2, 128);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> +
>> + free (res);
>> +
>> + res = strdup (ptr2);
>> +#ifdef __builtin_object_size
>> + if (__builtin_object_size (res, 3) != 27)
>> +#else
>> + if (__builtin_object_size (res, 3) != 1)
>> +#endif
>> + abort ();
>> +
>> + free (res);
>> + free (ptr2);
>> +
>> + ptr = "abcd\0efghijklmnopqrstuvwxyz";
>> + res = strdup (ptr);
>> + if (__builtin_object_size (res, 3) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 24);
>> + if (__builtin_object_size (res, 3) != 5)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (ptr, 2);
>> + if (__builtin_object_size (res, 3) != 3)
>> + abort ();
>> + free (res);
>> +
>> + res = strdup (&ptr[4]);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 4);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> + free (res);
>> +
>> + res = strndup (&ptr[4], 1);
>> + if (__builtin_object_size (res, 3) != 1)
>> + abort ();
>> + free (res);
>> +}
>> +
>> int
>> main (void)
>> {
>> @@ -530,5 +621,6 @@ main (void)
>> test6 ();
>> test7 ();
>> test8 (1);
>> + test9 ();
>> exit (0);
>> }
>> diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
>> index 1f04cb80fd0..08e5731617d 100644
>> --- a/gcc/tree-object-size.cc
>> +++ b/gcc/tree-object-size.cc
>> @@ -89,6 +89,10 @@ static bitmap computed[OST_END];
>> /* Maximum value of offset we consider to be addition. */
>> static unsigned HOST_WIDE_INT offset_limit;
>>
>> +/* Tell the generic SSA updater what kind of update is needed after the pass
>> + executes. */
>> +static unsigned todo;
>> +
>> /* Return true if VAL represents an initial size for OBJECT_SIZE_TYPE. */
>>
>> static inline bool
>> @@ -787,6 +791,73 @@ alloc_object_size (const gcall *call, int object_size_type)
>> return bytes ? bytes : size_unknown (object_size_type);
>> }
>>
>> +/* Compute __builtin_object_size for CALL, which is a call to either
>> + BUILT_IN_STRDUP or BUILT_IN_STRNDUP; IS_STRNDUP indicates which it is.
>> + OBJECT_SIZE_TYPE is the second argument from __builtin_object_size.
>> + If unknown, return size_unknown (object_size_type). */
>> +
>> +static tree
>> +strdup_object_size (const gcall *call, int object_size_type, bool is_strndup)
>> +{
>> + tree src = gimple_call_arg (call, 0);
>> + tree sz = size_unknown (object_size_type);
>> + tree n = NULL_TREE;
>> +
>> + if (is_strndup)
>> + n = fold_build2 (PLUS_EXPR, sizetype, size_one_node,
>> + gimple_call_arg (call, 1));
>> +
>> +
>> + /* For strdup, simply emit strlen (SRC) + 1 and let the optimizer fold it the
>> + way it likes. */
>> + if (!is_strndup)
> Sorry to nitpick, should this just be under else ? Since this
> condition will be false if the above if (is_strndup)
> is true.
Fixed locally. I'll resend once I have more comments on the rest of the
patch.
Thanks,
Sid
next prev parent reply other threads:[~2022-11-04 13:47 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-15 19:23 [PATCH] " Siddhesh Poyarekar
2022-08-29 14:16 ` Siddhesh Poyarekar
2022-09-07 19:21 ` Siddhesh Poyarekar
2022-09-15 14:00 ` Siddhesh Poyarekar
2022-09-22 13:02 ` Jakub Jelinek
2022-09-22 15:26 ` Siddhesh Poyarekar
2022-09-23 13:02 ` Jakub Jelinek
2022-11-02 22:30 ` Siddhesh Poyarekar
2022-11-04 12:48 ` [PATCH v2] " Siddhesh Poyarekar
2022-11-04 13:43 ` Prathamesh Kulkarni
2022-11-04 13:47 ` Siddhesh Poyarekar [this message]
2022-11-17 19:47 ` Siddhesh Poyarekar
2022-11-20 15:42 ` Jeff Law
2022-11-21 14:27 ` Siddhesh Poyarekar
2022-11-22 20:43 ` Jeff Law
2022-11-22 23:13 ` Siddhesh Poyarekar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0519cbc0-31f4-5ae2-0e44-cef59a563a49@gotplt.org \
--to=siddhesh@gotplt.org \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=prathamesh.kulkarni@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).