This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCHv4][Kasan] Allow to override Asan shadow offset from command line


On 10/17/2014 04:32 PM, Ian Lance Taylor wrote:
Jakub Jelinek <jakub@redhat.com> writes:

Not sure if there aren't extra steps to make strtoull prototype available
in system.h, libiberty.h etc. for systems that don't have strtoull in their
headers.

See the

#if defined(HAVE_DECL_XXX) && !HAVE_DECL_XXX

lines in include/libiberty.h.  Although strtol is missing there as well.

Thanks, here is a new version of patch which adds support for strtoll and strtoull and also a small test for strtol family.

There some open questions though:

1) how am to test libiberty patches like this? Glibc obviously has strtoll and strtoull so I won't get it in my libiberty.a by default. For now I manually embed strtoll.o/strtoull.o into libiberty.a and run tests by hand but that doesn't sound quite robust and also just x64 is probably not enough as well.

2) I had to use __extension__ keyword to hide warnings from -Wlong-long. Unfortunately it does not fix spurious warnings for long long constants in older versions of GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7263). I guess that's fine.

-Y

commit d78d8daeec19531014c703894dc67db1430f6cbb
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Thu Oct 16 18:31:10 2014 +0400

    Add strtoll and strtoull to libiberty.
    
    2014-10-20  Yury Gribov  <y.gribov@samsung.com>
    
    include/
    	* libiberty.h (strtol, strtoul, strtoll, strtoull): New prototypes.
    
    libiberty/
    	* strtoll.c: New file.
    	* strtoull.c: New file.
    	* configure.ac: Add long long checks. Add harness for strtoll and
    	strtoull. Check decls for strtol, strtoul, strtoll, strtoull.
    	* Makefile.in (CFILES, CONFIGURED_OFILES): Added strtoll and strtoull.
    	* config.in: Regenerate.
    	* configure: Regenerate.
    	* functions.texi: Regenerate.
    	* testsuite/Makefile.in (check-strtol): New rule.
    	(test-strtol): Likewise.
    	(mostlyclean): Clean up strtol test.
    	* testsuite/test-strtol.c: New test.

diff --git a/include/libiberty.h b/include/libiberty.h
index d09c9a5..26355a9 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -655,6 +655,33 @@ extern size_t strnlen (const char *, size_t);
 extern int strverscmp (const char *, const char *);
 #endif
 
+#if defined(HAVE_DECL_STRTOL) && !HAVE_DECL_STRTOL
+extern long int strtol (const char *nptr,
+                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOUL) && !HAVE_DECL_STRTOUL
+extern unsigned long int strtoul (const char *nptr,
+                                  char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOLL) && !HAVE_DECL_STRTOLL
+__extension__
+extern long long int strtoll (const char *nptr,
+                              char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRTOULL) && !HAVE_DECL_STRTOULL
+__extension__
+extern unsigned long long int strtoull (const char *nptr,
+                                        char **endptr, int base);
+#endif
+
+#if defined(HAVE_DECL_STRVERSCMP) && !HAVE_DECL_STRVERSCMP
+/* Compare version strings.  */
+extern int strverscmp (const char *, const char *);
+#endif
+
 /* Set the title of a process */
 extern void setproctitle (const char *name, ...);
 
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 9b87720..1b0d8ae 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -152,8 +152,8 @@ CFILES = alloca.c argv.c asprintf.c atexit.c				\
 	 spaces.c splay-tree.c stack-limit.c stpcpy.c stpncpy.c		\
 	 strcasecmp.c strchr.c strdup.c strerror.c strncasecmp.c	\
 	 strncmp.c strrchr.c strsignal.c strstr.c strtod.c strtol.c	\
-	 strtoul.c strndup.c strnlen.c strverscmp.c			\
-	timeval-utils.c tmpnam.c					\
+	 strtoll.c strtoul.c strtoull.c strndup.c strnlen.c             \
+	 strverscmp.c timeval-utils.c tmpnam.c				\
 	unlink-if-ordinary.c						\
 	vasprintf.c vfork.c vfprintf.c vprintf.c vsnprintf.c vsprintf.c	\
 	waitpid.c							\
@@ -219,8 +219,8 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(objext)		\
 	 ./strchr.$(objext) ./strdup.$(objext) ./strncasecmp.$(objext)	\
 	 ./strncmp.$(objext) ./strndup.$(objext) ./strnlen.$(objext)	\
 	 ./strrchr.$(objext) ./strstr.$(objext) ./strtod.$(objext)	\
-	 ./strtol.$(objext) ./strtoul.$(objext) ./strverscmp.$(objext)	\
-	./tmpnam.$(objext)						\
+	 ./strtol.$(objext) ./strtoul.$(objext) strtoll.$(objext)	\
+	./strtoull.$(objext) ./tmpnam.$(objext) ./strverscmp.$(objext)	\
 	./vasprintf.$(objext) ./vfork.$(objext) ./vfprintf.$(objext)	\
 	 ./vprintf.$(objext) ./vsnprintf.$(objext) ./vsprintf.$(objext)	\
 	./waitpid.$(objext)
@@ -694,6 +694,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/crc32.c $(OUTPUT_OPTION)
 
+./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/demangle.h $(INCDIR)/libiberty.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/d-demangle.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
+
 ./dwarfnames.$(objext): $(srcdir)/dwarfnames.c $(INCDIR)/dwarf2.def \
 	$(INCDIR)/dwarf2.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -714,14 +725,6 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/dyn-string.c $(OUTPUT_OPTION)
 
-./d-demangle.$(objext): $(srcdir)/d-demangle.c config.h $(INCDIR)/ansidecl.h \
-	$(srcdir)/cp-demangle.h $(INCDIR)/demangle.h \
-	$(INCDIR)/dyn-string.h $(INCDIR)/getopt.h $(INCDIR)/libiberty.h
-	if [ x"$(PICFLAG)" != x ]; then \
-	  $(COMPILE.c) $(PICFLAG) $(srcdir)/d-demangle.c -o pic/$@; \
-	else true; fi
-	$(COMPILE.c) $(srcdir)/d-demangle.c $(OUTPUT_OPTION)
-
 ./fdmatch.$(objext): $(srcdir)/fdmatch.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1471,6 +1474,15 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtol.c $(OUTPUT_OPTION)
 
+./strtoll.$(objext): $(srcdir)/strtoll.c config.h $(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoll.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoll.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoll.c $(OUTPUT_OPTION)
+
 ./strtoul.$(objext): $(srcdir)/strtoul.c config.h $(INCDIR)/ansidecl.h \
 	$(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
@@ -1481,6 +1493,16 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
 	else true; fi
 	$(COMPILE.c) $(srcdir)/strtoul.c $(OUTPUT_OPTION)
 
+./strtoull.$(objext): $(srcdir)/strtoull.c config.h $(INCDIR)/ansidecl.h \
+	$(INCDIR)/safe-ctype.h
+	if [ x"$(PICFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(srcdir)/strtoull.c -o pic/$@; \
+	else true; fi
+	if [ x"$(NOASANFLAG)" != x ]; then \
+	  $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/strtoull.c -o noasan/$@; \
+	else true; fi
+	$(COMPILE.c) $(srcdir)/strtoull.c $(OUTPUT_OPTION)
+
 ./strverscmp.$(objext): $(srcdir)/strverscmp.c $(INCDIR)/ansidecl.h \
 	$(INCDIR)/libiberty.h $(INCDIR)/safe-ctype.h
 	if [ x"$(PICFLAG)" != x ]; then \
diff --git a/libiberty/config.in b/libiberty/config.in
index 1cf9c11..7c05b9d 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -79,6 +79,22 @@
    don't. */
 #undef HAVE_DECL_SNPRINTF
 
+/* Define to 1 if you have the declaration of `strtol', and to 0 if you don't.
+   */
+#undef HAVE_DECL_STRTOL
+
+/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOLL
+
+/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOUL
+
+/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
+   don't. */
+#undef HAVE_DECL_STRTOULL
+
 /* Define to 1 if you have the declaration of `strverscmp', and to 0 if you
    don't. */
 #undef HAVE_DECL_STRVERSCMP
@@ -136,6 +152,9 @@
 /* Define to 1 if you have the <limits.h> header file. */
 #undef HAVE_LIMITS_H
 
+/* Define if you have the `long long' type. */
+#undef HAVE_LONG_LONG
+
 /* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
 #undef HAVE_MACHINE_HAL_SYSINFO_H
 
@@ -280,9 +299,15 @@
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
 /* Define to 1 if you have the `strtoul' function. */
 #undef HAVE_STRTOUL
 
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
 /* Define to 1 if you have the `strverscmp' function. */
 #undef HAVE_STRVERSCMP
 
@@ -439,6 +464,12 @@
 /* The size of `int', as computed by sizeof. */
 #undef SIZEOF_INT
 
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `long long', as computed by sizeof. */
+#undef SIZEOF_LONG_LONG
+
 /* Define if you know the direction of stack growth for your system; otherwise
    it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows
    toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses
diff --git a/libiberty/configure b/libiberty/configure
index 96feaed..4a5e40a 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5124,7 +5124,7 @@ $as_echo "#define NEED_DECLARATION_ERRNO 1" >>confdefs.h
 fi
 
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 # The cast to long int works around a bug in the HP C Compiler
 # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
 # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
@@ -5159,6 +5159,82 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+
+# Check for presense of long long
+ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default"
+if test "x$ac_cv_type_long_long" = x""yes; then :
+
+$as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h
+ # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5
+$as_echo_n "checking size of long long... " >&6; }
+if test "${ac_cv_sizeof_long_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5
+$as_echo "$ac_cv_sizeof_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+_ACEOF
+
+
+fi
+
 
 # Look for a 64-bit type.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a 64-bit type" >&5
@@ -5387,6 +5463,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -5423,7 +5501,7 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid
@@ -5499,6 +5577,46 @@ fi
 cat >>confdefs.h <<_ACEOF
 #define HAVE_DECL_VSNPRINTF $ac_have_decl
 _ACEOF
+ac_fn_c_check_decl "$LINENO" "strtol" "ac_cv_have_decl_strtol" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtol" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoul" "ac_cv_have_decl_strtoul" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoul" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOUL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoll" "ac_cv_have_decl_strtoll" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoll" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOLL $ac_have_decl
+_ACEOF
+ac_fn_c_check_decl "$LINENO" "strtoull" "ac_cv_have_decl_strtoull" "$ac_includes_default"
+if test "x$ac_cv_have_decl_strtoull" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_STRTOULL $ac_have_decl
+_ACEOF
 
 
 $as_echo "#define HAVE_SYS_ERRLIST 1" >>confdefs.h
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index 3380819..90adaea 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -272,8 +272,14 @@ AC_HEADER_TIME
 
 libiberty_AC_DECLARE_ERRNO
 
-# Determine the size of an int for struct fibnode.
+# Determine sizes of some types.
 AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long])
+
+# Check for presense of long long
+AC_CHECK_TYPE([long long],
+  [AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have the `long long' type.]) AC_CHECK_SIZEOF([long long])],
+  [])
 
 # Look for a 64-bit type.
 AC_MSG_CHECKING([for a 64-bit type])
@@ -365,6 +371,8 @@ funcs="$funcs strstr"
 funcs="$funcs strtod"
 funcs="$funcs strtol"
 funcs="$funcs strtoul"
+funcs="$funcs strtoll"
+funcs="$funcs strtoull"
 funcs="$funcs strverscmp"
 funcs="$funcs tmpnam"
 funcs="$funcs vasprintf"
@@ -401,11 +409,11 @@ if test "x" = "y"; then
     sbrk setenv setproctitle setrlimit sigsetmask snprintf spawnve spawnvpe \
      stpcpy stpncpy strcasecmp strchr strdup \
      strerror strncasecmp strndup strnlen strrchr strsignal strstr strtod \
-     strtol strtoul strverscmp sysconf sysctl sysmp \
+     strtol strtoul strtoll strtoull strverscmp sysconf sysctl sysmp \
     table times tmpnam \
     vasprintf vfprintf vprintf vsprintf \
     wait3 wait4 waitpid)
-  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf])
+  AC_CHECK_DECLS([basename(char *), ffs, asprintf, vasprintf, snprintf, vsnprintf, strtol, strtoul, strtoll, strtoull])
   AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
   AC_DEFINE(HAVE_SYS_NERR,    1, [Define if you have the sys_nerr variable.])
   AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
diff --git a/libiberty/functions.texi b/libiberty/functions.texi
index 387aee0..3627285 100644
--- a/libiberty/functions.texi
+++ b/libiberty/functions.texi
@@ -1714,6 +1714,24 @@ that the converted value is unsigned.
 
 @end deftypefn
 
+@c strtoll.c:33
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
 @c strsignal.c:502
 @deftypefn Extension int strtosigno (const char *@var{name})
 
diff --git a/libiberty/strtoll.c b/libiberty/strtoll.c
new file mode 100644
index 0000000..37ff8cd
--- /dev/null
+++ b/libiberty/strtoll.c
@@ -0,0 +1,175 @@
+/*-
+ * Copyright (c) 2014 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+
+@deftypefn Supplemental {long long int} strtoll (const char *@var{string}, @
+  char **@var{endptr}, int @var{base})
+@deftypefnx Supplemental {unsigned long long int} strtoul (@
+  const char *@var{string}, char **@var{endptr}, int @var{base})
+
+The @code{strtoll} function converts the string in @var{string} to a
+long long integer value according to the given @var{base}, which must be
+between 2 and 36 inclusive, or be the special value 0.  If @var{base}
+is 0, @code{strtoll} will look for the prefixes @code{0} and @code{0x}
+to indicate bases 8 and 16, respectively, else default to base 10.
+When the base is 16 (either explicitly or implicitly), a prefix of
+@code{0x} is allowed.  The handling of @var{endptr} is as that of
+@code{strtod} above.  The @code{strtoull} function is the same, except
+that the converted value is unsigned.
+
+@end deftypefn
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+__extension__
+typedef long long llong_type;
+
+/* FIXME: It'd be nice to configure around these, but the include files are too
+   painful.  These macros should at least be more portable than hardwired hex
+   constants. */
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX ((llong_type)(ULLONG_MAX >> 1)) /* 0x7FFFFFFFFFFFFFFF */
+#endif
+
+#ifndef LLONG_MIN
+#define LLONG_MIN (~LLONG_MAX) /* 0x8000000000000000 */
+#endif
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+llong_type
+strtoll(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set any if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? -(ullong_type)LLONG_MIN : LLONG_MAX;
+	cutlim = cutoff % (ullong_type)base;
+	cutoff /= (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LLONG_MIN : LLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/strtoull.c b/libiberty/strtoull.c
new file mode 100644
index 0000000..2f580fb
--- /dev/null
+++ b/libiberty/strtoull.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2014 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. [rescinded 22 July 1999]
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <errno.h>
+#ifdef NEED_DECLARATION_ERRNO
+extern int errno;
+#endif
+#if 0
+#include <stdlib.h>
+#endif
+#include "ansidecl.h"
+#include "safe-ctype.h"
+
+#ifdef HAVE_LONG_LONG
+
+__extension__
+typedef unsigned long long ullong_type;
+
+#ifndef ULLONG_MAX
+#define ULLONG_MAX (~(ullong_type)0) /* 0xFFFFFFFFFFFFFFFF */
+#endif
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Ignores `locale' stuff.  Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+ullong_type
+strtoull(const char *nptr, char **endptr, register int base)
+{
+	register const char *s = nptr;
+	register ullong_type acc;
+	register int c;
+	register ullong_type cutoff;
+	register int neg = 0, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	do {
+		c = *s++;
+	} while (ISSPACE(c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else if (c == '+')
+		c = *s++;
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X')) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	cutoff = (ullong_type)ULLONG_MAX / (ullong_type)base;
+	cutlim = (ullong_type)ULLONG_MAX % (ullong_type)base;
+	for (acc = 0, any = 0;; c = *s++) {
+		if (ISDIGIT(c))
+			c -= '0';
+		else if (ISALPHA(c))
+			c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULLONG_MAX;
+		errno = ERANGE;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != 0)
+		*endptr = (char *) (any ? s - 1 : nptr);
+	return (acc);
+}
+
+#endif /* ifdef HAVE_LONG_LONG */
diff --git a/libiberty/testsuite/Makefile.in b/libiberty/testsuite/Makefile.in
index bb2db67..4324a8f 100644
--- a/libiberty/testsuite/Makefile.in
+++ b/libiberty/testsuite/Makefile.in
@@ -45,7 +45,8 @@ all:
 # CHECK is set to "really_check" or the empty string by configure.
 check: @CHECK@
 
-really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv
+really-check: check-cplus-dem check-d-demangle check-pexecute check-expandargv \
+		check-strtol
 
 # Run some tests of the demangler.
 check-cplus-dem: test-demangle $(srcdir)/demangle-expected
@@ -62,6 +63,10 @@ check-pexecute: test-pexecute
 check-expandargv: test-expandargv
 	./test-expandargv
 
+# Check the strtol functionality
+check-strtol: test-strtol
+	./test-strtol
+
 # Run the demangler fuzzer
 fuzz-demangler: demangler-fuzzer
 	./demangler-fuzzer
@@ -79,6 +84,10 @@ test-expandargv: $(srcdir)/test-expandargv.c ../libiberty.a
 	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-expandargv \
 		$(srcdir)/test-expandargv.c ../libiberty.a
 
+test-strtol: $(srcdir)/test-strtol.c ../libiberty.a
+	$(TEST_COMPILE) -DHAVE_CONFIG_H -I.. -o test-strtol \
+		$(srcdir)/test-strtol.c ../libiberty.a
+
 demangler-fuzzer: $(srcdir)/demangler-fuzzer.c ../libiberty.a
 	$(TEST_COMPILE) -o demangler-fuzzer \
 		$(srcdir)/demangler-fuzzer.c ../libiberty.a
@@ -92,6 +101,7 @@ mostlyclean:
 	rm -f test-demangle
 	rm -f test-pexecute
 	rm -f test-expandargv
+	rm -f test-strtol
 	rm -f demangler-fuzzer
 	rm -f core
 clean: mostlyclean
diff --git a/libiberty/testsuite/test-strtol.c b/libiberty/testsuite/test-strtol.c
new file mode 100644
index 0000000..e797c47
--- /dev/null
+++ b/libiberty/testsuite/test-strtol.c
@@ -0,0 +1,182 @@
+/* Test program for strtol family of funtions,
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Yury Gribov <y.gribov@samsung.com>
+
+   This file is part of the libiberty library, which is part of GCC.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combined
+   executable.)
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "libiberty.h"
+#include <stdio.h>
+#include <errno.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+
+/* Test input data. */
+
+enum conversion_fun
+{
+  STRTOL,
+  STRTOLL,
+  STRTOUL,
+  STRTOULL,
+};
+
+#ifdef HAVE_LONG_LONG
+typedef unsigned long long integer_type;
+#else
+typedef unsigned long integer_type;
+#endif
+
+struct test_data_t
+{
+  enum conversion_fun fun;
+  const char *nptr;
+  int base;
+  integer_type res;
+  int errnum;
+};
+
+const struct test_data_t test_data[] = {
+  { STRTOL,  "0x123",       0, 0x123L,        0      },
+  { STRTOL,  "123",         0, 123L,          0      },
+  { STRTOL,  "0123",        0, 0123L,         0      },
+  { STRTOL,  "0x7FFFFFFF",  0, 0x7fffffffL,   0      },
+  { STRTOL,  "-0x80000000", 0, -0x80000000L,  0      },
+  { STRTOUL, "0x123",       0, 0x123UL,       0      },
+  { STRTOUL, "123",         0, 123UL,         0      },
+  { STRTOUL, "0123",        0, 0123UL,        0      },
+  { STRTOUL, "0xFFFFFFFF",  0, 0xffffffffUL,  0      },
+#if SIZEOF_LONG == 4
+  { STRTOL,  "0x80000000",  0, 0x7fffffffL,   ERANGE },
+  { STRTOL,  "-0x80000001", 0, -0x80000000L,  ERANGE },
+  { STRTOUL, "0x100000000", 0, 0xffffffffUL,  ERANGE },
+#endif
+#ifdef HAVE_LONG_LONG
+  { STRTOLL,  "0x123",               0, 0x123LL,               0      },
+  { STRTOLL,  "123",                 0, 123LL,                 0      },
+  { STRTOLL,  "0123",                0, 0123LL,                0      },
+  { STRTOLL,  "0x7FFFFFFFFFFFFFFF",  0, 0x7fffffffffffffffLL,  0      },
+  { STRTOLL,  "-0x8000000000000000", 0, -0x8000000000000000LL, 0      },
+  { STRTOULL, "0x123",               0, 0x123ULL,              0      },
+  { STRTOULL, "123",                 0, 123ULL,                0      },
+  { STRTOULL, "0123",                0, 0123ULL,               0      },
+  { STRTOULL, "0xFFFFFFFFFFFFFFFF",  0, 0xffffffffffffffffULL, 0      },
+#if SIZEOF_LONG_LONG == 8
+  { STRTOLL,  "0x8000000000000000",  0, 0x7fffffffffffffffLL,  ERANGE },
+  { STRTOLL,  "-0x8000000000000001", 0, -0x8000000000000000LL, ERANGE },
+  { STRTOULL, "0x10000000000000000", 0, 0xffffffffffffffffULL, ERANGE },
+#endif
+#endif
+};
+
+/* run_tests:
+    Run conversion function
+    Compare results
+    Return number of fails */
+
+int
+run_tests (const struct test_data_t *test_data, size_t ntests)
+{
+  int fails = 0, failed;
+  size_t i;
+
+  for (i = 0; i < ntests; ++i)
+    {
+      integer_type res;
+      int saved_errno;
+
+      errno = 0;
+
+      switch (test_data[i].fun)
+	{
+	case STRTOL:
+	  res = strtol (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOUL:
+	  res = strtoul (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOLL:
+	  res = strtoll (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	case STRTOULL:
+	  res = strtoull (test_data[i].nptr, 0, test_data[i].base);
+	  break;
+	}
+
+      saved_errno = errno;
+
+      failed = 0;
+
+      /* Compare result */
+      if (res != test_data[i].res)
+        {
+          printf ("FAIL: test-strtol-%zd. Results don't match.\n", i);
+	  failed++;
+        }
+
+      /* Compare errno */
+      if (saved_errno != test_data[i].errnum)
+        {
+          printf ("FAIL: test-strtol-%zd. Errnos don't match.\n", i);
+	  failed++;
+        }
+
+      if (!failed)
+        printf ("PASS: test-strtol-%zd.\n", i);
+      else
+        fails++;
+    }
+
+  return fails;
+}
+
+int 
+main(int argc, char **argv)
+{
+  int fails;
+  fails = run_tests (test_data, sizeof (test_data) / sizeof (test_data[0]));
+  exit (fails ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]