public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] PR c++/41020
@ 2009-10-23 19:48 Dodji Seketeli
  2009-10-23 20:11 ` Jason Merrill
  0 siblings, 1 reply; 10+ messages in thread
From: Dodji Seketeli @ 2009-10-23 19:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason

Hello,

If a builtin function is declared as extern "C", G++ forbids it's
re-declaration, unless the re-declaration is extern "C" as well.

The problem is G++ applies this constraint to friend function re-declarations
as well.

The [class.friend] section of the c++ standards reads:

~=~
4. "A function first declared in a friend declaration has external linkage
Otherwise, the function retains its previous linkage"
~=~

So I am proposing the patch below that relaxes the builtin function
constaint for friend function declarations.

Tested against trunk on x86-64-unknown-linux-gnu.

Comments ?

commit e0e60dd248a92c9743a33e56255d4e5b4017be2d
Author: Dodji Seketeli <dodji@redhat.com>
Date:   Fri Oct 23 21:15:12 2009 +0200

    Fix PR c++/41020
    
    gcc/cp/ChangeLog:
    
    	PR c++/41020
    	* decl.c (decls_match_1): Break this out from decl_match.
    	Make it aware of function friend-ness.
    	(decls_match): Use the new decls_match_1.
    	(duplicate_decls): Likewise.
    
    gcc/testsuite/ChangeLog:
    	PR c++/41020
    	* g++.dg/lookup/friend16.C: New test.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5eb389f..7c01ee2 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -104,6 +104,7 @@ static void store_parm_decls (tree);
 static void initialize_local_var (tree, tree);
 static void expand_static_init (tree, tree);
 static tree next_initializable_field (tree);
+static int decls_match_1 (tree, tree, bool);
 
 /* The following symbols are subsumed in the cp_global_trees array, and
    listed here individually for documentation purposes.
@@ -899,6 +900,14 @@ push_local_name (tree decl)
 int
 decls_match (tree newdecl, tree olddecl)
 {
+  return decls_match_1 (newdecl, olddecl, /* newdecl_is_friend  */ false);
+}
+
+/* Subroutine of decls_match.  */
+
+static int
+decls_match_1 (tree newdecl, tree olddecl, bool newdecl_is_friend)
+{
   int types_match;
 
   if (newdecl == olddecl)
@@ -934,9 +943,11 @@ decls_match (tree newdecl, tree olddecl)
 
 #ifdef NO_IMPLICIT_EXTERN_C
       /* A new declaration doesn't match a built-in one unless it
-	 is also extern "C".  */
+	 is also extern "C". Friend function re-declarations retain the
+	 the linkage of the original declaration though.  */
       if (DECL_BUILT_IN (olddecl)
-	  && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
+	  && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl)
+	  && !newdecl_is_friend)
 	return 0;
 #endif
 
@@ -1122,7 +1133,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
   if (newdecl == olddecl)
     return olddecl;
 
-  types_match = decls_match (newdecl, olddecl);
+  types_match = decls_match_1 (newdecl, olddecl, newdecl_is_friend);
 
   /* If either the type of the new decl or the type of the old decl is an
      error_mark_node, then that implies that we have already issued an
diff --git a/gcc/testsuite/g++.dg/lookup/friend16.C b/gcc/testsuite/g++.dg/lookup/friend16.C
new file mode 100644
index 0000000..e2c7169
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/friend16.C
@@ -0,0 +1,21 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/41020
+// { dg-do compile }
+
+extern "C"
+{
+  int fork (void);
+};
+
+class frok
+{
+  int this_errno;
+  friend int fork (void);
+};
+
+extern "C" int
+fork (void)
+{
+  frok grouped;
+  return grouped.this_errno;
+}

-- 
Dodji Seketeli
Red Hat

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2009-10-25 22:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-23 19:48 [RFA] PR c++/41020 Dodji Seketeli
2009-10-23 20:11 ` Jason Merrill
2009-10-23 22:50   ` Dodji Seketeli
2009-10-24  0:45     ` Jason Merrill
2009-10-24  4:11       ` Dave Korn
2009-10-24  6:20         ` Jason Merrill
2009-10-24  6:33           ` Jason Merrill
2009-10-24  9:12             ` Dave Korn
2009-10-25 11:59       ` Dodji Seketeli
2009-10-25 22:39         ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).