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: static-after-extern tests vs. mips explicit relocs


"Kaveh R. Ghazi" <ghazi@caip.rutgers.edu> writes:
>  > Richard, I'd be inclined to simply remove the "static" from each of
>  > these declarations, rather than have that [static_after_extern] tcl
>  > check.
>  > r~
> 
> As I recall, we ran into problems when they were extern because if the
> abort-ified function is called from a startup module before `main'
> we'll get a spurious crash.
> 
> [dig dig dig] ah here we are, it was you (rth) who did it ;-)
> http://gcc.gnu.org/ml/gcc-patches/2000-11/msg00466.html

I suppose one way of getting around this would be to introduce a
variable such as "inside_main" that is set at the beginning of main()
and cleared at the end.  The library functions would then only abort
while inside_main is true.  At other times they would behave normally.

I tried that with the patch below.  Unfortunately, making the functions
extern causes the tests to fail at -O3 (i686-pc-linux-gnu as well as mips
targets).  The problem is that we're seeing the definition of the library
functions before expanding main().  And duplicate_decls() says:

      if (DECL_BUILT_IN (olddecl))
	{
	  /* Get rid of any built-in function if new arg types don't match it
	     or if we have a function definition.  */

When the definitions were static, they didn't override the builtins.
Now they do, so they're no longer builtins within main().

Any suggestions?

Richard


Index: testsuite/gcc.c-torture/execute/string-opt-3.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/string-opt-3.c,v
retrieving revision 1.6
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.6 string-opt-3.c
*** testsuite/gcc.c-torture/execute/string-opt-3.c	21 Jan 2003 19:43:53 -0000	1.6
--- testsuite/gcc.c-torture/execute/string-opt-3.c	8 May 2003 17:13:14 -0000
*************** extern char *rindex (const char *, int);
*** 13,23 ****
--- 13,26 ----
  
  int x = 6;
  char *bar = "hi world";
+ int inside_main;
  
  int main()
  {
    const char *const foo = "hello world";
  
+   inside_main = 1;
+ 
    if (strlen (foo) != 11)
      abort ();
    if (strlen (foo + 4) != 7)
*************** int main()
*** 84,127 ****
    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
--- 87,162 ----
    if (__builtin_strcmp (foo, "hello") <= 0)
      abort ();
  
+   inside_main = 0;
    return 0;
  }
  
! __attribute__ ((noinline))
! char *
  rindex (const char *s, int c)
  {
  #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
  #endif
+   return strrchr (s, c);
  }
  
  /* When optimizing, all the above cases should be transformed into
     something else.  So any remaining calls to the original function
     should abort.  */
  __attribute__ ((noinline))
! __SIZE_TYPE__
  strlen (const char *s)
  {
!   __SIZE_TYPE__ i;
! 
! #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
! #endif
! 
!   for (i = 0; s[i] != 0; i++)
!     continue;
!   return i;
  }
  
  __attribute__ ((noinline))
! 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;
  }
  
  __attribute__ ((noinline))
! 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;
+ }
Index: testsuite/gcc.c-torture/execute/string-opt-4.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/string-opt-4.c,v
retrieving revision 1.5
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.5 string-opt-4.c
*** testsuite/gcc.c-torture/execute/string-opt-4.c	21 Jan 2003 19:43:53 -0000	1.5
--- testsuite/gcc.c-torture/execute/string-opt-4.c	8 May 2003 17:13:14 -0000
*************** extern void abort (void);
*** 9,18 ****
--- 9,22 ----
  extern char *strchr (const char *, int);
  extern char *index (const char *, int);
  
+ int inside_main;
+ 
  int main()
  {
    const char *const foo = "hello world";
  
+   inside_main = 1;
+ 
    if (strchr (foo, 'x'))
      abort ();
    if (strchr (foo, 'o') != foo + 4)
*************** int main()
*** 33,62 ****
    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
--- 37,74 ----
    if (__builtin_index (foo, 'o')  != foo + 4)
      abort ();
  
+   inside_main = 0;
    return 0;
  }
  
! char *
  index (const char *s, int c)
  {
  #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
  #endif
+   return strchr (s, c);
  }
  
  /* When optimizing, all the above cases should be transformed into
     something else.  So any remaining calls to the original function
     should abort.  */
  __attribute__ ((noinline))
! char *
  strchr (const char *s, int c)
  {
! #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
  #endif
+ 
+   for (;;)
+     {
+       if (*s == c)
+ 	return s;
+       if (*s == 0)
+ 	return 0;
+       s++;
+     }
+ }
Index: testsuite/gcc.c-torture/execute/string-opt-17.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/string-opt-17.c,v
retrieving revision 1.2
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.2 string-opt-17.c
*** testsuite/gcc.c-torture/execute/string-opt-17.c	21 Jan 2003 19:43:53 -0000	1.2
--- testsuite/gcc.c-torture/execute/string-opt-17.c	8 May 2003 17:13:14 -0000
*************** typedef __SIZE_TYPE__ size_t;
*** 10,19 ****
--- 10,22 ----
  extern void *memset (void *, int, size_t);
  
  char buffer[32];
+ int inside_main;
  
  int
  main (int argc)
  {
+   inside_main = 1;
+ 
    memset (buffer, argc, 0);
    memset (buffer, argc, 1);
    memset (buffer, argc, 2);
*************** main (int argc)
*** 33,51 ****
    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
  
--- 36,59 ----
    memset (buffer, argc, 16);
    memset (buffer, argc, 17);
  
+   inside_main = 0;
    return 0;
  }
  
  /* 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))
! void *
  memset (void *dst, int c, size_t len)
  {
! #ifdef __OPTIMIZE__
!   if (inside_main && len < 2)
      abort ();
  #endif
+ 
+   while (len-- > 0)
+     len[(char *) dst] = c;
+   return dst;
+ }
  
Index: testsuite/gcc.c-torture/execute/string-opt-18.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/string-opt-18.c,v
retrieving revision 1.3
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.3 string-opt-18.c
*** testsuite/gcc.c-torture/execute/string-opt-18.c	5 May 2003 19:31:35 -0000	1.3
--- testsuite/gcc.c-torture/execute/string-opt-18.c	8 May 2003 17:13:14 -0000
*************** char p[32] = "";
*** 18,29 ****
--- 18,32 ----
  char *s2 = "defg";
  char *s3 = "FGH";
  size_t l1 = 1;
+ int inside_main;
  
  int main()
  {
    int i;
    const char *s;
  
+   inside_main = 1;
+ 
    if (stpcpy (p, "abcde") != p + 5 || memcmp (p, "abcde", 6))
      abort ();
    if (stpcpy (p + 16, "vwxyz" + 1) != p + 16 + 4 || memcmp (p + 16, "wxyz", 5))
*************** int main()
*** 74,104 ****
    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
  }
--- 77,108 ----
    mempcpy (p + 6, s3 + 1, l1);
    if (memcmp (p, "ABCdeFG", 8))
      abort ();
+ 
+   inside_main = 0;
    return 0;
  }
  
  /* When optimizing, all the above cases should be transformed into
     something else.  So any remaining calls to the original function
!    should abort.  */
  __attribute__ ((noinline))
! char *
  stpcpy (char *d, const char *s)
  {
  #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
  #endif
+   return strcpy (d, s) + strlen (s);
  }
  
  __attribute__ ((noinline))
! void *
  mempcpy (void *dst, const void *src, size_t sz)
  {
  #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
  #endif
+   return (char *) memcpy (dst, src, sz) + sz;
  }
Index: testsuite/gcc.c-torture/execute/string-opt-19.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/string-opt-19.c,v
retrieving revision 1.2
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.2 string-opt-19.c
*** testsuite/gcc.c-torture/execute/string-opt-19.c	8 May 2003 13:45:38 -0000	1.2
--- testsuite/gcc.c-torture/execute/string-opt-19.c	8 May 2003 17:13:14 -0000
*************** extern int memcmp (const void *, const v
*** 12,17 ****
--- 12,18 ----
  
  const char s1[] = "123";
  char p[32] = "";
+ int inside_main;
  
  static const struct foo
  {
*************** int main()
*** 61,66 ****
--- 62,69 ----
    struct bar b1[sizeof bar/sizeof*bar];
    int bz[sizeof baz/sizeof*baz];
  
+   inside_main = 1;
+ 
    if (memmove (f1, foo, sizeof (foo)) != f1 || memcmp (f1, foo, sizeof(foo)))
      abort();
    if (memmove (b1, bar, sizeof (bar)) != b1 || memcmp (b1, bar, sizeof(bar)))
*************** int main()
*** 87,106 ****
    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)
--- 90,110 ----
    if (memcmp (p, "abfgAi", 7))
      abort ();
  
+   inside_main = 0;
    return 0;
  }
  
  /* When optimizing, all the above cases should be transformed into
     something else.  So any remaining calls to the original function
!    should abort.  */
  __attribute__ ((noinline))
! void *
  memmove (void *d, const void *s, size_t n)
  {
  #ifdef __OPTIMIZE__
!   if (inside_main)
!     abort ();
! #endif
    char *dst = (char *) d;
    const char *src = (const char *) s;
    if (src < dst)
*************** #else
*** 114,124 ****
      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);
--- 118,127 ----
      while (n--)
        *dst++ = *src++;
    return (char *) d;
  }
  
  __attribute__ ((noinline))
! void
  bcopy (const void *s, void *d, size_t n)
  {
    memmove (d, s, n);
Index: testsuite/gcc.c-torture/execute/builtin-noret-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/builtin-noret-1.c,v
retrieving revision 1.2
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.2 builtin-noret-1.c
*** testsuite/gcc.c-torture/execute/builtin-noret-1.c	11 Jul 2002 12:29:07 -0000	1.2
--- testsuite/gcc.c-torture/execute/builtin-noret-1.c	8 May 2003 17:13:14 -0000
*************** t_exit (void)
*** 50,55 ****
--- 50,56 ----
    link_failure ();
  }
  
+ #if !(defined (__mips) && defined (__linux__))
  /* Some non-Unix libcs might not have _exit.  This version should never
     get called.  */
  static void
*************** _exit (int i)
*** 57,62 ****
--- 58,64 ----
  {
    abort ();
  }
+ #endif
  
  void
  t_Exit (void)
*************** t_Exit (void)
*** 65,76 ****
--- 67,80 ----
    link_failure ();
  }
  
+ #if !(defined (__mips) && defined (__linux__))
  /* Some libcs might not have _Exit.  This version should never get called.  */
  static void
  _Exit (int i)
  {
    abort ();
  }
+ #endif
  
  /* When optimizing, no calls to link_failure should remain.  In any case,
     link_failure should not be called.  */
Index: testsuite/gcc.c-torture/execute/builtin-noret-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.c-torture/execute/builtin-noret-2.c,v
retrieving revision 1.1
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.1 builtin-noret-2.c
*** testsuite/gcc.c-torture/execute/builtin-noret-2.c	11 Apr 2003 04:26:54 -0000	1.1
--- testsuite/gcc.c-torture/execute/builtin-noret-2.c	8 May 2003 17:13:14 -0000
*************** t_exit (void)
*** 49,54 ****
--- 49,55 ----
    link_failure ();
  }
  
+ #if !(defined (__mips) && defined (__linux__))
  /* Some non-Unix libcs might not have _exit.  This version should never
     get called.  */
  static void
*************** _exit (int i)
*** 56,61 ****
--- 57,63 ----
  {
    abort ();
  }
+ #endif
  
  void
  t_Exit (void)
*************** t_Exit (void)
*** 65,76 ****
--- 67,80 ----
    link_failure ();
  }
  
+ #if !(defined (__mips) && defined (__linux__))
  /* Some libcs might not have _Exit.  This version should never get called.  */
  static void
  _Exit (int i)
  {
    abort ();
  }
+ #endif
  
  /* When optimizing, no calls to link_failure should remain.  In any case,
     link_failure should not be called.  */
Index: testsuite/gcc.dg/no-builtin-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/no-builtin-1.c,v
retrieving revision 1.1
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.1 no-builtin-1.c
*** testsuite/gcc.dg/no-builtin-1.c	18 Nov 2001 03:30:57 -0000	1.1
--- testsuite/gcc.dg/no-builtin-1.c	8 May 2003 17:13:14 -0000
***************
*** 2,7 ****
--- 2,8 ----
  /* Origin: Joseph Myers <jsm28@cam.ac.uk>.  */
  /* { dg-do run } */
  /* { dg-options "-fno-builtin-abs" } */
+ /* { dg-options "-fno-builtin-abs -mno-explicit-relocs" { target mips*-*-* } } */
  
  /* GCC normally handles abs and labs as built-in functions even without
     optimization.  So test that with -fno-builtin-abs, labs is so handled


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