decl.c (warn_extern_redeclared_static): Simplify.
authorMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 16 Sep 1999 01:20:45 +0000 (01:20 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Thu, 16 Sep 1999 01:20:45 +0000 (01:20 +0000)
* 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

gcc/cp/decl.c
gcc/testsuite/g++.old-deja/g++.mike/net46.C
gcc/testsuite/g++.old-deja/g++.other/linkage3.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.other/linkage4.C [new file with mode: 0644]

index 789fe4e..cd42511 100644 (file)
@@ -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))
     {
index ac79501..8439c34 100644 (file)
@@ -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 (file)
index 0000000..d32d770
--- /dev/null
@@ -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 (file)
index 0000000..65772f7
--- /dev/null
@@ -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