This is the mail archive of the gcc-bugs@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]

Re: problem with builtin functions



Here's the fix for your bug.  This patch also tightens our handling of
functions declared extern "C"; we did not previously flag redeclaring
such a function as static.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-09-15  Mark Mitchell  <mark@codesourcery.com>

	* decl.c (warn_extern_redeclared_static): Simplify.  Catch
	problems with extern "C" functions redeclared as static.
	(duplicate_decls): When a builtin is redeclared static, make the
	new function have internal linkage.
	
Index: testsuite/g++.old-deja/g++.mike/net46.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.mike/net46.C,v
retrieving revision 1.4
diff -c -p -r1.4 net46.C
*** net46.C	1998/12/16 21:45:58	1.4
--- net46.C	1999/09/16 00:03:39
***************
*** 4,10 ****
  
  int fail = 1;
  
! static void *operator new(size_t size) throw (std::bad_alloc) {
    --fail;
    return (void*) 0;
  }
--- 4,10 ----
  
  int fail = 1;
  
! void *operator new(size_t size) throw (std::bad_alloc) {
    --fail;
    return (void*) 0;
  }
Index: testsuite/g++.old-deja/g++.other/linkage3.C
===================================================================
RCS file: linkage3.C
diff -N linkage3.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- linkage3.C	Wed Sep 15 17:03:39 1999
***************
*** 0 ****
--- 1,5 ----
+ // Build don't link:
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+ 
+ extern "C" void f (); // ERROR - previous declaration
+ static void f () {} // ERROR - extern redeclared static
Index: testsuite/g++.old-deja/g++.other/linkage4.C
===================================================================
RCS file: linkage4.C
diff -N linkage4.C
*** /dev/null	Sat Dec  5 20:30:03 1998
--- linkage4.C	Wed Sep 15 17:03:39 1999
***************
*** 0 ****
--- 1,11 ----
+ // Build don't link:
+ // Origin: Mark Mitchell <mark@codesourcery.com>
+ 
+ static int strlen (const char*) { return 0; }
+ 
+ template <int (*)(const char*)>
+ void f () {}
+ 
+ // Check that the strlen declaration here is given internal linkage by
+ // using it as a non-type template argument, and expecting an error.
+ template void f<strlen>(); // ERROR - no matching template
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.451
diff -c -p -r1.451 decl.c
*** decl.c	1999/09/15 06:09:51	1.451
--- decl.c	1999/09/16 01:15:00
*************** decls_match (newdecl, olddecl)
*** 2921,2928 ****
  }
  
  /* If NEWDECL is `static' and an `extern' was seen previously,
!    warn about it.  (OLDDECL may be NULL_TREE; NAME contains
!    information about previous usage as an `extern'.)
  
     Note that this does not apply to the C++ case of declaring
     a variable `extern const' and then later `const'.
--- 2921,2927 ----
  }
  
  /* If NEWDECL is `static' and an `extern' was seen previously,
!    warn about it.  OLDDECL is the previous declaration.
  
     Note that this does not apply to the C++ case of declaring
     a variable `extern const' and then later `const'.
*************** static void
*** 2934,2966 ****
  warn_extern_redeclared_static (newdecl, olddecl)
       tree newdecl, olddecl;
  {
-   tree name;
- 
    static const char *explicit_extern_static_warning
      = "`%D' was declared `extern' and later `static'";
    static const char *implicit_extern_static_warning
      = "`%D' was declared implicitly `extern' and later `static'";
  
    if (TREE_CODE (newdecl) == TYPE_DECL)
      return;
  
    name = DECL_ASSEMBLER_NAME (newdecl);
!   if (TREE_PUBLIC (name) && DECL_THIS_STATIC (newdecl))
!     {
!       /* It's okay to redeclare an ANSI built-in function as static,
! 	 or to declare a non-ANSI built-in function as anything.  */
!       if (! (TREE_CODE (newdecl) == FUNCTION_DECL
! 	     && olddecl != NULL_TREE
! 	     && TREE_CODE (olddecl) == FUNCTION_DECL
! 	     && DECL_ARTIFICIAL (olddecl)))
! 	{
! 	  cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name)
! 		      ? implicit_extern_static_warning
! 		      : explicit_extern_static_warning, newdecl);
! 	  if (olddecl != NULL_TREE)
! 	    cp_pedwarn_at ("previous declaration of `%D'", olddecl);
! 	}
!     }
  }
  
  /* Handle when a new declaration NEWDECL has the same name as an old
--- 2933,2963 ----
  warn_extern_redeclared_static (newdecl, olddecl)
       tree newdecl, olddecl;
  {
    static const char *explicit_extern_static_warning
      = "`%D' was declared `extern' and later `static'";
    static const char *implicit_extern_static_warning
      = "`%D' was declared implicitly `extern' and later `static'";
  
+   tree name;
+ 
    if (TREE_CODE (newdecl) == TYPE_DECL)
      return;
  
+   /* If the old declaration was `static', or the new one isn't, then
+      then everything is OK.  */
+   if (DECL_THIS_STATIC (olddecl) || !DECL_THIS_STATIC (newdecl))
+     return;
+ 
+   /* It's OK to declare a builtin function as `static'.  */
+   if (TREE_CODE (olddecl) == FUNCTION_DECL
+       && DECL_ARTIFICIAL (olddecl))
+     return;
+ 
    name = DECL_ASSEMBLER_NAME (newdecl);
!   cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name)
! 	      ? implicit_extern_static_warning
! 	      : explicit_extern_static_warning, newdecl);
!   cp_pedwarn_at ("previous declaration of `%D'", olddecl);
  }
  
  /* Handle when a new declaration NEWDECL has the same name as an old
*************** duplicate_decls (newdecl, olddecl)
*** 3046,3051 ****
--- 3043,3056 ----
  	  else
  	    /* Discard the old built-in function.  */
  	    return 0;
+ 	}
+       
+       if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
+ 	{
+ 	  /* If a builtin function is redeclared as `static', merge
+ 	     the declarations, but make the original one static.  */
+ 	  DECL_THIS_STATIC (olddecl) = 1;
+ 	  TREE_PUBLIC (olddecl) = 0;
  	}
      }
    else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))


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