From patchwork Wed Jun 20 14:33:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 932286 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-480114-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="bdoKjKzg"; dkim-atps=neutral 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 419nPs63K3z9s4w for ; Thu, 21 Jun 2018 00:33:37 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=EyRzEuoBrMKQM49yic9DrwO+TBU05lmncFqDxKGeVcxhLHz+jM WX5upiUysAb8ob4fHrFePb6GIpKDk1ieL8THvP8bcBwlcIm0WvegX0k5CgiFEtun XPAN5nZrG6gj/3+8wU1/mm2iEltN59bIjNOA/yHmGJirtNOWIC98b83cA= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=PKc7G+mPwwVuVZ93+fT948nMShM=; b=bdoKjKzgsmZcBgJnagUo hDNaSszbrDtdCCY2w7BfcCtoTRBqF9q+1mAIjHnQtOpiYvF1NExH1q7ZnyMBFIit AKmm5IbqoEIrzxxAg9If9SlPFNDuavO2iNBGqJ3PYNXN7QFp6TeFB5tvkwm5+Na2 e4cW1oqbTBFD2DN7FXoqd4w= Received: (qmail 120559 invoked by alias); 20 Jun 2018 14:33:30 -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 120545 invoked by uid 89); 20 Jun 2018 14:33:29 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=nathan, idk, Nathan, H*Ad:U*nathan X-HELO: mail-yb0-f176.google.com Received: from mail-yb0-f176.google.com (HELO mail-yb0-f176.google.com) (209.85.213.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 20 Jun 2018 14:33:26 +0000 Received: by mail-yb0-f176.google.com with SMTP id h141-v6so1300643ybg.4 for ; Wed, 20 Jun 2018 07:33:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=5c73u1I7PvWSJr6r9ZYivuR05HfIpHHDPzPOJjjbCys=; b=D+xeiWCYEyqooBOQff0Hb2VqJccSj1zmLLskOh/1rCjinNSJHBFACheZflb71b2pjQ SzzU3NSyDpFb4J8ZVU3Wj35QEN9VoXqbd7fL6O9LIhAlDEaw2sljCuNcSc/Gjjv4DMqN ax1QGbDzwuL79JHJ3C0zMrtw8rLfMp41zgGiIN4h6Qg0heriD1HLPw5T+/woO72ZqjsW EIQVKEMBSCEj5bAUxRRCPgdj3gwMGCR+m5tjXL3oJVgnNuf3JL/w3GWqY8Sf14ULlPZj tYxbpbZ1cvNNFK2XXvnnlVHsxTaLvsOcpflDc+EI/EhQNIb8j6pwO8IeiU6LkdfDzG9n b3vQ== X-Gm-Message-State: APt69E2nfAJiVH5r67+tnfpMqegPhEKwJjednnQ+QpZwYN0njiqoT0BN Z0jIoBWznG6Kp5yUP8fZt3s= X-Google-Smtp-Source: ADUXVKIk6+H7qDwBwMyNyXGQK0CabcfEgb70RU1cuEz69b2rYAk2VKjyjD/Tmo7Zmmg/Zmo95hoNWQ== X-Received: by 2002:a25:b5c8:: with SMTP id d8-v6mr10234385ybg.373.1529505205047; Wed, 20 Jun 2018 07:33:25 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c091:200::3:1c8e]) by smtp.googlemail.com with ESMTPSA id g32-v6sm996523ywk.15.2018.06.20.07.33.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Jun 2018 07:33:24 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [PR c++/85634] Fix tsubst ICE Message-ID: <4846e7b1-ae84-ff0e-bcdd-9deaf9fc1de6@acm.org> Date: Wed, 20 Jun 2018 10:33:22 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 This patch fixes 85634, an ice during tsubst where we encounter an unmarked lookup. Such lookups could be mutated by declarations added after the template definition containing them. That would be bad. I had originally wanted to mark these lookups once we knew we were saving them, but this bug is the final straw in that approach. Instead I now mark them early when parsing the primary expression they are part of. At this point we'll have tried tentative parsing, for when they may have been part of a declaration, and it would be bad to mark them then. This allows me to rip out all the other places we mark them. Except for non-dependent ADL lookup. As the comment there says, we end up saving the overload set and re-jousting them at instantiation time. Which is unfortunate, but I didn't want to dive into fix that too -- there's an existing bug for that, which my earlier attempts at fixing broke the concept machinery. So not as simple as one might hope. The new maybe_fn_decls call is probably useable in a bunch of other places that call 'is_overloaded_fn .... get_fns' I'll port a cut down variant of this to the gcc-8 branch. nathan 2018-06-20 Nathan Sidwell PR c++/85634 * cp-tree.h (lookup_keep): Drop KEEP parm. (lookup_list_keep): Delete. (maybe_get_fns): Declare. * parser.c (cp_parser_primary_expression): Call lookup_keep here. (cp_parser_template_id): Not here ... * decl.c (cp_finish_decl): ... nor here ... * init.c (build_raw_new_expr): ... nor here ... * pt.c (process_template_parm): ... nor here ... * semantics.c (perform_koenig_lookup): Call lookup_keep. (finish_call_expr): Not here. * tree.c (ovl_cache): Delete. (ovl_make, ovl_copy): No cache. (lookup_keep): Always keep. (lookup_list_keep): Delete. (maybe_get_fns): New, broken out of ... (get_fns): ... here. Call it. (built_min_nt_loc, build_min, build_min_non_dep): Drop lookup_keep. (build_min_nt_call_vec): Likewise. PR c++/85634 * g++.dg/lookup/pr85634.C: New. Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 261799) +++ gcc/cp/cp-tree.h (working copy) @@ -7094,11 +7094,11 @@ extern void lookup_mark (tree lookup, extern tree lookup_add (tree fns, tree lookup); extern tree lookup_maybe_add (tree fns, tree lookup, bool deduping); -extern void lookup_keep (tree lookup, bool keep); -extern void lookup_list_keep (tree list, bool keep); +extern void lookup_keep (tree lookup); extern int is_overloaded_fn (tree) ATTRIBUTE_PURE; extern bool really_overloaded_fn (tree) ATTRIBUTE_PURE; extern tree dependent_name (tree); +extern tree maybe_get_fns (tree) ATTRIBUTE_PURE; extern tree get_fns (tree) ATTRIBUTE_PURE; extern tree get_first_fn (tree) ATTRIBUTE_PURE; extern tree ovl_scope (tree); Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 261799) +++ gcc/cp/decl.c (working copy) @@ -6973,11 +6973,8 @@ cp_finish_decl (tree decl, tree init, bo } if (init) - { - if (TREE_CODE (init) == TREE_LIST) - lookup_list_keep (init, true); - DECL_INITIAL (decl) = init; - } + DECL_INITIAL (decl) = init; + if (dep_init) { retrofit_lang_decl (decl); Index: gcc/cp/init.c =================================================================== --- gcc/cp/init.c (revision 261799) +++ gcc/cp/init.c (working copy) @@ -2403,12 +2403,7 @@ build_raw_new_expr (vec *pl else if (init->is_empty ()) init_list = void_node; else - { - init_list = build_tree_list_vec (init); - for (tree v = init_list; v; v = TREE_CHAIN (v)) - if (TREE_CODE (TREE_VALUE (v)) == OVERLOAD) - lookup_keep (TREE_VALUE (v), true); - } + init_list = build_tree_list_vec (init); new_expr = build4 (NEW_EXPR, build_pointer_type (type), build_tree_list_vec (placement), type, nelts, Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 261799) +++ gcc/cp/parser.c (working copy) @@ -5603,6 +5603,14 @@ cp_parser_primary_expression (cp_parser } } + if (processing_template_decl) + if (tree fns = maybe_get_fns (decl)) + /* It's too difficult to mark ths in all the places where + we know for sure we need to keep the lookup, so do it + now. The cost is extra GC to recycle the lookups + resolved at parse time. */ + lookup_keep (fns); + decl = (finish_id_expression (id_expression, decl, parser->scope, idk, @@ -15989,11 +15997,6 @@ cp_parser_template_id (cp_parser *parser token->type = CPP_TEMPLATE_ID; token->location = combined_loc; - /* We must mark the lookup as kept, so we don't throw it away on - the first parse. */ - if (is_overloaded_fn (template_id)) - lookup_keep (get_fns (template_id), true); - /* Retrieve any deferred checks. Do not pop this access checks yet so the memory will not be reclaimed during token replacing below. */ token->u.tree_check_value = ggc_cleared_alloc (); Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 261799) +++ gcc/cp/pt.c (working copy) @@ -4431,9 +4431,6 @@ process_template_parm (tree list, locati pushdecl (decl); - if (defval && TREE_CODE (defval) == OVERLOAD) - lookup_keep (defval, true); - /* Build the parameter node linking the parameter declaration, its default argument (if any), and its constraints (if any). */ parm = build_tree_list (defval, parm); Index: gcc/cp/semantics.c =================================================================== --- gcc/cp/semantics.c (revision 261799) +++ gcc/cp/semantics.c (working copy) @@ -2325,6 +2325,11 @@ perform_koenig_lookup (cp_expr fn, vec void Foo (T *const &); +} + +using namespace N; + +template void Foo (const T &); + + +template +void Frob() +{ + void (*op)(const T&) = Foo; +} + +template void Frob();