This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: problem with builtin functions
- To: Haj dot Ten dot Brugge at net dot HCC dot nl
- Subject: Re: problem with builtin functions
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 15 Sep 1999 18:25:26 -0700
- Cc: egcs-bugs at egcs dot cygnus dot com
- Organization: CodeSourcery, LLC
- References: <199909150658.HAA11592@net.HCC.nl>
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))