diff mbox

[c++] :PR/15774 - Conflicting function decls not diagnosed (this time really for 15774)

Message ID AANLkTi=nmhXXFAJziR9-B89oswb=xQPLkxKzJh_D4Eea@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz Dec. 22, 2010, 10:46 p.m. UTC
Hi,

This time with the correct version of patch and changelog for the bug
described at
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15774 in bugzilla.
It takes care about the following problematic. If there was an old
function prototype, and the new one has same or none attributes as the
old one, C++ accepts.
This behavior is unlikely to the C case, where this condition is
warned or in some cases even
errored out. If the new declaration specifies attributes, which aren't
identical to the old
declaration, an error has to be emitted.

ChangeLog gcc/cp

2010-12-22  Kai Tietz

      PR c++/15774
      * cp-tree.h (COMPARE_ALLOW_FIRST_NO_ATTRIBUTES): New define.
      * decl.c (decls_match): Compare parameter and function types
      by COMPARE_ALLOW_FIRST_NO_ATTRIBUTES.
      * typeck.c (structural_comptypes): Handle new flag.


ChangeLog gcc/testsuite

       PR c++/15774
       * g++.dg/pr15774-1.C: New test.
       * g++.dg/pr15774-2.C: New test.

Tested for i686-pc-cygwin, i686-pc-mingw32, and x86_64-w64-mingw32.

Ok for apply?

Regards,
Kai
diff mbox

Patch

Index: gcc/gcc/cp/cp-tree.h
===================================================================
--- gcc.orig/gcc/cp/cp-tree.h	2010-12-17 21:52:25.000000000 +0100
+++ gcc/gcc/cp/cp-tree.h	2010-12-22 20:31:54.963786500 +0100
@@ -4276,6 +4276,10 @@  enum overload_flags { NO_SPECIAL = 0, DT
 				   structural. The actual comparison
 				   will be identical to
 				   COMPARE_STRICT.  */
+#define COMPARE_ALLOW_FIRST_NO_ATTRIBUTES 16
+				/* Allow identity for two types, if difference
+				   is in attributes only and first (the new)
+				   has no attributes specified.  */
 
 /* Used with push_overloaded_decl.  */
 #define PUSH_GLOBAL	     0  /* Push the DECL into namespace scope,
Index: gcc/gcc/cp/decl.c
===================================================================
--- gcc.orig/gcc/cp/decl.c	2010-12-17 21:52:25.000000000 +0100
+++ gcc/gcc/cp/decl.c	2010-12-22 20:31:29.549332800 +0100
@@ -1009,7 +1009,12 @@  decls_match (tree newdecl, tree olddecl)
 	    }
 #endif
 	  else
-	    types_match = compparms (p1, p2);
+	    types_match = compparms (p1, p2)
+			  && comptypes (TREE_TYPE (newdecl),
+					TREE_TYPE (olddecl),
+					COMPARE_REDECLARATION
+					| COMPARE_ALLOW_FIRST_NO_ATTRIBUTES
+				       );
 	}
       else
 	types_match = 0;
Index: gcc/gcc/cp/typeck.c
===================================================================
--- gcc.orig/gcc/cp/typeck.c	2010-12-17 21:52:25.000000000 +0100
+++ gcc/gcc/cp/typeck.c	2010-12-22 20:31:46.535304400 +0100
@@ -1146,6 +1146,8 @@  comp_template_parms_position (tree t1, t
 static bool
 structural_comptypes (tree t1, tree t2, int strict)
 {
+  int attr_comp = 1;
+
   if (t1 == t2)
     return true;
 
@@ -1250,7 +1252,8 @@  structural_comptypes (tree t1, tree t2,
 
     case OFFSET_TYPE:
       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
-		      strict & ~COMPARE_REDECLARATION))
+		      strict & ~(COMPARE_REDECLARATION
+				 | COMPARE_ALLOW_FIRST_NO_ATTRIBUTES)))
 	return false;
       if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
 	return false;
@@ -1338,7 +1341,16 @@  structural_comptypes (tree t1, tree t2,
   /* If we get here, we know that from a target independent POV the
      types are the same.  Make sure the target attributes are also
      the same.  */
-  return targetm.comp_type_attributes (t1, t2);
+  attr_comp = targetm.comp_type_attributes (t1, t2);
+  if (attr_comp || (TREE_CODE (t1) != FUNCTION_TYPE
+  		    && TREE_CODE (t1) != METHOD_TYPE))
+    return attr_comp;
+  /* If new type T1 has no attributes, and therefore match fails, allow
+     check if COMPARE_ALLOW_FIRST_NO_ATTRIBUTES is defined.  */
+  if ((strict & COMPARE_ALLOW_FIRST_NO_ATTRIBUTES) !=0
+      && TYPE_ATTRIBUTES (t1) == NULL)
+    attr_comp = 1;
+  return attr_comp;
 }
 
 /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
Index: gcc/gcc/testsuite/g++.dg/pr15774-1.C
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/g++.dg/pr15774-1.C	2010-12-22 21:09:50.303928500 +0100
@@ -0,0 +1,15 @@ 
+// { dg-do compile { target i?86-*-* } }
+// Test that an new declartion with different attributes then old one fail.
+extern void foo (int); // { dg-error "ambiguates old declaration" }
+
+void
+bar (void)
+{
+  foo (1);
+}
+
+void __attribute__((stdcall)) foo (int i) // { dg-error "new declaration" }
+{
+}
+
+
Index: gcc/gcc/testsuite/g++.dg/pr15774-2.C
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gcc/gcc/testsuite/g++.dg/pr15774-2.C	2010-12-22 21:08:46.691290000 +0100
@@ -0,0 +1,15 @@ 
+// { dg-do compile { target i?86-*-* } }
+// Test that old declaration is used, if new one has no attributes.
+extern void __attribute__((stdcall)) foo (int);
+
+void
+bar (void)
+{
+  foo (1);
+}
+
+void foo (int i)
+{
+}
+
+