diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 7c0df90e822..8e4e59ac44c 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -2837,6 +2837,9 @@ can be included without error when @option{-mbig-endian} is passed. @item stpcpy Target provides @code{stpcpy} function. +@item strndup +Target provides @code{strndup} function. + @item sysconf Target supports @code{sysconf}. 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 173e7c755f4..d02e37f79d9 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2" } */ /* { dg-require-effective-target size20plus } */ -/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #include "builtin-object-size-common.h" @@ -567,6 +567,7 @@ test_strdup (const char *in) return sz; } +#ifndef SKIP_STRNDUP size_t __attribute__ ((noinline)) test_strndup (const char *in, size_t bound) @@ -577,6 +578,7 @@ test_strndup (const char *in, size_t bound) __builtin_free (res); return sz; } +#endif size_t __attribute__ ((noinline)) @@ -589,6 +591,7 @@ test_strdup_min (const char *in) return sz; } +#ifndef SKIP_STRNDUP size_t __attribute__ ((noinline)) test_strndup_min (const char *in, size_t bound) @@ -599,6 +602,7 @@ test_strndup_min (const char *in, size_t bound) __builtin_free (res); return sz; } +#endif /* Other tests. */ @@ -788,12 +792,16 @@ main (int argc, char **argv) const char *str = "hello world"; if (test_strdup (str) != __builtin_strlen (str) + 1) FAIL (); +#ifndef SKIP_STRNDUP if (test_strndup (str, 4) != 5) FAIL (); +#endif if (test_strdup_min (str) != __builtin_strlen (str) + 1) FAIL (); +#ifndef SKIP_STRNDUP if (test_strndup_min (str, 4) != 1) FAIL (); +#endif DONE (); } 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 ffa59985024..76b4f704fed 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ -/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-1.c" 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 fff32da7aea..cb757a8d699 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ -/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-2.c" 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 ac223d67b10..8a12f023f27 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-3.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ -/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-3.c" 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 fdf4284ae11..0efc2d98584 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-4.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ -/* { dg-skip-if "no strndup" { hppa*-*-hpux* } } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #define __builtin_object_size __builtin_dynamic_object_size #include "builtin-object-size-4.c" diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-1.c b/gcc/testsuite/gcc.dg/builtin-object-size-1.c index 4f7d4c0b370..d6d13c5ef7a 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-1.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-1.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #include "builtin-object-size-common.h" @@ -621,7 +622,7 @@ test10 (void) } } -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -709,7 +710,7 @@ test11 (void) FAIL (); free (res); } -#endif /* avr */ +#endif int main (void) @@ -726,7 +727,7 @@ main (void) test8 (); test9 (1); test10 (); -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP test11 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-2.c b/gcc/testsuite/gcc.dg/builtin-object-size-2.c index 37d3dcc6f56..c28d72eee9b 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-2.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-2.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #include "builtin-object-size-common.h" @@ -536,7 +537,7 @@ test8 (unsigned cond) #endif } -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -624,7 +625,7 @@ test9 (void) FAIL (); free (res); } -#endif /* avr */ +#endif int main (void) @@ -639,7 +640,7 @@ main (void) test6 (); test7 (); test8 (1); -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP test9 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-3.c b/gcc/testsuite/gcc.dg/builtin-object-size-3.c index f4d1ebf7027..3f58da3d500 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-3.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-3.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #include "builtin-object-size-common.h" @@ -628,7 +629,7 @@ test10 (void) } } -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -717,7 +718,7 @@ test11 (void) FAIL (); free (res); } -#endif /* avr */ +#endif int main (void) @@ -734,7 +735,7 @@ main (void) test8 (); test9 (1); test10 (); -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP test11 (); #endif DONE (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c index 2887dd15042..b3eb36efb74 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c @@ -1,6 +1,7 @@ /* { dg-do run } */ /* { dg-options "-O2 -Wno-stringop-overread" } */ /* { dg-require-effective-target alloca } */ +/* { dg-additional-options "-DSKIP_STRNDUP" { target { ! strndup } } } */ #include "builtin-object-size-common.h" @@ -509,7 +510,7 @@ test8 (unsigned cond) #endif } -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP /* Tests for strdup/strndup. */ size_t __attribute__ ((noinline)) @@ -597,7 +598,7 @@ test9 (void) FAIL (); free (res); } -#endif /* avr */ +#endif int main (void) @@ -612,7 +613,7 @@ main (void) test6 (); test7 (); test8 (1); -#if !defined(__AVR__) && !defined(__hpux__) /* avr and hpux have no strndup */ +#ifndef SKIP_STRNDUP test9 (); #endif DONE (); diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 938fff9392c..3a5713d9869 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -11581,6 +11581,17 @@ proc check_effective_target_stpcpy {} { return [check_function_available "stpcpy"] } +# Returns 1 if "strndup" is available on the target system. + +proc check_effective_target_strndup {} { + if { [istarget *-*-vxworks*] } { + # VxWorks doesn't have strndup but our way to test fails + # to detect as we're doing partial links for kernel modules. + return 0 + } + return [check_function_available "strndup"] +} + # Returns 1 if "sigsetjmp" is available on the target system. # Also check if "__sigsetjmp" is defined since that's what glibc # uses.