From patchwork Mon Feb 24 01:56:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 323418 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 1C55A2C0078 for ; Mon, 24 Feb 2014 12:57:16 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=PXRnNojUMV4M x3LB5zI3loAnGMMm5QZU0Y+8LSuBuxPT4S5nPIWzY+v4fLKnuRjwLt38q9EFKHIh Y0xfniqLaxjJioTmGpLrSFNQPL0VEqqmDELjMFLaQSNHNJ7fZP/pbDZEaR5TMT1m VRvFRXpEyEa9A5xG5BJqLovY7W4m3lY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=dD9s/VkX/E0SQBJ19S J2LDiogQQ=; b=wma4AmV0b0N7lCW8xzAAu+9mLgDNPBgFr9XVdR29rlQm1JzKSP XLjXHDPhqeoq0NcWFvrBYX6kQRMJSAy6xJdVSGUSoeBkuRvTxT3EaFniu6H4DJtt JAGPoe1TLw+teJ2SQHYqeRoKSdUDrxNaO7e6YyLdehQg4tSRImBxr7w+U= Received: (qmail 14885 invoked by alias); 24 Feb 2014 01:57:09 -0000 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 Received: (qmail 14593 invoked by uid 89); 24 Feb 2014 01:57:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 X-HELO: mail-qc0-f170.google.com Received: from mail-qc0-f170.google.com (HELO mail-qc0-f170.google.com) (209.85.216.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 24 Feb 2014 01:57:08 +0000 Received: by mail-qc0-f170.google.com with SMTP id c9so8152846qcz.15 for ; Sun, 23 Feb 2014 17:57:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=qR7i/u4ooBjDh5jCsJaxru7hhe0ut3AN87X/FXfUoi8=; b=O0yxM/n7kgacHTW+QZjy6Uq2MZF2Cz8UBMowCk5WCEraWdNEw7KEiDANdTAGFRk9GH HxS+CWZnU9d2KYGNd5XqTIFgnkfakkMoSDEza9opHiqs4m9XjYwN4L2ChDQJu8GxhAYs UJ4vAm6e5mJzSAdRX4sn/oUlvs3o1MlxF26zH7hRDLTFEbl4fvZP1vSAB6t3iej52uIO /H9U3NsFwT4msoyY7uygZmKNvnoEl0yuG2hD1KwvpbNFw0MCNUBhcnXzDW9ULILsTxQb h73hfisWJWn2phQGehX14SyIDrpFwlgyeFSPg6GxkCZYcxuJ9Y+C/2J4Kla3WWIv8T73 73mA== X-Gm-Message-State: ALoCoQkJuEZWDmEiXj/GSPT27B2Veb3aRHnUPvLHne/Uv+g9VSk+uu/tGgoK/iidzsVmkkOUHd51 X-Received: by 10.224.16.72 with SMTP id n8mr26888977qaa.76.1393207025997; Sun, 23 Feb 2014 17:57:05 -0800 (PST) Received: from localhost.localdomain (ool-4353a9c4.dyn.optonline.net. [67.83.169.196]) by mx.google.com with ESMTPSA id p67sm23438646qgd.8.2014.02.23.17.57.04 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 23 Feb 2014 17:57:04 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: Patrick Palka Subject: [PATCH] Fix PR c++/25940 Date: Sun, 23 Feb 2014 20:56:55 -0500 Message-Id: <1393207015-11364-1-git-send-email-patrick@parcs.ath.cx> Hi, The following patch fixes two issues: the first is PR c++/25940 and the second is related to PR c++/13699. The first issue is that the C++ frontend fails to reject duplicate definitions of functions with C language linkage. This results in the compiler emitting ASM that defines the same symbol more than once. The second issue is that upon encountering a redeclaration of an extern "C" function with a different exception specification, the C++ frontend fails to add the new declaration to the list of things declared in the current namespace. This makes the new declaration appear to be not in scope. I bootstrapped and regtested this patch on x86_64-unknown-linux-gnu. I had a few guality and cilk FAILs but I don't think they are related to this patch. PR c++/25940 * name-lookup.c (pushdecl_maybe_friend_1): Bail when a function with C language linkage is redefined. Don't return error_mark_node after a function with C language linkage is redeclared with a different exception specification. (lookup_extern_c_fun_in_all_ns): Prefer returning an existing function definition instead of a declaration. PR c++/25940 * g++.dg/lookup/extern-c-redecl6.C: New test. * g++.dg/lookup/extern-c-redecl7.C: New test. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index ea16061..0ee4f4c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -861,6 +861,15 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) tree x_exception_spec = NULL_TREE; tree previous_exception_spec = NULL_TREE; + if (DECL_INITIAL (x) && DECL_INITIAL (previous)) + { + error_at (input_location, + "redefinition of %q+#D with C language linkage", + x); + inform (input_location, + "%q+#D previously defined here", previous); + return error_mark_node; + } x_exception_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (x)); previous_exception_spec = @@ -877,7 +886,6 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) previous); pedwarn (input_location, 0, "due to different exception specifications"); - return error_mark_node; } if (DECL_ASSEMBLER_NAME_SET_P (previous)) SET_DECL_ASSEMBLER_NAME (x, @@ -2142,8 +2150,10 @@ binding_for_name (cp_binding_level *scope, tree name) } /* Walk through the bindings associated to the name of FUNCTION, - and return the first declaration of a function with a - "C" linkage specification, a.k.a 'extern "C"'. + and return the first definition of a function with a + "C" linkage specification, a.k.a 'extern "C"'. If no previous + definition exists, return the first declaration of the function. + This function looks for the binding, regardless of which scope it has been defined in. It basically looks in all the known scopes. Note that this function does not lookup for bindings of builtin functions @@ -2152,6 +2162,7 @@ static tree lookup_extern_c_fun_in_all_ns (tree function) { tree name; + tree ret = NULL_TREE; cxx_binding *iter; gcc_assert (function && TREE_CODE (function) == FUNCTION_DECL); @@ -2172,11 +2183,14 @@ lookup_extern_c_fun_in_all_ns (tree function) && DECL_EXTERN_C_P (decl) && !DECL_ARTIFICIAL (decl)) { - return decl; + if (DECL_INITIAL (decl)) + return decl; + if (!ret) + ret = decl; } } } - return NULL; + return ret; } /* Returns a list of C-linkage decls with the name NAME. */ diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C b/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C new file mode 100644 index 0000000..37424d6 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/extern-c-redecl6.C @@ -0,0 +1,29 @@ +// PR c++/25940 + +namespace X { + extern "C" void foo () throw (); +} + +namespace A { + extern "C" void foo () // { dg-message "previously defined" } + { + } +} + +namespace Y { + extern "C" void foo (); +} + +namespace B { + extern "C" void foo () // { dg-error "redefinition" } + { + } +} + +namespace Z { + extern "C" void foo (); +} + +extern "C" void foo () // { dg-error "redefinition" } +{ +} diff --git a/gcc/testsuite/g++.dg/lookup/extern-c-redecl7.C b/gcc/testsuite/g++.dg/lookup/extern-c-redecl7.C new file mode 100644 index 0000000..2210417 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/extern-c-redecl7.C @@ -0,0 +1,12 @@ +namespace A { + extern "C" void foo () throw (); // { dg-error "previous declaration" } +} + +namespace B { + extern "C" void foo (); // { dg-error "declaration of|different exception" } +} + +void bar () +{ + B::foo (); +}