From patchwork Fri Feb 5 12:54:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 579472 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 2B481140328 for ; Fri, 5 Feb 2016 23:54:30 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=r//yCZns; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :date:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=JkCAtOkZrpXIRFXr G6gx2E52z1L6Ju1ztlSfDXDX/l5775NGzw7U1q6oQFdb5Fmql98zHIUGv5rC14fg tCpW5+PQe0T1pBj1kF/+JAdffoosMRISbrDQMmFqd7rZ+/pEU26SZxC9h1RnzB/w ezIKp/lms098xMPSTuoQk3KEOQw= 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 :date:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=jGmCeTdJteVjvIuO+4gnwl 5f67E=; b=r//yCZns1ZTVX4t8YT7+D4uZzzsfTQXKE9fEzbpxVPGHpqb3IdcYLO D6vesAg2bFX6HlbFhU2i/t7J57QGkuEh3BOy9QbHCtY19yJVNcGdeQb0syo0zaLk Ps6cEdWzPWsKxORIMGTvaTblM2bA0FHK0WNvjKREfS1fyJiyYKNjg= Received: (qmail 41685 invoked by alias); 5 Feb 2016 12:54:24 -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 40462 invoked by uid 89); 5 Feb 2016 12:54:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=sk:baselin X-HELO: mail-qk0-f182.google.com Received: from mail-qk0-f182.google.com (HELO mail-qk0-f182.google.com) (209.85.220.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 05 Feb 2016 12:54:21 +0000 Received: by mail-qk0-f182.google.com with SMTP id o6so33454852qkc.2 for ; Fri, 05 Feb 2016 04:54:21 -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:date:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version:content-type; bh=On1X90w56GCB4EWWTqKj4lgqkZTLfCQGZqg7D+CKtA4=; b=KV2UHUhgRVl/Cpk9NFNDGazQLjrsRmnGmW5B1zLpVn52i7lCDtY5nOf/hL/J69YdVT molQ/Ooju0KlSEsivl9oEDZGxUtQxNZ5UBAkxhdLgwy9p34NszrVOA6lQxrkLLoWevjI IWEpCDA/0/jHpiki/bMe5Y1S5UV+rk7OdnNMPOswycYsQHOMo+49gv5oNSqMS21vcezB t/P5K77Bo6Xk3fdasq2ZUXk/4327Ekv10QsKQNK7SAyVKb0YRxNXdMhTT6rUph2gVMNz gsn7IdIbcAgvsCPMiGFuCGF1iB7X1szgbSPqgvPYxgfyh8XR0fE2+tUIBwBEaIcJ8OJ6 0wpg== X-Gm-Message-State: AG10YOR4u8xMVi8PV+Zm86ehATMjKxz8XEfORjyp/6X2WVXOKXOLY1/aExQPhw+CRCAKkA== X-Received: by 10.55.23.9 with SMTP id i9mr16317149qkh.7.1454676859176; Fri, 05 Feb 2016 04:54:19 -0800 (PST) Received: from [192.168.1.130] (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id e11sm7644936qkb.39.2016.02.05.04.54.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Feb 2016 04:54:18 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Fri, 5 Feb 2016 07:54:11 -0500 (EST) To: Patrick Palka cc: gcc-patches@gcc.gnu.org, jason@redhat.com Subject: Re: [PATCH] Fix PR c++/68948 (wrong code generation due to invalid constructor call) In-Reply-To: <1454646091-8065-1-git-send-email-patrick@parcs.ath.cx> Message-ID: References: <1454646091-8065-1-git-send-email-patrick@parcs.ath.cx> User-Agent: Alpine 2.20.9 (DEB 106 2015-09-22) MIME-Version: 1.0 On Thu, 4 Feb 2016, Patrick Palka wrote: > The compiler correctly detects and diagnoses invalid constructor calls > such as C::C () in a non-template context but it fails to do so while > processing a class template. [ Section 3.4.3.1 of the standard is what > makes these forms of constructor calls illegal -- see > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68948#c9 ] > > In a non-template context this diagnosis would take place in > build_new_method_call, called from finish_call_expr, but while > processing a class template we may exit early out of finish_call_expr > and never call build_new_method_call. > > Thus we never diagnose this invalid constructor call during template > processing. So then during instantiation of the enclosing template we > call tsubst_baselink on this constructor call, during which the call to > lookup_fnfields returns NULL (because it finds the injected class type C > not the constructor C). Because the lookup failed, tsubst_baselink > returns error_mark_node and this node persists all the way through to > gimplification where it silently gets discarded. > > This patch fixes this problem by diagnosing these invalid constructor > calls in tsubst_baselink. Alternatively, we can rewire finish_call_expr > avoid exiting early while processing a template if the call in question > is a constructor call. I'm not sure which approach is better. This > approach seems more conservative, since it's just attaching an error > message to an existing error path. And here is the other approach, which rewires finish_call_expr: -- >8 -- gcc/cp/ChangeLog: PR c++/68948 * semantics.c (finish_call_expr): Don't assume a constructor call is dependent if the "this" pointer is dependent. gcc/testsuite/ChangeLog: PR c++/68948 * g++.dg/template/pr68948.C: New test. --- gcc/cp/semantics.c | 14 +++++++++-- gcc/testsuite/g++.dg/template/pr68948.C | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr68948.C diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 95c4f19..31c03ae 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2270,6 +2270,7 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, related to CWG issues 515 and 1005. */ || (TREE_CODE (fn) != COMPONENT_REF && non_static_member_function_p (fn) + && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn)) && current_class_ref && type_dependent_expression_p (current_class_ref))) { @@ -2348,8 +2349,17 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, [class.access.base] says that we need to convert 'this' to B* as part of the access, so we pass 'B' to maybe_dummy_object. */ - object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), - NULL); + if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn))) + { + /* A constructor call always uses a dummy object. (This constructor + call which has the form A::A () is actually invalid and we are + going to reject it later in build_new_method_call.) */ + object = build_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn))); + gcc_assert (!type_dependent_expression_p (object)); + } + else + object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), + NULL); if (processing_template_decl) { diff --git a/gcc/testsuite/g++.dg/template/pr68948.C b/gcc/testsuite/g++.dg/template/pr68948.C new file mode 100644 index 0000000..3cb6844 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr68948.C @@ -0,0 +1,41 @@ +// PR c++/68948 + +struct B { B (); B (int); }; + +struct Time : B { }; + +/* Here, A and B are unrelated types. */ + +template +struct A +{ + void TestBody () + { + B::B (); // { dg-error "cannot call constructor .B::B." } + B::B::B (); // { dg-error "cannot call constructor .B::B." } + B::B (0); // { dg-error "cannot call constructor .B::B." } + } +}; + +/* Here, C is (indirectly) derived from B. */ + +template +struct C : Time +{ + void TestBody () + { + B::B (); // { dg-error "cannot call constructor .B::B." } + B::B::B (); // { dg-error "cannot call constructor .B::B." } + B::B (0); // { dg-error "cannot call constructor .B::B." } + Time::B (0); + } +}; + +int +main (void) +{ + A a; + C c; + a.TestBody (); + c.TestBody (); +}