diff options
author | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-09-16 01:20:45 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-09-16 01:20:45 +0000 |
commit | 24f30ed448cf01c0fc89f75ea711fa04440beefc (patch) | |
tree | 8f287ea08cc8d076c9ded0ad71332b7743e7fdae | |
parent | 9605da8a3fda7f5f52221143d6af94e9ed13a306 (diff) | |
download | gcc-24f30ed448cf01c0fc89f75ea711fa04440beefc.zip gcc-24f30ed448cf01c0fc89f75ea711fa04440beefc.tar.gz gcc-24f30ed448cf01c0fc89f75ea711fa04440beefc.tar.bz2 |
decl.c (warn_extern_redeclared_static): Simplify.
* 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.
From-SVN: r29450
-rw-r--r-- | gcc/cp/decl.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.mike/net46.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/linkage3.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/linkage4.C | 11 |
4 files changed, 42 insertions, 21 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 789fe4e..cd42511 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2921,8 +2921,7 @@ decls_match (newdecl, olddecl) } /* 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'.) + 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'. @@ -2934,33 +2933,31 @@ static void 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'"; + 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); - 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); - } - } + 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 @@ -3047,6 +3044,14 @@ duplicate_decls (newdecl, olddecl) /* 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)) { diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net46.C b/gcc/testsuite/g++.old-deja/g++.mike/net46.C index ac79501..8439c34 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/net46.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/net46.C @@ -4,7 +4,7 @@ int fail = 1; -static void *operator new(size_t size) throw (std::bad_alloc) { +void *operator new(size_t size) throw (std::bad_alloc) { --fail; return (void*) 0; } diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage3.C b/gcc/testsuite/g++.old-deja/g++.other/linkage3.C new file mode 100644 index 0000000..d32d770 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/linkage3.C @@ -0,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 diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage4.C b/gcc/testsuite/g++.old-deja/g++.other/linkage4.C new file mode 100644 index 0000000..65772f7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/linkage4.C @@ -0,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 |