From patchwork Tue Jan 21 15:17:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 1226626 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=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-517899-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=OdSKN635; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=E+vJBJnf; 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 482BxK64XMz9sRk for ; Wed, 22 Jan 2020 02:17:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:content-type :content-transfer-encoding; q=dns; s=default; b=VFE8ypYufhC265tw EDM36T3avSXZvbuHvlsXPSKCjgBVrUHpzbElw8XJZc1ia/hnI9/hXWZw5BoaVh/5 WU6VFe2nyfzsnC3JxwiN7ceSl9iyfdt54RxmNRWVcJikSz8jV58tsGnMcN9MiGC7 rLtgBFrcluAujnl7eLkNCV8bH5s= 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 :to:subject:date:message-id:content-type :content-transfer-encoding; s=default; bh=XKMpHItDw2kIBaWznuDnwJ hnAoc=; b=OdSKN635PeqODQxSEG25AeRJ2jZw65HzHvmqYwG/8/Jm/tgC0VbLYJ Y8ZLv7R8iI7oBYD9KygsQSjg1tfC3nZtUA+R10k/De0++0+hn27cTn63ukPw4acr J+NCST/XW7CdrEf7Ammk/dzWvA51sT2CdJM9qH6dLh20TW5t5BVjc= Received: (qmail 21053 invoked by alias); 21 Jan 2020 15:17:49 -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 20982 invoked by uid 89); 21 Jan 2020 15:17:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=H*F:U*jason, 91476 X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-1.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 21 Jan 2020 15:17:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1579619857; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=auaK8ddtgF8KU0p0t/wQIR3B9q+pPQJ7Cmrbm90S8X4=; b=E+vJBJnfodb2RiFT1gEO8d4ClYztVOmYA1r7/sSDPrKqn01Da2FgoUJPDLkxbIrtkzUEvY C9YtVp7VW6CFNMb0xZI0UC37u+Wu7POif1RLTfdyTMJM2BkHfIXbI/QVMKGedudy1uNJc1 SQhJ55HQTuadfCPhruLkok2GPmamhV4= Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-389-5JqrZhFfPy-2prTSqaLsYw-1; Tue, 21 Jan 2020 10:17:34 -0500 Received: by mail-qv1-f71.google.com with SMTP id r9so1779319qvs.19 for ; Tue, 21 Jan 2020 07:17:34 -0800 (PST) Received: from barrymore.redhat.com (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id a14sm11701513qta.97.2020.01.21.07.17.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jan 2020 07:17:32 -0800 (PST) From: Jason Merrill To: gcc-patches@gcc.gnu.org Subject: [PATCH] PR c++/91476 - anon-namespace reference temp clash between TUs. Date: Tue, 21 Jan 2020 10:17:31 -0500 Message-Id: <20200121151731.24798-1-jason@redhat.com> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-IsSubscribed: yes The problem in the PR was that make_temporary_var_for_ref_to_temp ran before determine_visibility, so when we copied the linkage of the reference variable it had not yet been restricted by its anonymous namespace context, so the temporary wrongly ended up with TREE_PUBLIC set. The natural solution is to run determine_visibility earlier. But that needs to happen after maybe_commonize_var increases the linkage of some local variables, and on targets without weak symbol support, that function does different things based on the results of check_initializer, which is what calls make_temporary_var_for_ref_to_temp. To break this circular dependency I'm calling maybe_commonize_var early, and then again later if the target doesn't support weak symbols. It also occurred to me that make_temporary_var_for_ref_to_temp wasn't handling DECL_VISIBILITY at all, and verified that we were doing the wrong thing. So I've combined the linkage-copying code from there and two other places. Tested x86_64-pc-linux-gnu, applying to trunk. * decl2.c (copy_linkage): Factor out of get_guard. * call.c (make_temporary_var_for_ref_to_temp): Use it. * decl.c (cp_finish_decomp): Use it. (cp_finish_decl): determine_visibility sooner. --- gcc/cp/cp-tree.h | 1 + gcc/cp/call.c | 9 +---- gcc/cp/decl.c | 33 +++++++---------- gcc/cp/decl2.c | 36 ++++++++++++------- .../g++.dg/ext/visibility/ref-temp1.C | 17 +++++++++ 5 files changed, 55 insertions(+), 41 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C base-commit: f0aec8643830a50812aeec0296086ed338aac678 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 890d5a27350..77bcf046608 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6636,6 +6636,7 @@ extern bool mark_used (tree); extern bool mark_used (tree, tsubst_flags_t); extern void finish_static_data_member_decl (tree, tree, bool, tree, int); extern tree cp_build_parm_decl (tree, tree, tree); +extern void copy_linkage (tree, tree); extern tree get_guard (tree); extern tree get_guard_cond (tree, bool); extern tree set_guard (tree); diff --git a/gcc/cp/call.c b/gcc/cp/call.c index d47747117b9..aacd961faa1 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -11973,14 +11973,7 @@ make_temporary_var_for_ref_to_temp (tree decl, tree type) GR and suffixed with a sequence number mangled using the usual rules for a seq-id. Temporaries are numbered with a pre-order, depth-first, left-to-right walk of the complete initializer. */ - - TREE_STATIC (var) = TREE_STATIC (decl); - TREE_PUBLIC (var) = TREE_PUBLIC (decl); - if (vague_linkage_p (decl)) - comdat_linkage (var); - - CP_DECL_THREAD_LOCAL_P (var) = CP_DECL_THREAD_LOCAL_P (decl); - set_decl_tls_model (var, DECL_TLS_MODEL (decl)); + copy_linkage (var, decl); tree name = mangle_ref_init_variable (decl); DECL_NAME (var) = name; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 28a79029d92..47ff7eea88f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -7657,6 +7657,14 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, TREE_READONLY (decl) = 0; } + /* This needs to happen before extend_ref_init_temps. */ + if (VAR_OR_FUNCTION_DECL_P (decl)) + { + if (VAR_P (decl)) + maybe_commonize_var (decl); + determine_visibility (decl); + } + if (VAR_P (decl)) { duration_kind dk = decl_storage_duration (decl); @@ -7786,12 +7794,11 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, if (VAR_P (decl)) { layout_var_decl (decl); - maybe_commonize_var (decl); + if (!flag_weak) + /* Check again now that we have an initializer. */ + maybe_commonize_var (decl); } - /* This needs to happen after the linkage is set. */ - determine_visibility (decl); - if (var_definition_p && TREE_STATIC (decl)) { /* If a TREE_READONLY variable needs initialization @@ -8328,23 +8335,7 @@ cp_finish_decomp (tree decl, tree first, unsigned int count) } if (!processing_template_decl) { - TREE_PUBLIC (v[i]) = TREE_PUBLIC (decl); - TREE_STATIC (v[i]) = TREE_STATIC (decl); - DECL_COMMON (v[i]) = DECL_COMMON (decl); - DECL_COMDAT (v[i]) = DECL_COMDAT (decl); - if (TREE_STATIC (v[i])) - { - CP_DECL_THREAD_LOCAL_P (v[i]) - = CP_DECL_THREAD_LOCAL_P (decl); - set_decl_tls_model (v[i], DECL_TLS_MODEL (decl)); - if (DECL_ONE_ONLY (decl)) - make_decl_one_only (v[i], cxx_comdat_group (v[i])); - if (TREE_PUBLIC (decl)) - DECL_WEAK (v[i]) = DECL_WEAK (decl); - DECL_VISIBILITY (v[i]) = DECL_VISIBILITY (decl); - DECL_VISIBILITY_SPECIFIED (v[i]) - = DECL_VISIBILITY_SPECIFIED (decl); - } + copy_linkage (v[i], decl); cp_finish_decl (v[i], init, /*constexpr*/false, /*asm*/NULL_TREE, LOOKUP_NORMAL); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 042d6fa12df..1ecf0b937d5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3214,6 +3214,29 @@ build_cleanup (tree decl) return clean; } +/* GUARD is a helper variable for DECL; make them have the same linkage and + visibility. */ + +void +copy_linkage (tree guard, tree decl) +{ + TREE_PUBLIC (guard) = TREE_PUBLIC (decl); + TREE_STATIC (guard) = TREE_STATIC (decl); + DECL_COMMON (guard) = DECL_COMMON (decl); + DECL_COMDAT (guard) = DECL_COMDAT (decl); + if (TREE_STATIC (guard)) + { + CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl); + set_decl_tls_model (guard, DECL_TLS_MODEL (decl)); + /* We can't rely on DECL_WEAK (decl) or DECL_ONE_ONLY (decl) here, as + they may not be set until import_export_decl at EOF. */ + if (vague_linkage_p (decl)) + comdat_linkage (guard); + DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl); + DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl); + } +} + /* Returns the initialization guard variable for the variable DECL, which has static storage duration. */ @@ -3236,18 +3259,7 @@ get_guard (tree decl) VAR_DECL, sname, guard_type); /* The guard should have the same linkage as what it guards. */ - TREE_PUBLIC (guard) = TREE_PUBLIC (decl); - TREE_STATIC (guard) = TREE_STATIC (decl); - DECL_COMMON (guard) = DECL_COMMON (decl); - DECL_COMDAT (guard) = DECL_COMDAT (decl); - CP_DECL_THREAD_LOCAL_P (guard) = CP_DECL_THREAD_LOCAL_P (decl); - set_decl_tls_model (guard, DECL_TLS_MODEL (decl)); - if (DECL_ONE_ONLY (decl)) - make_decl_one_only (guard, cxx_comdat_group (guard)); - if (TREE_PUBLIC (decl)) - DECL_WEAK (guard) = DECL_WEAK (decl); - DECL_VISIBILITY (guard) = DECL_VISIBILITY (decl); - DECL_VISIBILITY_SPECIFIED (guard) = DECL_VISIBILITY_SPECIFIED (decl); + copy_linkage (guard, decl); DECL_ARTIFICIAL (guard) = 1; DECL_IGNORED_P (guard) = 1; diff --git a/gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C b/gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C new file mode 100644 index 00000000000..ecb62326e1b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/visibility/ref-temp1.C @@ -0,0 +1,17 @@ +// PR c++/91476 +// Test that hidden and internal visibility propagates to reference temps. + +#define HIDDEN __attribute((visibility("hidden"))) + +// { dg-final { scan-hidden "_ZGRZ1fvE3foo_" } } +HIDDEN inline const int* f() { static const int &foo = 1; return &foo; } + +// { dg-final { scan-assembler-not "(weak|globl)\[^\n\]*_ZGRN12_GLOBAL__N_13fooE_" } } +namespace { const int &foo = 1; } + +const void *volatile p; +int main() +{ + p = f(); + p = &foo; +}