Commit e1112e60 by Richard Sandiford Committed by Richard Sandiford

builtins: New directory.

	* gcc.c-torture/execute/builtins: New directory.
	* gcc.c-torture/execute/string-opt-{3,4,16,17,18,19}.c: Move into
	gcc.c-torture/execute/builtins.
	* gcc.c-torture/execute/string-opt-asm-{1,2}.c: Likewise.
	* gcc.c-torture/execute/builtin-noret-{1,2}.c: Move to...
	* gcc.dg/torture: ...this new directory.  Turn into link-only tests.
	* gcc.dg/no-builtin-1.c: Move into gcc.c-torture/execute/builtins.

From-SVN: r66680
parent 51ff8149
2003-05-11 Richard Sandiford <rsandifo@redhat.com>
* gcc.c-torture/execute/builtins: New directory.
* gcc.c-torture/execute/string-opt-{3,4,16,17,18,19}.c: Move into
gcc.c-torture/execute/builtins.
* gcc.c-torture/execute/string-opt-asm-{1,2}.c: Likewise.
* gcc.c-torture/execute/builtin-noret-{1,2}.c: Move to...
* gcc.dg/torture: ...this new directory. Turn into link-only tests.
* gcc.dg/no-builtin-1.c: Move into gcc.c-torture/execute/builtins.
2003-05-10 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/9252
......
extern int abs_called;
extern int inside_main;
/* The labs call should have been optimized, but the abs call
shouldn't have been. */
int
abs (int x)
{
if (inside_main)
abs_called = 1;
return (x < 0 ? -x : x);
}
long
labs (long x)
{
if (inside_main)
abort ();
return (x < 0 ? -x : x);
}
/* Test for -fno-builtin-FUNCTION. */
/* Origin: Joseph Myers <jsm28@cam.ac.uk>. */
/* { dg-do run } */
/* { dg-options "-fno-builtin-abs" } */
/* GCC normally handles abs and labs as built-in functions even without
optimization. So test that with -fno-builtin-abs, labs is so handled
but abs isn't. */
......@@ -14,8 +11,8 @@ extern long labs (long);
extern void abort (void);
extern void exit (int);
int
main (void)
void
main_test (void)
{
if (labs (0) != 0)
abort ();
......@@ -23,21 +20,4 @@ main (void)
abort ();
if (!abs_called)
abort ();
exit (0);
}
/* The labs call above should have been optimized, but the abs call
shouldn't have been. */
static int
abs (int x)
{ /* { dg-warning "static" "static decl warning" } */
abs_called = 1;
return (x < 0 ? -1 : x);
}
static long
labs (long x)
{
abort ();
}
set additional_flags -fno-builtin-abs
return 0
# This harness is for testing builtin support. Each test has two files:
#
# - foo.c defines the main testing function, main_test().
# - foo-lib.c implements the library functions that foo.c is testing.
#
# The functions in foo-lib.c will often want to abort on certain inputs.
# They can use the global variable inside_main to see whether they are
# being called from the test program or part of the common runtime.
#
# In many cases, the library functions will behave as normal at -O0
# and abort when optimisation is enabled. Such implementations should
# go into the lib/ directory so that they can be included by any test
# that needs them. They shouldn't call any external functions in case
# those functions were overridden too.
load_lib c-torture.exp
foreach src [lsort [find $srcdir/$subdir *.c]] {
if {![string match *-lib.c $src] && [runtest_file_p $runtests $src]} {
c-torture-execute [list $src \
[file root $src]-lib.c \
$srcdir/$subdir/lib/main.c]
}
}
extern void main_test (void);
int inside_main;
int
main ()
{
inside_main = 1;
main_test ();
inside_main = 0;
return 0;
}
extern int inside_main;
int
memcmp (const void *s1, const void *s2, __SIZE_TYPE__ len)
{
const unsigned char *sp1, *sp2;
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
sp1 = s1;
sp2 = s2;
while (len != 0 && *sp1 == *sp2)
sp1++, sp2++, len--;
if (len == 0)
return 0;
return *sp1 - *sp2;
}
extern int inside_main;
void *
memmove (void *dst, const void *src, __SIZE_TYPE__ n)
{
char *dstp;
const char *srcp;
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
srcp = src;
dstp = dst;
if (srcp < dstp)
while (n-- != 0)
dstp[n] = srcp[n];
else
while (n-- != 0)
*dstp++ = *srcp++;
return dst;
}
void
bcopy (const void *src, void *dst, __SIZE_TYPE__ n)
{
memmove (dst, src, n);
}
extern int inside_main;
void *
mempcpy (void *dst, const void *src, __SIZE_TYPE__ n)
{
const char *srcp;
char *dstp;
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
srcp = src;
dstp = dst;
while (n-- != 0)
*dstp++ = *srcp++;
return dstp;
}
extern int inside_main;
char *
stpcpy (char *dst, const char *src)
{
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
while (*src != 0)
*dst++ = *src++;
*dst = 0;
return dst;
}
extern int inside_main;
char *
strchr (const char *s, int c)
{
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
for (;;)
{
if (*s == c)
return (char *) s;
if (*s == 0)
return 0;
s++;
}
}
char *
index (const char *s, int c)
{
return strchr (s, c);
}
extern int inside_main;
int
strcmp (const char *s1, const char *s2)
{
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
while (*s1 != 0 && *s1 == *s2)
s1++, s2++;
if (*s1 == 0 || *s2 == 0)
return (unsigned char) *s1 - (unsigned char) *s2;
return *s1 - *s2;
}
extern int inside_main;
__SIZE_TYPE__
strlen (const char *s)
{
__SIZE_TYPE__ i;
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
i = 0;
while (s[i] != 0)
i++;
return i;
}
extern int inside_main;
char *
strrchr (const char *s, int c)
{
__SIZE_TYPE__ i;
#ifdef __OPTIMIZE__
if (inside_main)
abort ();
#endif
i = 0;
while (s[i] != 0)
i++;
do
if (s[i] == c)
return (char *) s + i;
while (i-- != 0);
return 0;
}
char *
rindex (const char *s, int c)
{
return strrchr (s, c);
}
#include "lib/strrchr.c"
#include "lib/strlen.c"
#include "lib/strcmp.c"
/* Copyright (C) 2000 Free Software Foundation.
/* Copyright (C) 2000, 2003 Free Software Foundation.
Ensure all expected transformations of builtin strlen, strcmp,
strrchr and rindex occur and perform correctly.
......@@ -14,7 +14,8 @@ extern char *rindex (const char *, int);
int x = 6;
char *bar = "hi world";
int main()
void
main_test (void)
{
const char *const foo = "hello world";
......@@ -83,45 +84,4 @@ int main()
abort ();
if (__builtin_strcmp (foo, "hello") <= 0)
abort ();
return 0;
}
static char *
rindex (const char *s, int c)
{
/* For systems which don't have rindex, we ensure no link failures
occur by always providing a backup definition. During
optimization this function aborts to catch errors. */
#ifdef __OPTIMIZE__
abort ();
#else
return strrchr(s, c);
#endif
}
#ifdef __OPTIMIZE__
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. */
__attribute__ ((noinline))
static __SIZE_TYPE__
strlen (const char *s)
{
abort ();
}
__attribute__ ((noinline))
static int
strcmp (const char *s1, const char *s2)
{
abort ();
}
__attribute__ ((noinline))
static char *
strrchr (const char *s, int c)
{
abort ();
}
#endif
/* Copyright (C) 2000 Free Software Foundation.
/* Copyright (C) 2000, 2003 Free Software Foundation.
Ensure all expected transformations of builtin strchr and index
occur and perform correctly.
......@@ -9,7 +9,8 @@ extern void abort (void);
extern char *strchr (const char *, int);
extern char *index (const char *, int);
int main()
void
main_test (void)
{
const char *const foo = "hello world";
......@@ -32,31 +33,4 @@ int main()
abort ();
if (__builtin_index (foo, 'o') != foo + 4)
abort ();
return 0;
}
static char *
index (const char *s, int c)
{
/* For systems which don't have index, we ensure no link failures
occur by always providing a backup definition. During
optimization this function aborts to catch errors. */
#ifdef __OPTIMIZE__
abort ();
#else
return strchr(s, c);
#endif
}
#ifdef __OPTIMIZE__
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. */
__attribute__ ((noinline))
static char *
strchr (const char *s, int c)
{
abort ();
}
#endif
extern int inside_main;
void *
memset (void *dst, int c, __SIZE_TYPE__ n)
{
/* Single-byte memsets should be done inline when optimisation
is enabled. */
#ifdef __OPTIMIZE__
if (inside_main && n < 2)
abort ();
#endif
while (n-- != 0)
n[(char *) dst] = c;
return dst;
}
/* Copyright (C) 2002 Free Software Foundation.
/* Copyright (C) 2002, 2003 Free Software Foundation.
Ensure that builtin memset operations for constant length and
non-constant assigned value don't cause compiler problems.
......@@ -10,9 +10,10 @@ typedef __SIZE_TYPE__ size_t;
extern void *memset (void *, int, size_t);
char buffer[32];
int argc = 1;
int
main (int argc)
void
main_test (void)
{
memset (buffer, argc, 0);
memset (buffer, argc, 1);
......@@ -32,20 +33,4 @@ main (int argc)
memset (buffer, argc, 15);
memset (buffer, argc, 16);
memset (buffer, argc, 17);
return 0;
}
#ifdef __OPTIMIZE__
/* When optimizing, most of the above cases should be transformed into
something else. So any remaining calls to the original function
for short lengths should abort. */
__attribute__ ((noinline))
static void *
memset (void *dst, int c, size_t len)
{
if (len < 2)
abort ();
}
#endif
#include "lib/stpcpy.c"
#include "lib/mempcpy.c"
......@@ -19,7 +19,8 @@ char *s2 = "defg";
char *s3 = "FGH";
size_t l1 = 1;
int main()
void
main_test (void)
{
int i;
const char *s;
......@@ -29,7 +30,7 @@ int main()
if (stpcpy (p + 16, "vwxyz" + 1) != p + 16 + 4 || memcmp (p + 16, "wxyz", 5))
abort ();
if (stpcpy (p + 1, "") != p + 1 + 0 || memcmp (p, "a\0cde", 6))
abort ();
abort ();
if (stpcpy (p + 3, "fghij") != p + 3 + 5 || memcmp (p, "a\0cfghij", 9))
abort ();
if (mempcpy (p, "ABCDE", 6) != p + 6 || memcmp (p, "ABCDE", 6))
......@@ -37,7 +38,7 @@ int main()
if (mempcpy (p + 16, "VWX" + 1, 2) != p + 16 + 2 || memcmp (p + 16, "WXyz", 5))
abort ();
if (mempcpy (p + 1, "", 1) != p + 1 + 1 || memcmp (p, "A\0CDE", 6))
abort ();
abort ();
if (mempcpy (p + 3, "FGHI", 4) != p + 3 + 4 || memcmp (p, "A\0CFGHIj", 9))
abort ();
......@@ -55,7 +56,7 @@ int main()
abort();
if (mempcpy (mempcpy (p, "abcdEFG", 4), "efg", 4) != p + 8 || memcmp (p, "abcdefg", 8))
abort();
/* Test at least one instance of the __builtin_ style. We do this
to ensure that it works and that the prototype is correct. */
if (__builtin_stpcpy (p, "abcde") != p + 5 || memcmp (p, "abcde", 6))
......@@ -74,31 +75,4 @@ int main()
mempcpy (p + 6, s3 + 1, l1);
if (memcmp (p, "ABCdeFG", 8))
abort ();
return 0;
}
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. When not optimizing, we provide fallback funcs for
platforms that don't have mempcpy or stpcpy in libc.*/
__attribute__ ((noinline))
static char *
stpcpy (char *d, const char *s)
{
#ifdef __OPTIMIZE__
abort ();
#else
return strcpy (d, s) + strlen (s);
#endif
}
__attribute__ ((noinline))
static void *
mempcpy (void *dst, const void *src, size_t sz)
{
#ifdef __OPTIMIZE__
abort ();
#else
return (char *) memcpy (dst, src, sz) + sz;
#endif
}
......@@ -54,7 +54,8 @@ static const struct bar
static const int baz[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int main()
void
main_test (void)
{
const char *s;
struct foo f1[sizeof foo/sizeof*foo];
......@@ -86,40 +87,4 @@ int main()
__builtin_bcopy ("ABCDE", p + 4, 1);
if (memcmp (p, "abfgAi", 7))
abort ();
return 0;
}
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. When not optimizing, provide memmove/bcopy implementation
just in case target lacks these in its libc. */
__attribute__ ((noinline))
static void *
memmove (void *d, const void *s, size_t n)
{
#ifdef __OPTIMIZE__
abort ();
#else
char *dst = (char *) d;
const char *src = (const char *) s;
if (src < dst)
{
dst += n;
src += n;
while (n--)
*--dst = *--src;
}
else
while (n--)
*dst++ = *src++;
return (char *) d;
#endif
}
__attribute__ ((noinline))
static void
bcopy (const void *s, void *d, size_t n)
{
memmove (d, s, n);
}
......@@ -12,36 +12,23 @@ extern void link_error (void);
typedef __SIZE_TYPE__ size_t;
extern int memcmp (const void *, const void *, size_t);
int
main (int argc)
void
main_test (void)
{
if (memcmp ("abcd", "efgh", 4) >= 0)
link_error ();
link_error ();
if (memcmp ("abcd", "abcd", 4) != 0)
link_error ();
link_error ();
if (memcmp ("efgh", "abcd", 4) <= 0)
link_error ();
return 0;
link_error ();
}
#ifdef __OPTIMIZE__
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. */
__attribute__ ((noinline))
static int
memcmp (const void *s1, const void *s2, size_t len)
{
abort ();
}
#else
#ifndef __OPTIMIZE__
/* When not optimizing, the above tests may generate references to
the function link_error, but should never actually call it. */
__attribute__ ((noinline))
static void
void
link_error ()
{
abort ();
}
#endif
extern int inside_main;
extern const char *p;
char *
my_strstr (const char *s1, const char *s2)
{
__SIZE_TYPE__ len = strlen (s2);
#ifdef __OPTIMIZE__
/* If optimizing, we should be called only in the strstr (foo + 2, p)
case. All other cases should be optimized. */
if (inside_main)
if (s2 != p || strcmp (s1, "hello world" + 2) != 0)
abort ();
#endif
if (len == 0)
return (char *) s1;
for (s1 = strchr (s1, *s2); s1; s1 = strchr (s1 + 1, *s2))
if (strncmp (s1, s2, len) == 0)
return (char *) s1;
return (char *) 0;
}
char *
strstr (const char *s1, const char *s2)
{
if (inside_main)
abort ();
return my_strstr (s1, s2);
}
/* Copyright (C) 2000, 2003 Free Software Foundation.
Ensure all expected transformations of builtin strstr occur and
perform correctly in presence of redirect. */
typedef __SIZE_TYPE__ size_t;
extern void abort (void);
extern char *strstr (const char *, const char *)
__asm ("my_strstr");
const char *p = "rld", *q = "hello world";
void
main_test (void)
{
const char *const foo = "hello world";
if (strstr (foo, "") != foo)
abort ();
if (strstr (foo + 4, "") != foo + 4)
abort ();
if (strstr (foo, "h") != foo)
abort ();
if (strstr (foo, "w") != foo + 6)
abort ();
if (strstr (foo + 6, "o") != foo + 7)
abort ();
if (strstr (foo + 1, "world") != foo + 6)
abort ();
if (strstr (foo + 2, p) != foo + 8)
abort ();
if (strstr (q, "") != q)
abort ();
if (strstr (q + 1, "o") != q + 4)
abort ();
/* Test at least one instance of the __builtin_ style. We do this
to ensure that it works and that the prototype is correct. */
if (__builtin_strstr (foo + 1, "world") != foo + 6)
abort ();
}
extern int inside_main;
typedef __SIZE_TYPE__ size_t;
#define TEST_ABORT if (inside_main) abort()
void *
my_memcpy (void *d, const void *s, size_t n)
{
char *dst = (char *) d;
const char *src = (const char *) s;
while (n--)
*dst++ = *src++;
return (char *) d;
}
void
my_bcopy (const void *s, void *d, size_t n)
{
char *dst = (char *) d;
const char *src = (const char *) s;
if (src >= dst)
while (n--)
*dst++ = *src++;
else
{
dst += n;
src += n;
while (n--)
*--dst = *--src;
}
}
void *
my_memset (void *d, int c, size_t n)
{
char *dst = (char *) d;
while (n--)
*dst++ = c;
return (char *) d;
}
void
my_bzero (void *d, size_t n)
{
char *dst = (char *) d;
while (n--)
*dst++ = '\0';
}
void *
memcpy (void *d, const void *s, size_t n)
{
TEST_ABORT;
return my_memcpy (d, s, n);
}
void
bcopy (const void *s, void *d, size_t n)
{
TEST_ABORT;
my_bcopy (s, d, n);
}
void *
memset (void *d, int c, size_t n)
{
TEST_ABORT;
return my_memset (d, c, n);
}
void
bzero (void *d, size_t n)
{
TEST_ABORT;
my_bzero (d, n);
}
/* Copyright (C) 2003 Free Software Foundation.
Test memcpy and memset in presence of redirect. */
typedef __SIZE_TYPE__ size_t;
extern void abort (void);
extern void *memcpy (void *, const void *, size_t)
__asm ("my_memcpy");
extern void bcopy (const void *, void *, size_t)
__asm ("my_bcopy");
extern void *memset (void *, int, size_t)
__asm ("my_memset");
extern void bzero (void *, size_t)
__asm ("my_bzero");
extern int memcmp (const void *, const void *, size_t);
struct A { char c[32]; } a = { "foobar" };
char x[64] = "foobar", y[64];
int i = 39, j = 6, k = 4;
void
main_test (void)
{
struct A b = a;
struct A c = { { 'x' } };
if (memcmp (b.c, x, 32) || c.c[0] != 'x' || memcmp (c.c + 1, x + 32, 31))
abort ();
if (__builtin_memcpy (y, x, i) != y || memcmp (x, y, 64))
abort ();
if (memcpy (y + 6, x, j) != y + 6
|| memcmp (x, y, 6) || memcmp (x, y + 6, 58))
abort ();
if (__builtin_memset (y + 2, 'X', k) != y + 2
|| memcmp (y, "foXXXXfoobar", 13))
abort ();
bcopy (y + 1, y + 2, 6);
if (memcmp (y, "fooXXXXfobar", 13))
abort ();
__builtin_bzero (y + 4, 2);
if (memcmp (y, "fooX\0\0Xfobar", 13))
abort ();
}
/* Test for builtin noreturn attributes. */
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
/* { dg-do link } */
extern void abort (void);
extern void exit (int);
......@@ -17,7 +18,6 @@ int
main (void)
{
volatile int i = 0;
/* The real test here is that the program links. */
if (i)
tabort ();
if (i)
......@@ -50,9 +50,8 @@ t_exit (void)
link_failure ();
}
/* Some non-Unix libcs might not have _exit. This version should never
get called. */
static void
/* Some non-Unix libcs might not have _exit. */
void
_exit (int i)
{
abort ();
......@@ -65,20 +64,9 @@ t_Exit (void)
link_failure ();
}
/* Some libcs might not have _Exit. This version should never get called. */
static void
_Exit (int i)
{
abort ();
}
/* When optimizing, no calls to link_failure should remain. In any case,
link_failure should not be called. */
#ifndef __OPTIMIZE__
/* Some libcs might not have _Exit. */
void
link_failure (void)
_Exit (int i)
{
abort ();
}
#endif
/* Test for builtin noreturn attributes when the visible declarations
are function-local. Doesn't presently work. Modified from
builtin-noret-1.c by Zack Weinberg <zack@codesourcery.com>. */
are function-local. Modified from builtin-noret-1.c by Zack Weinberg
<zack@codesourcery.com>. */
/* { dg-do link } */
extern void tabort (void);
extern void texit (void);
......@@ -13,7 +14,6 @@ int
main (void)
{
volatile int i = 0;
/* The real test here is that the program links. */
if (i)
tabort ();
if (i)
......@@ -49,9 +49,8 @@ t_exit (void)
link_failure ();
}
/* Some non-Unix libcs might not have _exit. This version should never
get called. */
static void
/* Some non-Unix libcs might not have _exit. */
void
_exit (int i)
{
abort ();
......@@ -65,20 +64,9 @@ t_Exit (void)
link_failure ();
}
/* Some libcs might not have _Exit. This version should never get called. */
static void
_Exit (int i)
{
abort ();
}
/* When optimizing, no calls to link_failure should remain. In any case,
link_failure should not be called. */
#ifndef __OPTIMIZE__
/* Some libcs might not have _Exit. */
void
link_failure (void)
_Exit (int i)
{
abort ();
}
#endif
# This harness is for tests that should be run at all optimisation levels.
load_lib gcc-dg.exp
dg-init
gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] ""
dg-finish
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment