Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-22 Thread Siddhesh Poyarekar

On 2022-11-22 15:43, Jeff Law wrote:


On 11/21/22 07:27, Siddhesh Poyarekar wrote:

On 2022-11-20 10:42, Jeff Law wrote:


On 11/4/22 06:48, Siddhesh Poyarekar 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.


I'm struggling to see how the SSA updating is correct.  Yes we need 
to update the virtuals due to the introduction of the call to strlen, 
particularly when SRC is not a string constant.  But do we need to do 
more?


Don't we end up gimplifying the 1 + strlenfn (src) expression? Can 
that possibly create new SSA_NAMEs?  Do those need to be put into SSA 
form? I feel like I'm missing something here...


We do all of that manually in gimplify_size_expressions, the only 
thing left to do is updating virtuals AFAICT.


I guess it's actually buried down in force_gimple_operand and I guess 
for temporaries they're not going to be alive across the new gimple 
sequence and each destination gets its own SSA_NAME, so it ought to be 
safe.  Just had to work a bit further through things.


OK for the trunk.


Thanks, pushed with the trivial fixup that Prathamesh suggested, i.e. 
replaced 'if (!strndup)' with 'else'.


Sid


Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-22 Thread Jeff Law via Gcc-patches



On 11/21/22 07:27, Siddhesh Poyarekar wrote:

On 2022-11-20 10:42, Jeff Law wrote:


On 11/4/22 06:48, Siddhesh Poyarekar 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.


I'm struggling to see how the SSA updating is correct.  Yes we need 
to update the virtuals due to the introduction of the call to strlen, 
particularly when SRC is not a string constant.  But do we need to do 
more?


Don't we end up gimplifying the 1 + strlenfn (src) expression? Can 
that possibly create new SSA_NAMEs?  Do those need to be put into SSA 
form? I feel like I'm missing something here...


We do all of that manually in gimplify_size_expressions, the only 
thing left to do is updating virtuals AFAICT.


I guess it's actually buried down in force_gimple_operand and I guess 
for temporaries they're not going to be alive across the new gimple 
sequence and each destination gets its own SSA_NAME, so it ought to be 
safe.  Just had to work a bit further through things.


OK for the trunk.


Thanks,
jeff




Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-21 Thread Siddhesh Poyarekar

On 2022-11-20 10:42, Jeff Law wrote:


On 11/4/22 06:48, Siddhesh Poyarekar 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.


I'm struggling to see how the SSA updating is correct.  Yes we need to 
update the virtuals due to the introduction of the call to strlen, 
particularly when SRC is not a string constant.  But do we need to do more?


Don't we end up gimplifying the 1 + strlenfn (src) expression? Can that 
possibly create new SSA_NAMEs?  Do those need to be put into SSA form? I 
feel like I'm missing something here...


We do all of that manually in gimplify_size_expressions, the only thing 
left to do is updating virtuals AFAICT.


Thanks,
Sid


Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-20 Thread Jeff Law via Gcc-patches



On 11/4/22 06:48, Siddhesh Poyarekar 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.


I'm struggling to see how the SSA updating is correct.  Yes we need to 
update the virtuals due to the introduction of the call to strlen, 
particularly when SRC is not a string constant.  But do we need to do more?


Don't we end up gimplifying the 1 + strlenfn (src) expression? Can that 
possibly create new SSA_NAMEs?  Do those need to be put into SSA form?  
I feel like I'm missing something here...



jeff



Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-17 Thread Siddhesh Poyarekar

Ping!

On 2022-11-04 08:48, Siddhesh Poyarekar 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 ();
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 

Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-04 Thread Siddhesh Poyarekar

On 2022-11-04 09:43, Prathamesh Kulkarni wrote:

On Fri, 4 Nov 2022 at 18:18, Siddhesh Poyarekar  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 ();
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
+++ 

Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-04 Thread Prathamesh Kulkarni via Gcc-patches
On Fri, 4 Nov 2022 at 18:18, Siddhesh Poyarekar  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 ();
>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 
> 

[PATCH v2] tree-object-size: Support strndup and strdup

2022-11-04 Thread Siddhesh Poyarekar
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 ();
   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" } */
 /* {