From patchwork Wed Dec 22 22:46:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 76452 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id DD2B4B7088 for ; Thu, 23 Dec 2010 09:47:01 +1100 (EST) Received: (qmail 5910 invoked by alias); 22 Dec 2010 22:46:59 -0000 Received: (qmail 5900 invoked by uid 22791); 22 Dec 2010 22:46:57 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, RFC_ABUSE_POST X-Spam-Check-By: sourceware.org Received: from mail-qy0-f182.google.com (HELO mail-qy0-f182.google.com) (209.85.216.182) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 22 Dec 2010 22:46:52 +0000 Received: by qyk36 with SMTP id 36so5877095qyk.20 for ; Wed, 22 Dec 2010 14:46:50 -0800 (PST) MIME-Version: 1.0 Received: by 10.229.229.132 with SMTP id ji4mr6392786qcb.285.1293058010327; Wed, 22 Dec 2010 14:46:50 -0800 (PST) Received: by 10.229.137.136 with HTTP; Wed, 22 Dec 2010 14:46:50 -0800 (PST) In-Reply-To: References: Date: Wed, 22 Dec 2010 23:46:50 +0100 Message-ID: Subject: [patch c++]:PR/15774 - Conflicting function decls not diagnosed (this time really for 15774) From: Kai Tietz To: GCC Patches Cc: Jason Merrill X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 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) +{ +} + +