From patchwork Thu Sep 10 12:43:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1361548 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=qcXrg/Jx; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BnJVL6Z3wz9sTg for ; Thu, 10 Sep 2020 22:44:09 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EBE123971C67; Thu, 10 Sep 2020 12:44:05 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by sourceware.org (Postfix) with ESMTPS id DA4CF3857C5B for ; Thu, 10 Sep 2020 12:44:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org DA4CF3857C5B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qk1-x72a.google.com with SMTP id q63so5066671qkf.3 for ; Thu, 10 Sep 2020 05:44:01 -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=ePo0JxgKlr4izTaDYC4+wlNyHlC0vM2A+bvlYK1jKhE=; b=qcXrg/Jxe9YNb0HUQvDT4ls4JKp3O4pfSvvvV/87WcyiHzfOBWk0DvRi01N7EYbkRg 4jwCdtnftM466d39sFK3l3HWutEkceNfKjrqdTns101s64YQDgAJ6vEpn8JNYzdpDQeS DvS2gBQVl5XsRn3hdLhyKwMNO11MRLD5PLC7jW01HLI05Q48QpQ/a6LGtGl5srdsARQd f+34z5JFHfa5O4mlIUwvPZwjIzqbT9hQ5/fl1slPQeaMFkpn2UrctNjW/kcQDDxSY8QL 6MjHgUGUFhB0Iy1Y+fOML/ATnJ74sXE8GZpB7iQV4S54dtknanAhmSKZSfSFZP6dcx6r oaCw== 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=ePo0JxgKlr4izTaDYC4+wlNyHlC0vM2A+bvlYK1jKhE=; b=INUw8BY/6PQOQsbxaP/BVFLl5I26Ps0YE8+ljzp0FIIwR9dG3Iq8dikTZ8izTM67Kq CUfy2qh8aT9lp9oGI0afQs46Ki271fOYK61nd65P2f2vrrdUQxWT1Z1L0DZCljucLblj UnIm6LgYxJZlvHPEaCg499U4D2tiH94GzLraKKjIKoPWS3+zW8CozGDHJJIGxJGQJy7d eC0xigtbDenAL54F4crMuSWv0MT9WcaMZY0PxbEjCti2bhs/dvnRZqCfzCOKFnwpOcka HEnxCVfiRCVocumHpfeiU69/zQA2OoPjvCvmIMdOYTkP67YgQSMwSO4iQZtsUNlf41vq 4HEg== X-Gm-Message-State: AOAM531RHDROROj/T6w4+ihbWIGQMUB5DAK+wWJLbBhsEg7Im5oNZ82J LnjAkJo7JP0DsnqoZxDmqHM= X-Google-Smtp-Source: ABdhPJzJsvwZrzr7XwV2+Ek6Jy/Lbb8G7UIFV240C9PcP9nwCogbYaxNr0hIyex3VgIq3ISM4lnCuw== X-Received: by 2002:a05:620a:a45:: with SMTP id j5mr7863656qka.367.1599741841238; Thu, 10 Sep 2020 05:44:01 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a8:1102:85a5:b01a:3dae:ee68? ([2620:10d:c091:480::1:2535]) by smtp.googlemail.com with ESMTPSA id z133sm6272845qka.3.2020.09.10.05.43.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 10 Sep 2020 05:43:59 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: c++: DECL_LOCAL_FUNCTION_P -> DECL_LOCAL_DECL_P Message-ID: <9a23f589-aa7f-4ef1-4726-0d54973189e9@acm.org> Date: Thu, 10 Sep 2020 08:43:55 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-9.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Our handling of block-scope extern decls is insufficient for modern C++, in particular modules, (but also constexprs). We mark such local function decls, and this patch extends that to marking local var decls too, so mainly a macro rename. Also, we set this flag earlier, rather than learning about it when pushing the decl. This is a step towards handling these properly. gcc/cp/ * cp-tree.h (DECL_LOCAL_FUNCTION_P): Rename to ... (DECL_LOCAL_DECL_P): ... here. Accept both fns and vars. (start_decl): Set DECL_LOCAL_DECL_P for local externs. (omp_declare_variant_finalize_one): Use DECL_LOCAL_DECL_P. (local_variable_p): Simplify. * name-lookup.c (set_decl_context_in_fn): Assert DECL_LOCAL_DECL_P is as expected. Simplify. (do_pushdecl): Don't set decl_context_in_fn for friends. (is_local_extern): Simplify. * call.c (equal_functions): Use DECL_LOCAL_DECL_P. * parser.c (cp_parser_postfix_expression): Likewise. (cp_parser_omp_declare_reduction): Likewise. * pt.c (check_default_tmpl_args): Likewise. (tsubst_expr): Assert nested reduction function is local. (type_dependent_expression_p): Use DECL_LOCAL_DECL_P. * semantics.c (finish_call_expr): Likewise. libcc1/ * licp1plugin.cc (plugin_build_call_expr): Use DECL_LOCAL_DECL_P. pushed to trunk nathan diff --git c/gcc/cp/call.c w/gcc/cp/call.c index 61bbb38bd2b..5606389f4bd 100644 --- c/gcc/cp/call.c +++ w/gcc/cp/call.c @@ -3631,7 +3631,7 @@ equal_functions (tree fn1, tree fn2) return 0; if (TREE_CODE (fn1) == TEMPLATE_DECL) return fn1 == fn2; - if (DECL_LOCAL_FUNCTION_P (fn1) || DECL_LOCAL_FUNCTION_P (fn2) + if (DECL_LOCAL_DECL_P (fn1) || DECL_LOCAL_DECL_P (fn2) || DECL_EXTERN_C_FUNCTION_P (fn1)) return decls_match (fn1, fn2); return fn1 == fn2; diff --git c/gcc/cp/cp-tree.h w/gcc/cp/cp-tree.h index 78739411755..b12c78739e4 100644 --- c/gcc/cp/cp-tree.h +++ w/gcc/cp/cp-tree.h @@ -506,7 +506,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; Usage of DECL_LANG_FLAG_?: 0: DECL_TEMPLATE_PARM_P (in PARM_DECL, CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) - DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL) + DECL_LOCAL_DECL_P (in FUNCTION_DECL, VAR_DECL) DECL_MUTABLE_P (in FIELD_DECL) DECL_DEPENDENT_P (in USING_DECL) LABEL_DECL_BREAK (in LABEL_DECL) @@ -4009,10 +4009,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define TYPE_CONTAINS_VPTR_P(NODE) \ (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE)) -/* Nonzero if NODE is a FUNCTION_DECL (for a function with global - scope) declared in a local scope. */ -#define DECL_LOCAL_FUNCTION_P(NODE) \ - DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE)) +/* Nonzero if NODE is a FUNCTION_DECL or VARIABLE_DECL (for a decl + with namespace scope) declared in a local scope. */ +#define DECL_LOCAL_DECL_P(NODE) \ + DECL_LANG_FLAG_0 (VAR_OR_FUNCTION_DECL_CHECK (NODE)) /* Nonzero if NODE is the target for genericization of 'break' stmts. */ #define LABEL_DECL_BREAK(NODE) \ diff --git c/gcc/cp/decl.c w/gcc/cp/decl.c index ce97d19884d..be2bc9db2e5 100644 --- c/gcc/cp/decl.c +++ w/gcc/cp/decl.c @@ -5199,8 +5199,8 @@ groktypename (cp_decl_specifier_seq *type_specifiers, return type; } -/* Process a DECLARATOR for a function-scope variable declaration, - namespace-scope variable declaration, or function declaration. +/* Process a DECLARATOR for a function-scope or namespace-scope + variable or function declaration. (Function definitions go through start_function; class member declarations appearing in the body of the class go through grokfield.) The DECL corresponding to the DECLARATOR is returned. @@ -5410,6 +5410,11 @@ start_decl (const cp_declarator *declarator, was_public = TREE_PUBLIC (decl); + if ((DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL) + && current_function_decl) + /* A function-scope decl of some namespace-scope decl. */ + DECL_LOCAL_DECL_P (decl) = true; + /* Enter this declaration into the symbol table. Don't push the plain VAR_DECL for a variable template. */ if (!template_parm_scope_p () @@ -7360,7 +7365,7 @@ omp_declare_variant_finalize_one (tree decl, tree attr) fn = STRIP_TEMPLATE (fn); if (!((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn)) || DECL_FUNCTION_MEMBER_P (fn) - || DECL_LOCAL_FUNCTION_P (fn))) + || DECL_LOCAL_DECL_P (fn))) { koenig_p = true; if (!any_type_dependent_arguments_p (args)) @@ -13877,11 +13882,9 @@ int local_variable_p (const_tree t) { if ((VAR_P (t) - /* A VAR_DECL with a context that is a _TYPE is a static data - member. */ - && !TYPE_P (CP_DECL_CONTEXT (t)) - /* Any other non-local variable must be at namespace scope. */ - && !DECL_NAMESPACE_SCOPE_P (t)) + && (DECL_LOCAL_DECL_P (t) + || !DECL_CONTEXT (t) + || TREE_CODE (DECL_CONTEXT (t)) == FUNCTION_DECL)) || (TREE_CODE (t) == PARM_DECL)) return 1; diff --git c/gcc/cp/name-lookup.c w/gcc/cp/name-lookup.c index 3c2ddc197e6..bbeaf64104b 100644 --- c/gcc/cp/name-lookup.c +++ w/gcc/cp/name-lookup.c @@ -2855,14 +2855,13 @@ check_local_shadow (tree decl) static void set_decl_context_in_fn (tree ctx, tree decl) { + if (TREE_CODE (decl) == FUNCTION_DECL + || (VAR_P (decl) && DECL_EXTERNAL (decl))) + /* Make sure local externs are marked as such. */ + gcc_checking_assert (DECL_LOCAL_DECL_P (decl) + && DECL_NAMESPACE_SCOPE_P (decl)); + if (!DECL_CONTEXT (decl) - /* A local declaration for a function doesn't constitute - nesting. */ - && TREE_CODE (decl) != FUNCTION_DECL - /* A local declaration for an `extern' variable is in the - scope of the current namespace, not the current - function. */ - && !(VAR_P (decl) && DECL_EXTERNAL (decl)) /* When parsing the parameter list of a function declarator, don't set DECL_CONTEXT to an enclosing function. When we push the PARM_DECLs in order to process the function body, @@ -2871,12 +2870,6 @@ set_decl_context_in_fn (tree ctx, tree decl) && current_binding_level->kind == sk_function_parms && current_binding_level->this_entity == NULL)) DECL_CONTEXT (decl) = ctx; - - /* If this is the declaration for a namespace-scope function, - but the declaration itself is in a local scope, mark the - declaration. */ - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_NAMESPACE_SCOPE_P (decl)) - DECL_LOCAL_FUNCTION_P (decl) = 1; } /* DECL is a local-scope decl with linkage. SHADOWED is true if the @@ -2998,7 +2991,7 @@ do_pushdecl (tree decl, bool is_friend) if (decl == error_mark_node) return error_mark_node; - if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl) + if (!DECL_TEMPLATE_PARM_P (decl) && current_function_decl && !is_friend) set_decl_context_in_fn (current_function_decl, decl); /* The binding level we will be pushing into. During local class @@ -6682,29 +6675,15 @@ lookup_type_scope (tree name, tag_scope scope) } /* Returns true iff DECL is a block-scope extern declaration of a function - or variable. */ + or variable. We will already have determined validity of the decl + when pushing it. So we do not have to redo that lookup. */ bool is_local_extern (tree decl) { - cxx_binding *binding; - - /* For functions, this is easy. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - return DECL_LOCAL_FUNCTION_P (decl); - - if (!VAR_P (decl)) - return false; - if (!current_function_decl) - return false; - - /* For variables, this is not easy. We need to look at the binding stack - for the identifier to see whether the decl we have is a local. */ - for (binding = IDENTIFIER_BINDING (DECL_NAME (decl)); - binding && binding->scope->kind != sk_namespace; - binding = binding->previous) - if (binding->value == decl) - return LOCAL_BINDING_P (binding); + if ((TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == VAR_DECL)) + return DECL_LOCAL_DECL_P (decl); return false; } diff --git c/gcc/cp/parser.c w/gcc/cp/parser.c index 0da383937c2..916ea6cd910 100644 --- c/gcc/cp/parser.c +++ w/gcc/cp/parser.c @@ -7467,7 +7467,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if ((TREE_CODE (fn) == USING_DECL && DECL_DEPENDENT_P (fn)) || DECL_FUNCTION_MEMBER_P (fn) - || DECL_LOCAL_FUNCTION_P (fn)) + || DECL_LOCAL_DECL_P (fn)) { do_adl_p = false; break; @@ -42582,6 +42582,7 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok, { block_scope = true; DECL_CONTEXT (fndecl) = global_namespace; + DECL_LOCAL_DECL_P (fndecl) = true; if (!processing_template_decl) pushdecl (fndecl); } diff --git c/gcc/cp/pt.c w/gcc/cp/pt.c index 4e212620eaf..d4ece3818a4 100644 --- c/gcc/cp/pt.c +++ w/gcc/cp/pt.c @@ -5417,7 +5417,7 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary, class template. */ if (TREE_CODE (CP_DECL_CONTEXT (decl)) == FUNCTION_DECL - || (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_FUNCTION_P (decl))) + || (TREE_CODE (decl) == FUNCTION_DECL && DECL_LOCAL_DECL_P (decl))) /* You can't have a function template declaration in a local scope, nor you can you define a member of a class template in a local scope. */ @@ -18080,6 +18080,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, /* We pretend this is regular local extern decl of a namespace-scope fn. Then we make it really local, it is a nested function. */ + gcc_checking_assert (DECL_LOCAL_DECL_P (decl)); DECL_CONTEXT (decl) = global_namespace; pushdecl (decl); DECL_CONTEXT (decl) = current_function_decl; @@ -26978,7 +26979,7 @@ type_dependent_expression_p (tree expression) && DECL_FRIEND_P (expression) && (!DECL_FRIEND_CONTEXT (expression) || dependent_type_p (DECL_FRIEND_CONTEXT (expression)))) - && !DECL_LOCAL_FUNCTION_P (expression)) + && !DECL_LOCAL_DECL_P (expression)) { gcc_assert (!dependent_type_p (TREE_TYPE (expression)) || undeduced_auto_decl (expression)); diff --git c/gcc/cp/semantics.c w/gcc/cp/semantics.c index 107d39ddb0e..dafb4032c00 100644 --- c/gcc/cp/semantics.c +++ w/gcc/cp/semantics.c @@ -2518,7 +2518,7 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, { tree ifn = get_first_fn (fn); if (TREE_CODE (ifn) == FUNCTION_DECL - && DECL_LOCAL_FUNCTION_P (ifn)) + && DECL_LOCAL_DECL_P (ifn)) orig_fn = DECL_NAME (ifn); } diff --git c/libcc1/libcp1plugin.cc w/libcc1/libcp1plugin.cc index a83bfeb0a16..c8b30113ce6 100644 --- c/libcc1/libcp1plugin.cc +++ w/libcc1/libcp1plugin.cc @@ -3294,7 +3294,7 @@ plugin_build_call_expr (cc1_plugin::connection *self, fn = STRIP_TEMPLATE (fn); if (!DECL_FUNCTION_MEMBER_P (fn) - && !DECL_LOCAL_FUNCTION_P (fn)) + && !DECL_LOCAL_DECL_P (fn)) koenig_p = true; } }