From patchwork Wed Oct 30 13:49:40 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Sutton X-Patchwork-Id: 287210 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 19E492C03B6 for ; Thu, 31 Oct 2013 00:50:12 +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 :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=hrg1MWaIJAQ1bBdrFxviVnxe+UQvRTguItHpHzTmbtIOgW 8x09h8QaAluSOw6DeJihQ//C+7tZYNcSojCy27FGxdFivgLU+hHH4mXAqWppkaLz qd9JKEKeFXl3c9Q3z4bc6IifZ/w4Frhd6jrAnK1p+ev0dQ27WvdtYCBt9nFwA= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=2ExsIGrjNdFo0WOXqDLH2JimNQQ=; b=kNAKZpLtxmHV9z2s+OoD wyU9DpNCGNpfLPyunKdlH2wygUUa464UdJrQroir5e3ycussVvEVoMbXNmgyV/Vq voPo0Bz0FIh05LiECu93v5GPwyCUz8cFE9hY9DWYi+MSt/OIhmP/kcJtB5h0uVyW Fx28xEMHOLhrD2evrNlB8ow= Received: (qmail 24152 invoked by alias); 30 Oct 2013 13:50:05 -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 24136 invoked by uid 89); 30 Oct 2013 13:50:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-vc0-f176.google.com Received: from mail-vc0-f176.google.com (HELO mail-vc0-f176.google.com) (209.85.220.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Wed, 30 Oct 2013 13:50:03 +0000 Received: by mail-vc0-f176.google.com with SMTP id ia6so914247vcb.21 for ; Wed, 30 Oct 2013 06:50:00 -0700 (PDT) X-Received: by 10.52.64.143 with SMTP id o15mr2681937vds.16.1383141000762; Wed, 30 Oct 2013 06:50:00 -0700 (PDT) MIME-Version: 1.0 Received: by 10.52.244.2 with HTTP; Wed, 30 Oct 2013 06:49:40 -0700 (PDT) From: Andrew Sutton Date: Wed, 30 Oct 2013 09:49:40 -0400 Message-ID: Subject: [c++-concepts] Constrained scope bugfix To: gcc-patches , Jason Merrill Partially fixing a bug that caused lookup errors in valid programs. For example: template pair::type void f(T, U); // Error, no such pair When entering a template scope, we tried to match the template to one having the same constraints. Obviously pair doesn't have Int and Float constraints, and it probably doesn't have a partial specialization with those constraints either. I relaxed the fixup_template_type function so that it would just return the looked-up type without emitting a diagnostic. This fix makes the following a legal, however: template struct S { void f(); } template void S::f() { } // Should be an error The right solution seems to be to diagnose the error only when defining an out-of-class member by verifying that each template scope in the qualified name matches a declaration with the same constraints. 2013-10-30 Andrew Sutton * gcc/cp/semantics.c (fixup_template_type): Don't emit errors when no templates can be found with matching constraints. Index: gcc/cp/semantics.c =================================================================== --- gcc/cp/semantics.c (revision 203626) +++ gcc/cp/semantics.c (working copy) @@ -2847,8 +2847,35 @@ finish_template_decl (tree parms) // Returns the template type of the class scope being entered. If we're // entering a constrained class scope. TYPE is the class template -// scope being entered. If TYPE is not a class-type (e.g. a typename type), -// then no fixup is needed. +// scope being entered and we may need to match the intended type with +// a constrained specialization. For example: +// +// template +// struct S { void f(); }; #1 +// +// template +// void S::f() { } #2 +// +// We check, in #2, that S refers precisely to the type declared by +// #1 (i.e., that the constraints match). Note that the following should +// be an error since there is no specialization of S that is +// unconstrained, but this is not diagnosed here. +// +// template +// void S::f() { } +// +// We cannot diagnose this problem here since this function also matches +// qualified template names that are not part of a definition. For example: +// +// template +// typename pair::first_type void f(T, U); +// +// Here, it is unlikely that there is a partial specialization of +// pair constrained for for Integral and Floating_point arguments. +// +// The general rule is: if a constrained specialization with matching +// constraints is found return that type. Alos note that if TYPE is not a +// class-type (e.g. a typename type), then no fixup is needed. static tree fixup_template_type (tree type) { @@ -2866,14 +2893,8 @@ fixup_template_type (tree type) return type; tree cur_constr = TEMPLATE_PARMS_CONSTRAINTS (parms); - // Do the constraints match those of the most general template? - // If the constraints are NULL_TREE, this will match the most general - // template iff it is unconstrained. + // Search for a specialization whose constraints match. tree tmpl = CLASSTYPE_TI_TEMPLATE (type); - if (equivalent_constraints (cur_constr, DECL_CONSTRAINTS (tmpl))) - return type; - - // Can we find a specialization that matches? tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); while (specs) { @@ -2883,10 +2904,8 @@ fixup_template_type (tree type) specs = TREE_CHAIN (specs); } - // Emit an error, but return the type to allow processing to continue. - // TODO: We should emit candidates since we've just scanned the - // list of template constraints. - error ("type %qT does not match any declarations", type); + // If no specialization matches, then must return the type + // previously found. return type; } @@ -2904,7 +2923,7 @@ finish_template_type (tree name, tree ar type = lookup_template_class (name, args, NULL_TREE, NULL_TREE, entering_scope, tf_warning_or_error | tf_user); - + // If entering a scope, correct the lookup to account for constraints. if (entering_scope) type = fixup_template_type (type);