From patchwork Wed May 8 17:31:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1097165 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-500324-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="sRLDoMis"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ddv2pDEm"; 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 44zk6w0FZgz9s4V for ; Thu, 9 May 2019 03:31:49 +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=FxnCX9dUGZ4mu5yT9T7NNe3pl5IXa3zWGlNSsvc4OyAQHT6nGz o23fl2mmZ6+Y9ysqvTSlZUkTv1yD62KtfggliYPWxYtqSzbRTbv8n8a093ByV7kK 34Nz9dOu/7RAE/QUnj3hjjG8JHuOvzrd0zAYIBA7RMgzk3BSLvyfu2Ph8= 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=3/x5Vl3Pg5wHJ6MDRjyCXC+drDY=; b=sRLDoMisP2I3SmfJEsLE Y0D5WjsEZfVlPuil0PQdtsGKAwuDySNknvMA4CmzCi8UmtHfD2/bS4NhBpPKTQN8 YT9ioEJk5oC4njpoqXOdKKVSyZAy64y8iYRTXKzqT/W11yshQqlQnlrUe0UtEU4K IMxCIWWdo/C/VDzSChOm3nI= Received: (qmail 50238 invoked by alias); 8 May 2019 17:31:41 -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 50230 invoked by uid 89); 8 May 2019 17:31:41 -0000 Authentication-Results: sourceware.org; auth=none 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.1 spammy=faithfully, sk:finish_ X-HELO: mail-qk1-f177.google.com Received: from mail-qk1-f177.google.com (HELO mail-qk1-f177.google.com) (209.85.222.177) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 08 May 2019 17:31:38 +0000 Received: by mail-qk1-f177.google.com with SMTP id n68so2657755qka.1 for ; Wed, 08 May 2019 10:31:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=ukeGfWYchMwKhL7QHWFFZMBfLTyuFjFTsP1gPOwz9tg=; b=Ddv2pDEmZn8/cCSlTnZjxQYRoyZbX2Z3r24GRmtt3JoOO1xyH5yyVCjhO7PBxx9FJn 2UK50236cIrJFTB76QWFxarFGLwp/i1ZYMzoIu2pjo4Fp8gr95KYj3h/k7Lm8EivMVZF Leg0Rv4t0KcjyQYmjQZ+yq/8HyaYsVpuSv6ForgI9PuGIT+cdCYKnOgOT/s3DGD5umjq RlDib5T58y7v4zTqNsMSAlexM4boiupNtrKFlq2Oe7ga4/mMYdkiK1gO65Cb4PigJ+Au 8+7IHdc9ReqxqFZTwUQEZQi0UdV47uT+IiecQnwlHJ4raebh/BjIRQPlclUP8XYRibc0 VvKw== Received: from ?IPv6:2620:10d:c0a8:1102:ec60:b4f:e225:8109? ([2620:10d:c091:480::e900]) by smtp.googlemail.com with ESMTPSA id c13sm8685066qkk.11.2019.05.08.10.31.35 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Wed, 08 May 2019 10:31:36 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] Kill DECL_SAVED_FUNCTION_DATA Message-ID: <6fbcb00e-cbcc-3854-e81c-cce451f8ea17@acm.org> Date: Wed, 8 May 2019 13:31:34 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 I discovered that DECL_SAVED_FUNCTION_DATA became obsolete during or after the gimple conversion. But we continued to faithfully save and restore it in the C++ FE. We then extended it to hold the auto return pattern a function might have been declared with. This patch removes the saved function data, and stores the auto pattern in the decl's slot that used to point to the saved data. nathan 2019-05-08 Nathan Sidwell Kill DECL_SAVED_FUNCTION_DATA . * cp-tree.h (language_function): Remove x_auto_return_pattern. (current_function_auto_return_pattern): Delete. (lang_decl_fn): Replace saved_language_function with saved_auto_return type. (DECL_SAVED_FUNCTION_DATA): Delete. (DECL_SAVED_AUTO_RETURN_TYPE): New. (FNDECL_USED_AUTO): Correct documentation. * decl.c (duplicate_decls): Adjust AUTO return handling. (start_preparsed_function): Replace current_function_auto_return_pattern with DECL_SAVED_AUTO_RETURN_TYPE. Remove DECL_SAVED_FUNCTION_DATA zapping. (finish_function): Likewise. (save_function_data): Delete. (fndecl_declared_return_type): Reimplement. * mangle.c (write_unqualified_name): Use DECL_SAVED_AUTO_RETURN_TYPE. * method.c (make_thunk, make_alias_for): Likewise. * parser.c (cp_parser_jump_statement): Likewise. * pt.c (do_auto_deduction): Likewise. * typeck.c (check_return_expr): Likewise. Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 271012) +++ gcc/cp/cp-tree.h (working copy) @@ -1813,7 +1813,6 @@ struct GTY(()) language_function { tree x_in_charge_parm; tree x_vtt_parm; tree x_return_value; - tree x_auto_return_pattern; BOOL_BITFIELD returns_value : 1; BOOL_BITFIELD returns_null : 1; @@ -1909,11 +1908,6 @@ struct GTY(()) language_function { #define current_function_return_value \ (cp_function_chain->x_return_value) -/* A type involving 'auto' to be used for return type deduction. */ - -#define current_function_auto_return_pattern \ - (cp_function_chain->x_auto_return_pattern) - /* In parser.c. */ extern tree cp_literal_operator_id (const char *); @@ -2654,8 +2648,7 @@ struct GTY(()) lang_decl_fn { union lang_decl_u3 { struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info; - struct language_function * GTY ((tag ("0"))) - saved_language_function; + tree GTY ((tag ("0"))) saved_auto_return_type; } GTY ((desc ("%1.pending_inline_p"))) u; }; @@ -3700,10 +3693,10 @@ struct GTY(()) lang_decl { #define FOLD_EXPR_INIT(NODE) \ TREE_OPERAND (BINARY_FOLD_EXPR_CHECK (NODE), 2) -/* In a FUNCTION_DECL, the saved language-specific per-function data. */ -#define DECL_SAVED_FUNCTION_DATA(NODE) \ +/* In a FUNCTION_DECL, the saved auto-return pattern. */ +#define DECL_SAVED_AUTO_RETURN_TYPE(NODE) \ (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE)) \ - ->u.saved_language_function) + ->u.saved_auto_return_type) /* True if NODE is an implicit INDIRECT_REF from convert_from_reference. */ #define REFERENCE_REF_P(NODE) \ @@ -3934,7 +3927,7 @@ more_aggr_init_expr_args_p (const aggr_i /* True if NODE was declared with auto in its return type, but it has started compilation and so the return type might have been changed by return type deduction; its declared return type should be found in - DECL_STRUCT_FUNCTION(NODE)->language->x_auto_return_pattern. */ + DECL_SAVED_AUTO_RETURN_TYPE (NODE). */ #define FNDECL_USED_AUTO(NODE) \ TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE)) Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 271012) +++ gcc/cp/decl.c (working copy) @@ -80,7 +80,6 @@ static void maybe_deduce_size_from_array static void layout_var_decl (tree); static tree check_initializer (tree, tree, int, vec **); static void make_rtl_for_nonlocal_decl (tree, tree, const char *); -static void save_function_data (tree); static void copy_type_enum (tree , tree); static void check_function_type (tree, tree); static void finish_constructor_body (void); @@ -2480,9 +2479,9 @@ duplicate_decls (tree newdecl, tree oldd } else if (DECL_PENDING_INLINE_P (newdecl)) ; - else if (DECL_SAVED_FUNCTION_DATA (newdecl) == NULL) - DECL_SAVED_FUNCTION_DATA (newdecl) - = DECL_SAVED_FUNCTION_DATA (olddecl); + else if (DECL_SAVED_AUTO_RETURN_TYPE (newdecl) == NULL) + DECL_SAVED_AUTO_RETURN_TYPE (newdecl) + = DECL_SAVED_AUTO_RETURN_TYPE (olddecl); DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl); @@ -15449,20 +15448,21 @@ start_preparsed_function (tree decl1, tr current_stmt_tree ()->stmts_are_full_exprs_p = 1; current_binding_level = bl; + /* If we are (erroneously) defining a function that we have already + defined before, wipe out what we knew before. */ + gcc_checking_assert (!DECL_PENDING_INLINE_P (decl1)); + FNDECL_USED_AUTO (decl1) = false; + DECL_SAVED_AUTO_RETURN_TYPE (decl1) = NULL; + if (!processing_template_decl && type_uses_auto (restype)) { FNDECL_USED_AUTO (decl1) = true; - current_function_auto_return_pattern = restype; + DECL_SAVED_AUTO_RETURN_TYPE (decl1) = restype; } /* Start the statement-tree, start the tree now. */ DECL_SAVED_TREE (decl1) = push_stmt_list (); - /* If we are (erroneously) defining a function that we have already - defined before, wipe out what we knew before. */ - if (!DECL_PENDING_INLINE_P (decl1)) - DECL_SAVED_FUNCTION_DATA (decl1) = NULL; - if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1)) { /* We know that this was set up by `grokclassfn'. We do not @@ -15753,31 +15753,6 @@ store_parm_decls (tree current_function_ } -/* We have finished doing semantic analysis on DECL, but have not yet - generated RTL for its body. Save away our current state, so that - when we want to generate RTL later we know what to do. */ - -static void -save_function_data (tree decl) -{ - struct language_function *f; - - /* Save the language-specific per-function data so that we can - get it back when we really expand this function. */ - gcc_assert (!DECL_PENDING_INLINE_P (decl)); - - /* Make a copy. */ - f = ggc_alloc (); - memcpy (f, cp_function_chain, sizeof (struct language_function)); - DECL_SAVED_FUNCTION_DATA (decl) = f; - - /* Clear out the bits we don't need. */ - f->base.x_stmt_tree.x_cur_stmt_list = NULL; - f->bindings = NULL; - f->base.local_typedefs = NULL; -} - - /* Set the return value of the constructor (if present). */ static void @@ -16106,9 +16081,9 @@ finish_function (bool inline_p) the return type is void. But if the declared type is something like auto*, this is an error. */ if (!processing_template_decl && FNDECL_USED_AUTO (fndecl) - && TREE_TYPE (fntype) == current_function_auto_return_pattern) + && TREE_TYPE (fntype) == DECL_SAVED_AUTO_RETURN_TYPE (fndecl)) { - if (is_auto (current_function_auto_return_pattern)) + if (is_auto (DECL_SAVED_AUTO_RETURN_TYPE (fndecl))) { apply_deduced_return_type (fndecl, void_type_node); fntype = TREE_TYPE (fndecl); @@ -16117,7 +16092,7 @@ finish_function (bool inline_p) && !current_function_returns_null) { error ("no return statements in function returning %qT", - current_function_auto_return_pattern); + DECL_SAVED_AUTO_RETURN_TYPE (fndecl)); inform (input_location, "only plain % return type can be " "deduced to %"); } @@ -16180,10 +16155,6 @@ finish_function (bool inline_p) to the FUNCTION_DECL node itself. */ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - /* Save away current state, if appropriate. */ - if (!processing_template_decl) - save_function_data (fndecl); - /* Complain if there's just no return statement. */ if (warn_return_type && !VOID_TYPE_P (TREE_TYPE (fntype)) @@ -16265,20 +16236,7 @@ finish_function (bool inline_p) /* Genericize before inlining. */ if (!processing_template_decl) - { - struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl); - cp_genericize (fndecl); - /* Clear out the bits we don't need. */ - f->x_current_class_ptr = NULL; - f->x_current_class_ref = NULL; - f->x_eh_spec_block = NULL; - f->x_in_charge_parm = NULL; - f->x_vtt_parm = NULL; - f->x_return_value = NULL; - f->bindings = NULL; - f->extern_decl_map = NULL; - f->infinite_loops = NULL; - } + cp_genericize (fndecl); /* We're leaving the context of this function, so zap cfun. It's still in DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation. */ @@ -16692,14 +16650,8 @@ fndecl_declared_return_type (tree fn) { fn = STRIP_TEMPLATE (fn); if (FNDECL_USED_AUTO (fn)) - { - struct language_function *f = NULL; - if (DECL_STRUCT_FUNCTION (fn)) - f = DECL_STRUCT_FUNCTION (fn)->language; - if (f == NULL) - f = DECL_SAVED_FUNCTION_DATA (fn); - return f->x_auto_return_pattern; - } + return DECL_SAVED_AUTO_RETURN_TYPE (fn); + return TREE_TYPE (TREE_TYPE (fn)); } Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c (revision 271012) +++ gcc/cp/mangle.c (working copy) @@ -1366,8 +1366,7 @@ write_unqualified_name (tree decl) type = TREE_TYPE (fn_type); } else if (FNDECL_USED_AUTO (decl)) - type = (DECL_STRUCT_FUNCTION (decl)->language - ->x_auto_return_pattern); + type = DECL_SAVED_AUTO_RETURN_TYPE (decl); else type = DECL_CONV_FN_TYPE (decl); write_conversion_operator_name (type); Index: gcc/cp/method.c =================================================================== --- gcc/cp/method.c (revision 271012) +++ gcc/cp/method.c (working copy) @@ -118,7 +118,7 @@ make_thunk (tree function, bool this_adj DECL_INTERFACE_KNOWN (thunk) = 1; DECL_NOT_REALLY_EXTERN (thunk) = 1; DECL_COMDAT (thunk) = DECL_COMDAT (function); - DECL_SAVED_FUNCTION_DATA (thunk) = NULL; + DECL_SAVED_AUTO_RETURN_TYPE (thunk) = NULL; /* The thunk itself is not a constructor or destructor, even if the thing it is thunking to is. */ DECL_CXX_DESTRUCTOR_P (thunk) = 0; @@ -206,7 +206,7 @@ make_alias_for (tree target, tree newid) DECL_TEMPLATE_INSTANTIATED (alias) = 0; if (TREE_CODE (alias) == FUNCTION_DECL) { - DECL_SAVED_FUNCTION_DATA (alias) = NULL; + DECL_SAVED_AUTO_RETURN_TYPE (alias) = NULL; DECL_CXX_DESTRUCTOR_P (alias) = 0; DECL_CXX_CONSTRUCTOR_P (alias) = 0; DECL_PENDING_INLINE_P (alias) = 0; Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 271012) +++ gcc/cp/parser.c (working copy) @@ -12913,7 +12913,7 @@ cp_parser_jump_statement (cp_parser* par expression. */ expr = NULL_TREE; /* Build the return-statement. */ - if (current_function_auto_return_pattern && in_discarded_stmt) + if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt) /* Don't deduce from a discarded return statement. */; else statement = finish_return_stmt (expr); Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 271012) +++ gcc/cp/pt.c (working copy) @@ -27622,7 +27622,10 @@ do_auto_deduction (tree type, tree init, emitted by now. Also, having a mention to '' in the diagnostic is not really useful to the user. */ { - if (cfun && auto_node == current_function_auto_return_pattern + if (cfun + && FNDECL_USED_AUTO (current_function_decl) + && (auto_node + == DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl)) && LAMBDA_FUNCTION_P (current_function_decl)) error ("unable to deduce lambda return type from %qE", init); else Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 271012) +++ gcc/cp/typeck.c (working copy) @@ -9551,7 +9551,7 @@ check_return_expr (tree retval, bool *no /* If one of the types might be void, we can't tell whether we're returning a value. */ if ((WILDCARD_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))) - && !current_function_auto_return_pattern) + && !FNDECL_USED_AUTO (current_function_decl)) || (retval != NULL_TREE && (TREE_TYPE (retval) == NULL_TREE || WILDCARD_TYPE_P (TREE_TYPE (retval))))) @@ -9561,16 +9561,17 @@ check_return_expr (tree retval, bool *no functype = TREE_TYPE (TREE_TYPE (current_function_decl)); /* Deduce auto return type from a return statement. */ - if (current_function_auto_return_pattern) + if (FNDECL_USED_AUTO (current_function_decl)) { + tree pattern = DECL_SAVED_AUTO_RETURN_TYPE (current_function_decl); tree auto_node; tree type; - if (!retval && !is_auto (current_function_auto_return_pattern)) + if (!retval && !is_auto (pattern)) { /* Give a helpful error message. */ error ("return-statement with no value, in function returning %qT", - current_function_auto_return_pattern); + pattern); inform (input_location, "only plain % return type can be " "deduced to %"); type = error_mark_node; @@ -9584,14 +9585,13 @@ check_return_expr (tree retval, bool *no { if (!retval) retval = void_node; - auto_node = type_uses_auto (current_function_auto_return_pattern); - type = do_auto_deduction (current_function_auto_return_pattern, - retval, auto_node); + auto_node = type_uses_auto (pattern); + type = do_auto_deduction (pattern, retval, auto_node); } if (type == error_mark_node) /* Leave it. */; - else if (functype == current_function_auto_return_pattern) + else if (functype == pattern) apply_deduced_return_type (current_function_decl, type); else if (!same_type_p (type, functype)) {