builtins.c (expand_builtin_strncmp, [...]): New functions.
* builtins.c (expand_builtin_strncmp, expand_builtin_strncpy): New functions. (expand_builtin): Handle BUILT_IN_STRNCPY and BUILT_IN_STRNCMP. * builtins.def (BUILT_IN_STRNCPY, BUILT_IN_STRNCMP): New entries. * c-common.c (c_common_nodes_and_builtins): Declare builtin strncpy and strncmp. * extend.texi (strncmp, strncpy): Document new builtins. testsuite: * gcc.c-torture/execute/string-opt-7.c: New test. * gcc.c-torture/execute/string-opt-8.c: Likewise. From-SVN: r37777
This commit is contained in:
parent
231db5f4ec
commit
da9e9f0862
@ -1,3 +1,16 @@
|
||||
2000-11-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* builtins.c (expand_builtin_strncmp, expand_builtin_strncpy): New
|
||||
functions.
|
||||
(expand_builtin): Handle BUILT_IN_STRNCPY and BUILT_IN_STRNCMP.
|
||||
|
||||
* builtins.def (BUILT_IN_STRNCPY, BUILT_IN_STRNCMP): New entries.
|
||||
|
||||
* c-common.c (c_common_nodes_and_builtins): Declare builtin
|
||||
strncpy and strncmp.
|
||||
|
||||
* extend.texi (strncmp, strncpy): Document new builtins.
|
||||
|
||||
2000-11-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* config/elfos.h (ASM_OUTPUT_SECTION_NAME): Use a hash table, not
|
||||
|
151
gcc/builtins.c
151
gcc/builtins.c
@ -104,8 +104,12 @@ static rtx expand_builtin_memcmp PARAMS ((tree, tree, rtx));
|
||||
#endif
|
||||
static rtx expand_builtin_strcmp PARAMS ((tree, rtx,
|
||||
enum machine_mode));
|
||||
static rtx expand_builtin_strncmp PARAMS ((tree, rtx,
|
||||
enum machine_mode));
|
||||
static rtx expand_builtin_memcpy PARAMS ((tree));
|
||||
static rtx expand_builtin_strcpy PARAMS ((tree));
|
||||
static rtx expand_builtin_strncpy PARAMS ((tree, rtx,
|
||||
enum machine_mode));
|
||||
static rtx expand_builtin_memset PARAMS ((tree));
|
||||
static rtx expand_builtin_bzero PARAMS ((tree));
|
||||
static rtx expand_builtin_strlen PARAMS ((tree, rtx));
|
||||
@ -1770,6 +1774,63 @@ expand_builtin_strcpy (exp)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Expand expression EXP, which is a call to the strncpy builtin. Return 0
|
||||
if we failed the caller should emit a normal call. */
|
||||
|
||||
static rtx
|
||||
expand_builtin_strncpy (arglist, target, mode)
|
||||
tree arglist;
|
||||
rtx target;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (arglist == 0
|
||||
/* Arg could be non-pointer if user redeclared this fcn wrong. */
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
|
||||
|| TREE_CHAIN (arglist) == 0
|
||||
|| (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist))))
|
||||
!= POINTER_TYPE)
|
||||
|| TREE_CHAIN (TREE_CHAIN (arglist)) == 0
|
||||
|| (TREE_CODE (TREE_TYPE (TREE_VALUE
|
||||
(TREE_CHAIN (TREE_CHAIN (arglist)))))
|
||||
!= INTEGER_TYPE))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
tree slen = c_strlen (TREE_VALUE (TREE_CHAIN (arglist)));
|
||||
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
|
||||
|
||||
/* We must be passed a constant len parameter. */
|
||||
if (TREE_CODE (len) != INTEGER_CST)
|
||||
return 0;
|
||||
|
||||
/* If the len parameter is zero, return the dst parameter. */
|
||||
if (compare_tree_int (len, 0) == 0)
|
||||
{
|
||||
/* Evaluate and ignore the src argument in case it has
|
||||
side-effects. */
|
||||
expand_expr (TREE_VALUE (TREE_CHAIN (arglist)), const0_rtx,
|
||||
VOIDmode, EXPAND_NORMAL);
|
||||
/* Return the dst parameter. */
|
||||
return expand_expr (TREE_VALUE (arglist), target, mode,
|
||||
EXPAND_NORMAL);
|
||||
}
|
||||
|
||||
/* Now, we must be passed a constant src ptr parameter. */
|
||||
if (slen == 0)
|
||||
return 0;
|
||||
|
||||
slen = size_binop (PLUS_EXPR, slen, ssize_int (1));
|
||||
|
||||
/* We're required to pad with trailing zeros if the requested
|
||||
len is greater than strlen(s2)+1, so in that case punt. */
|
||||
if (tree_int_cst_lt (slen, len))
|
||||
return 0;
|
||||
|
||||
/* OK transform into builtin memcpy. */
|
||||
return expand_builtin_memcpy (arglist);
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand expression EXP, which is a call to the memset builtin. Return 0
|
||||
if we failed the caller should emit a normal call. */
|
||||
|
||||
@ -2051,6 +2112,83 @@ expand_builtin_strcmp (exp, target, mode)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Expand expression EXP, which is a call to the strncmp builtin. Return 0
|
||||
if we failed the caller should emit a normal call, otherwise try to get
|
||||
the result in TARGET, if convenient. */
|
||||
static rtx
|
||||
expand_builtin_strncmp (exp, target, mode)
|
||||
tree exp;
|
||||
rtx target;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
tree arglist = TREE_OPERAND (exp, 1);
|
||||
tree arg1, arg2, arg3;
|
||||
const char *p1, *p2;
|
||||
|
||||
/* If we need to check memory accesses, call the library function. */
|
||||
if (current_function_check_memory_usage)
|
||||
return 0;
|
||||
|
||||
if (arglist == 0
|
||||
/* Arg could be non-pointer if user redeclared this fcn wrong. */
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
|
||||
|| TREE_CHAIN (arglist) == 0
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE
|
||||
|| TREE_CHAIN (TREE_CHAIN (arglist)) == 0
|
||||
|| TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))))) != INTEGER_TYPE)
|
||||
return 0;
|
||||
|
||||
arg1 = TREE_VALUE (arglist);
|
||||
arg2 = TREE_VALUE (TREE_CHAIN (arglist));
|
||||
arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
|
||||
|
||||
/* We must be passed a constant len parameter. */
|
||||
if (TREE_CODE (arg3) != INTEGER_CST)
|
||||
return 0;
|
||||
|
||||
/* If the len parameter is zero, return zero. */
|
||||
if (compare_tree_int (arg3, 0) == 0)
|
||||
{
|
||||
/* Evaluate and ignore arg1 and arg2 in case they have
|
||||
side-effects. */
|
||||
expand_expr (arg1, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
expand_expr (arg2, const0_rtx, VOIDmode, EXPAND_NORMAL);
|
||||
return const0_rtx;
|
||||
}
|
||||
|
||||
p1 = c_getstr (arg1);
|
||||
p2 = c_getstr (arg2);
|
||||
|
||||
/* If all arguments are constant, evaluate at compile-time. */
|
||||
if (p1 && p2)
|
||||
{
|
||||
const int r = strncmp (p1, p2, TREE_INT_CST_LOW (arg3));
|
||||
return (r < 0 ? constm1_rtx : (r > 0 ? const1_rtx : const0_rtx));
|
||||
}
|
||||
|
||||
/* If either string parameter is constant and its strlen is strictly
|
||||
less than the length parameter, call expand_builtin_strcmp(). */
|
||||
if ((p1 && compare_tree_int (arg3, strlen (p1)) > 0)
|
||||
|| (p2 && compare_tree_int (arg3, strlen (p2)) > 0))
|
||||
{
|
||||
tree newarglist =
|
||||
tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
|
||||
rtx result;
|
||||
|
||||
/* Call expand_builtin_strcmp with the modified newarglist. If
|
||||
the expansion does not occur, do not allow strncmp to expand to
|
||||
strcmp since strcmp requires that both strings be NULL
|
||||
terminated whereas strncmp does not. */
|
||||
TREE_OPERAND (exp, 1) = newarglist;
|
||||
result = expand_builtin_strcmp (exp, target, mode);
|
||||
/* Always restore the original arguments. */
|
||||
TREE_OPERAND (exp, 1) = arglist;
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Expand a call to __builtin_saveregs, generating the result in TARGET,
|
||||
if that's convenient. */
|
||||
|
||||
@ -2752,6 +2890,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
|| fcode == BUILT_IN_INDEX || fcode == BUILT_IN_RINDEX
|
||||
|| fcode == BUILT_IN_STRCHR || fcode == BUILT_IN_STRRCHR
|
||||
|| fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
|
||||
|| fcode == BUILT_IN_STRNCPY || fcode == BUILT_IN_STRNCMP
|
||||
|| fcode == BUILT_IN_STRSTR || fcode == BUILT_IN_STRPBRK
|
||||
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
|
||||
|| fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
|
||||
@ -2881,6 +3020,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
return target;
|
||||
break;
|
||||
|
||||
case BUILT_IN_STRNCPY:
|
||||
target = expand_builtin_strncpy (arglist, target, mode);
|
||||
if (target)
|
||||
return target;
|
||||
break;
|
||||
|
||||
case BUILT_IN_STRSTR:
|
||||
target = expand_builtin_strstr (arglist, target, mode);
|
||||
if (target)
|
||||
@ -2931,6 +3076,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
return target;
|
||||
break;
|
||||
|
||||
case BUILT_IN_STRNCMP:
|
||||
target = expand_builtin_strncmp (exp, target, mode);
|
||||
if (target)
|
||||
return target;
|
||||
break;
|
||||
|
||||
/* These comparison functions need an instruction that returns an actual
|
||||
index. An ordinary compare that just sets the condition codes
|
||||
is not enough. */
|
||||
|
@ -39,7 +39,9 @@ DEF_BUILTIN(BUILT_IN_BCMP)
|
||||
DEF_BUILTIN(BUILT_IN_INDEX)
|
||||
DEF_BUILTIN(BUILT_IN_RINDEX)
|
||||
DEF_BUILTIN(BUILT_IN_STRCPY)
|
||||
DEF_BUILTIN(BUILT_IN_STRNCPY)
|
||||
DEF_BUILTIN(BUILT_IN_STRCMP)
|
||||
DEF_BUILTIN(BUILT_IN_STRNCMP)
|
||||
DEF_BUILTIN(BUILT_IN_STRLEN)
|
||||
DEF_BUILTIN(BUILT_IN_STRSTR)
|
||||
DEF_BUILTIN(BUILT_IN_STRPBRK)
|
||||
|
@ -4887,6 +4887,7 @@ c_common_nodes_and_builtins ()
|
||||
tree int_ftype_cptr_cptr_sizet;
|
||||
tree int_ftype_string_string, string_ftype_ptr_ptr;
|
||||
tree string_ftype_string_int, string_ftype_string_string;
|
||||
tree string_ftype_string_cstring_sizet, int_ftype_cstring_cstring_sizet;
|
||||
tree long_ftype_long;
|
||||
tree longlong_ftype_longlong;
|
||||
/* Either char* or void*. */
|
||||
@ -4987,6 +4988,14 @@ c_common_nodes_and_builtins ()
|
||||
const_string_type_node,
|
||||
endlink)));
|
||||
|
||||
/* Prototype for strncpy. */
|
||||
string_ftype_string_cstring_sizet
|
||||
= build_function_type (string_type_node,
|
||||
tree_cons (NULL_TREE, string_type_node,
|
||||
tree_cons (NULL_TREE,
|
||||
const_string_type_node,
|
||||
sizetype_endlink)));
|
||||
|
||||
traditional_len_type_node = ((flag_traditional &&
|
||||
c_language != clk_cplusplus)
|
||||
? integer_type_node : sizetype);
|
||||
@ -5001,6 +5010,14 @@ c_common_nodes_and_builtins ()
|
||||
const_string_type_node,
|
||||
endlink)));
|
||||
|
||||
/* Prototype for strncmp. */
|
||||
int_ftype_cstring_cstring_sizet
|
||||
= build_function_type (integer_type_node,
|
||||
tree_cons (NULL_TREE, const_string_type_node,
|
||||
tree_cons (NULL_TREE,
|
||||
const_string_type_node,
|
||||
sizetype_endlink)));
|
||||
|
||||
/* Prototype for strstr, strpbrk, etc. */
|
||||
string_ftype_string_string
|
||||
= build_function_type (string_type_node,
|
||||
@ -5246,8 +5263,11 @@ c_common_nodes_and_builtins ()
|
||||
BUILT_IN_INDEX, BUILT_IN_NORMAL, "index");
|
||||
builtin_function ("__builtin_rindex", string_ftype_string_int,
|
||||
BUILT_IN_RINDEX, BUILT_IN_NORMAL, "rindex");
|
||||
builtin_function ("__builtin_strcmp", int_ftype_string_string,
|
||||
BUILT_IN_STRCMP, BUILT_IN_NORMAL, "strcmp");
|
||||
built_in_decls[BUILT_IN_STRCMP] =
|
||||
builtin_function ("__builtin_strcmp", int_ftype_string_string,
|
||||
BUILT_IN_STRCMP, BUILT_IN_NORMAL, "strcmp");
|
||||
builtin_function ("__builtin_strncmp", int_ftype_cstring_cstring_sizet,
|
||||
BUILT_IN_STRNCMP, BUILT_IN_NORMAL, "strncmp");
|
||||
builtin_function ("__builtin_strstr", string_ftype_string_string,
|
||||
BUILT_IN_STRSTR, BUILT_IN_NORMAL, "strstr");
|
||||
builtin_function ("__builtin_strpbrk", string_ftype_string_string,
|
||||
@ -5259,6 +5279,8 @@ c_common_nodes_and_builtins ()
|
||||
BUILT_IN_STRRCHR, BUILT_IN_NORMAL, "strrchr");
|
||||
builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr,
|
||||
BUILT_IN_STRCPY, BUILT_IN_NORMAL, "strcpy");
|
||||
builtin_function ("__builtin_strncpy", string_ftype_string_cstring_sizet,
|
||||
BUILT_IN_STRNCPY, BUILT_IN_NORMAL, "strncpy");
|
||||
builtin_function ("__builtin_strlen", strlen_ftype,
|
||||
BUILT_IN_STRLEN, BUILT_IN_NORMAL, "strlen");
|
||||
builtin_function ("__builtin_sqrtf", float_ftype_float,
|
||||
@ -5325,6 +5347,8 @@ c_common_nodes_and_builtins ()
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strncmp", int_ftype_cstring_cstring_sizet,
|
||||
BUILT_IN_STRNCMP, BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strstr", string_ftype_string_string, BUILT_IN_STRSTR,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strchr", string_ftype_string_int, BUILT_IN_STRCHR,
|
||||
@ -5335,6 +5359,8 @@ c_common_nodes_and_builtins ()
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strncpy", string_ftype_string_cstring_sizet,
|
||||
BUILT_IN_STRNCPY, BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT,
|
||||
|
@ -3294,6 +3294,8 @@ function as well.
|
||||
@findex strcmp
|
||||
@findex strcpy
|
||||
@findex strlen
|
||||
@findex strncmp
|
||||
@findex strncpy
|
||||
@findex strpbrk
|
||||
@findex strrchr
|
||||
@findex strstr
|
||||
@ -3338,10 +3340,11 @@ The following ISO C89 functions are recognized as builtins unless
|
||||
@samp{-fno-builtin} is specified: @code{abs}, @code{cos}, @code{fabs},
|
||||
@code{fputs}, @code{labs}, @code{memcmp}, @code{memcpy}, @code{memset},
|
||||
@code{printf}, @code{sin}, @code{sqrt}, @code{strchr}, @code{strcmp},
|
||||
@code{strcpy}, @code{strlen}, @code{strpbrk}, @code{strrchr}, and
|
||||
@code{strstr}. All of these functions have corresponding versions
|
||||
prefixed with @code{__builtin_}, except that the version for @code{sqrt}
|
||||
is called @code{__builtin_fsqrt}.
|
||||
@code{strcpy}, @code{strlen}, @code{strncmp}, @code{strncpy},
|
||||
@code{strpbrk}, @code{strrchr}, and @code{strstr}. All of these
|
||||
functions have corresponding versions prefixed with @code{__builtin_},
|
||||
except that the version for @code{sqrt} is called
|
||||
@code{__builtin_fsqrt}.
|
||||
|
||||
GNU CC provides builtin versions of the ISO C99 floating point
|
||||
comparison macros (that avoid raising exceptions for unordered
|
||||
|
71
gcc/testsuite/gcc.c-torture/execute/string-opt-7.c
Normal file
71
gcc/testsuite/gcc.c-torture/execute/string-opt-7.c
Normal file
@ -0,0 +1,71 @@
|
||||
/* Copyright (C) 2000 Free Software Foundation.
|
||||
|
||||
Ensure all expected transformations of builtin strncpy occur and
|
||||
perform correctly.
|
||||
|
||||
Written by Kaveh R. Ghazi, 11/25/2000. */
|
||||
|
||||
extern void abort (void);
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
extern char *strncpy (char *, const char *, size_t);
|
||||
extern int strcmp (const char *, const char *);
|
||||
extern int strncmp (const char *, const char *, size_t);
|
||||
extern void *memset (void *, int, size_t);
|
||||
|
||||
int main ()
|
||||
{
|
||||
const char *const src = "hello world";
|
||||
const char *src2;
|
||||
char dst[64], *dst2;
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
if (strncpy (dst, src, 4) != dst || strncmp (dst, src, 4))
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
if (strncpy (dst+16, src, 4) != dst+16 || strncmp (dst+16, src, 4))
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
if (strncpy (dst+32, src+5, 4) != dst+32 || strncmp (dst+32, src+5, 4))
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
dst2 = dst;
|
||||
if (strncpy (++dst2, src+5, 4) != dst+1 || strncmp (dst2, src+5, 4)
|
||||
|| dst2 != dst+1)
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
if (strncpy (dst, src, 0) != dst || strcmp (dst, ""))
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
dst2 = dst; src2 = src;
|
||||
if (strncpy (++dst2, ++src2, 0) != dst+1 || strcmp (dst2, "")
|
||||
|| dst2 != dst+1 || src2 != src+1)
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
dst2 = dst; src2 = src;
|
||||
if (strncpy (++dst2+5, ++src2+5, 0) != dst+6 || strcmp (dst2+5, "")
|
||||
|| dst2 != dst+1 || src2 != src+1)
|
||||
abort();
|
||||
|
||||
memset (dst, 0, sizeof (dst));
|
||||
if (strncpy (dst, src, 12) != dst || strcmp (dst, src))
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
/* When optimizing, all the above cases should be transformed into
|
||||
something else. So any remaining calls to the original function
|
||||
should abort. */
|
||||
static char *
|
||||
strncpy(char *s1, const char *s2, size_t n)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
#endif
|
60
gcc/testsuite/gcc.c-torture/execute/string-opt-8.c
Normal file
60
gcc/testsuite/gcc.c-torture/execute/string-opt-8.c
Normal file
@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 2000 Free Software Foundation.
|
||||
|
||||
Ensure all expected transformations of builtin strncmp occur and
|
||||
perform correctly.
|
||||
|
||||
Written by Kaveh R. Ghazi, 11/26/2000. */
|
||||
|
||||
extern void abort (void);
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
extern int strncmp (const char *, const char *, size_t);
|
||||
|
||||
int main ()
|
||||
{
|
||||
const char *const s1 = "hello world";
|
||||
const char *s2, *s3;
|
||||
|
||||
if (strncmp (s1, "hello world", 12) != 0)
|
||||
abort();
|
||||
if (strncmp ("hello world", s1, 12) != 0)
|
||||
abort();
|
||||
if (strncmp ("hello", "hello", 6) != 0)
|
||||
abort();
|
||||
if (strncmp ("hello", "hello", 2) != 0)
|
||||
abort();
|
||||
if (strncmp ("hello", "hello", 100) != 0)
|
||||
abort();
|
||||
if (strncmp (s1+10, "d", 100) != 0)
|
||||
abort();
|
||||
if (strncmp (10+s1, "d", 100) != 0)
|
||||
abort();
|
||||
if (strncmp ("d", s1+10, 1) != 0)
|
||||
abort();
|
||||
if (strncmp ("d", 10+s1, 1) != 0)
|
||||
abort();
|
||||
if (strncmp ("hello", "aaaaa", 100) <= 0)
|
||||
abort();
|
||||
if (strncmp ("aaaaa", "hello", 100) >= 0)
|
||||
abort();
|
||||
if (strncmp ("hello", "aaaaa", 1) <= 0)
|
||||
abort();
|
||||
if (strncmp ("aaaaa", "hello", 1) >= 0)
|
||||
abort();
|
||||
|
||||
s2 = s1; s3 = s1+4;
|
||||
if (strncmp (++s2, ++s3, 0) != 0 || s2 != s1+1 || s3 != s1+5)
|
||||
abort();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __OPTIMIZE__
|
||||
/* When optimizing, all the above cases should be transformed into
|
||||
something else. So any remaining calls to the original function
|
||||
should abort. */
|
||||
static char *
|
||||
strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user