From patchwork Thu Feb 18 15:01:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1441685 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; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=hXJMG8uL; 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 4DhHwp072dz9sCD for ; Fri, 19 Feb 2021 02:01:45 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 19C3B388E839; Thu, 18 Feb 2021 15:01:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 19C3B388E839 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1613660502; bh=e1Q0+7grDQIcYT9b10cu2XDGXPJoZYgUgl/ECAG+nKU=; h=References:In-Reply-To:Date:Subject:To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=hXJMG8uL8+QMpMKmvfAV/m/Ss/Aqx4XTFvZpbomtY2Fes8M1hTDcSWJNVZbCLfiDN oA7oKm5WODJsP0TJwGDWNfUETKWBAylrjt1he96dmMF/lropFKC2SF+1fYu6Y2xe4n Bveb/4DsV7Q7xgkzURSxHF9wQ+p3NwJpFALJ9LnY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ot1-x32a.google.com (mail-ot1-x32a.google.com [IPv6:2607:f8b0:4864:20::32a]) by sourceware.org (Postfix) with ESMTPS id 22DB2386F420 for ; Thu, 18 Feb 2021 15:01:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 22DB2386F420 Received: by mail-ot1-x32a.google.com with SMTP id c16so2133493otp.0 for ; Thu, 18 Feb 2021 07:01:37 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=e1Q0+7grDQIcYT9b10cu2XDGXPJoZYgUgl/ECAG+nKU=; b=ndRchJDya7VklbzIhaKcIl5P/+tQTwQlRTHgvXfZ2z43ah1hylsyi8rjZLqRvc6VBF GH+3e5gZUlzeMEqnLRXjfnDWfwsDQBiYFQ42KKScM7iQK9guA41J+OD/HlFGGeYZ8+36 68nB+vETPDlO8jUbC0Ppp/l4CXuQyWZ4LIK63AEpiw8gv+u1YryCuIneCyPhIZD1i36m wSTyJOpwv2Bgby0h62OoH7eJwsKLL4vzGuxnJIa42aLqsRnYSqnWpK0IHglbsXvUVYfN i2rwe7BnUdjFWLdgr47F+7ntSCnw+pvVB9PTXnysoMscpS4tHPFWLHtCe9jpGd7Zwhi1 CdvA== X-Gm-Message-State: AOAM530tv8RayG9e/vtN5s4d/7AQqLOmhkVSccY+kB0OUpqSxSlaUCrY 0retrPFNXGaOI+ecOme3Fqxfjjokx40RBxAR5lo= X-Google-Smtp-Source: ABdhPJzYXaDqRPMemct45i131IMHBU9a9AdKosrNLsZviMhVqFmJBfPudtnEa9sOA5BwcXDMnh7Y5mzAXgxe2tDe55M= X-Received: by 2002:a9d:bcb:: with SMTP id 69mr3114123oth.269.1613660496389; Thu, 18 Feb 2021 07:01:36 -0800 (PST) MIME-Version: 1.0 References: <20210215223507.39713-1-hjl.tools@gmail.com> <20210216164547.GC4020736@tucnak> <20210217142638.GO4020736@tucnak> <20210217185656.GP4020736@tucnak> <20210217201409.GQ4020736@tucnak> In-Reply-To: Date: Thu, 18 Feb 2021 07:01:00 -0800 Message-ID: Subject: [PATCH v7] Add retain attribute to place symbols in SHF_GNU_RETAIN section To: Richard Biener X-Spam-Status: No, score=-3036.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, 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: , X-Patchwork-Original-From: "H.J. Lu via Gcc-patches" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Jakub Jelinek , GCC Patches Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" On Thu, Feb 18, 2021 at 2:25 AM Richard Biener wrote: > > On Thu, Feb 18, 2021 at 5:15 AM H.J. Lu via Gcc-patches > wrote: > > > > On Wed, Feb 17, 2021 at 12:50 PM H.J. Lu wrote: > > > > > > On Wed, Feb 17, 2021 at 12:14 PM Jakub Jelinek wrote: > > > > > > > > On Wed, Feb 17, 2021 at 12:04:34PM -0800, H.J. Lu wrote:> > > > > > > + /* For -fretain-used-symbol, a "used" attribute also implies "retain". */ > > > > > > > > s/-symbol/-symbols/ > > > > > > Fixed. > > > > > > > > + if (flag_retain_used_symbols > > > > > + && attributes > > > > > + && (TREE_CODE (*node) == FUNCTION_DECL > > > > > + || (VAR_P (*node) && TREE_STATIC (*node)) > > > > > + || (TREE_CODE (*node) == TYPE_DECL)) > > > > > > > > What will "retain" do on TYPE_DECLs? It only makes sense to me > > > > for FUNCTION_DECL or non-automatic VAR_DECLs, unless for types > > > > it means the types with that result in vars with those types automatically > > > > getting "retain", but there is no code for that and I don't see "used" > > > > handled that way. > > > > > > Fixed. > > > > > > > > + if (SUPPORTS_SHF_GNU_RETAIN > > > > > + && (TREE_CODE (node) == FUNCTION_DECL > > > > > + || (VAR_P (node) && TREE_STATIC (node)) > > > > > + || (TREE_CODE (node) == TYPE_DECL))) > > > > > > > > Likewise. > > > > > > Fixed. > > > > > > > > + ; > > > > > + else > > > > > + { > > > > > + warning (OPT_Wattributes, "%qE attribute ignored", name); > > > > > + *no_add_attrs = true; > > > > > + } > > > > > + > > > > > + return NULL_TREE; > > > > > +} > > > > > + > > > > > /* Handle a "externally_visible" attribute; arguments as in > > > > > struct attribute_spec.handler. */ > > > > > > > > > > diff --git a/gcc/common.opt b/gcc/common.opt > > > > > index c75dd36843e..70842481d4d 100644 > > > > > --- a/gcc/common.opt > > > > > +++ b/gcc/common.opt > > > > > @@ -2404,6 +2404,10 @@ frerun-loop-opt > > > > > Common Ignore > > > > > Does nothing. Preserved for backward compatibility. > > > > > > > > > > +fretain-used-symbols > > > > > +Common Var(flag_retain_used_symbols) > > > > > +Make the used attribute to imply the retain attribute if supported. > > > > > > > > English is not my native language, but I think the "to " doesn't belong > > > > here. > > > > > > Fixed. > > > > > > > > +@item -fretain-used-symbols > > > > > +@opindex fretain-used-symbols > > > > > +On systems with recent GNU assembler and linker, the compiler makes > > > > > > > > I think we should avoid recent here, new/old/recent etc. are relative terms. > > > > Either use exact version (is it 2.36 or later) or say GNU assembler and > > > > linker that supports the @code{.retain} directive or something similar. > > > > > > Fixed. > > > > > > > > flags |= SECTION_NAMED; > > > > > - if (SUPPORTS_SHF_GNU_RETAIN > > > > > - && decl != nullptr > > > > > + if (decl != nullptr > > > > > && DECL_P (decl) > > > > > - && DECL_PRESERVE_P (decl)) > > > > > + && DECL_PRESERVE_P (decl) > > > > > + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) > > > > > flags |= SECTION_RETAIN; > > > > > if (*slot == NULL) > > > > > { > > > > > > > > I think none of the varasm.c code should use DECL_PRESERVE_P when it means > > > > retain, just lookup_attribute. > > > > > > Fixed. > > > > > > > > @@ -487,7 +487,8 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, > > > > > if (DECL_SECTION_NAME (decl) == NULL > > > > > && targetm_common.have_named_sections > > > > > && (flag_function_or_data_sections > > > > > - || (SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)) > > > > > + || (DECL_PRESERVE_P (decl) > > > > > + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) > > > > > || DECL_COMDAT_GROUP (decl))) > > > > > { > > > > > targetm.asm_out.unique_section (decl, reloc); > > > > > @@ -1227,7 +1228,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p) > > > > > vnode->get_constructor (); > > > > > > > > > > if (DECL_COMMON (decl) > > > > > - && !(SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))) > > > > > + && !(DECL_PRESERVE_P (decl) > > > > > + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))) > > > > > { > > > > > /* If the decl has been given an explicit section name, or it resides > > > > > in a non-generic address space, then it isn't common, and shouldn't > > > > > @@ -7761,12 +7763,14 @@ switch_to_section (section *new_section, tree decl) > > > > > { > > > > > if (in_section == new_section) > > > > > { > > > > > - if (SUPPORTS_SHF_GNU_RETAIN > > > > > - && (new_section->common.flags & SECTION_NAMED) > > > > > + if ((new_section->common.flags & SECTION_NAMED) > > > > > && decl != nullptr > > > > > && DECL_P (decl) > > > > > && (!!DECL_PRESERVE_P (decl) > > > > > - != !!(new_section->common.flags & SECTION_RETAIN))) > > > > > + != !!(new_section->common.flags & SECTION_RETAIN)) > > > > > + && (lookup_attribute ("retain", > > > > > + DECL_ATTRIBUTES (new_section->named.decl)) > > > > > + || lookup_attribute ("retain", DECL_ATTRIBUTES (decl)))) > > > > > { > > > > > /* If the SECTION_RETAIN bit doesn't match, switch to a new > > > > > section. */ > > > > > -- > > > > > 2.29.2 > > > > > > > > > > > Here is the updated patch. > > > > > > > Here is the updated patch. Tested on Linux/x86-64 with binutils > > master branch. OK for master? > > If you can split it up into adding the 'retain' attribute and the > new -fretain-used-symbols option (which I think should not be > added) I'll approve the 'retain' attribute parts plus a patch to > no longer apply SHF_GNU_RETAIN for 'used'. Done. > 'used' and 'retain' are two different things and that's how it should remain. Here is the patch. OK for master? From 76816f2a52285913b4180b3dccbb0bbe69e05389 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 15 Feb 2021 11:31:12 -0800 Subject: [PATCH v7] Add retain attribute to place symbols in SHF_GNU_RETAIN section When building Linux kernel, ld in bninutils 2.36 with GCC 11 generates thousands of ld: warning: orphan section `.data.event_initcall_finish' from `init/main.o' being placed in section `.data.event_initcall_finish' ld: warning: orphan section `.data.event_initcall_start' from `init/main.o' being placed in section `.data.event_initcall_start' ld: warning: orphan section `.data.event_initcall_level' from `init/main.o' being placed in section `.data.event_initcall_level' Since these sections are marked with SHF_GNU_RETAIN, they are placed in separate sections. They become orphan sections since they aren't expected in the Linux kernel linker script. But orphan sections normally don't work well with the Linux kernel linker script and the resulting kernel crashed. Add the "retain" attribute to place symbols in separate SHF_GNU_RETAIN sections. Issue a warning if the configured assembler/linker doesn't support SHF_GNU_RETAIN. gcc/ PR target/99113 * varasm.c (get_section): Replace SUPPORTS_SHF_GNU_RETAIN with looking up the retain attribute. (resolve_unique_section): Likewise. (get_variable_section): Likewise. (switch_to_section): Likewise. Warn when a symbol without the retain attribute and a symbol with the retain attribute are placed in the section with the same name, instead of the used attribute. * doc/extend.texi: Document the "retain" attribute. gcc/c-family/ PR target/99113 * c-attribs.c (c_common_attribute_table): Add the "retain" attribute. (handle_retain_attribute): New function. gcc/testsuite/ PR target/99113 * c-c++-common/attr-retain-1.c: New test. * c-c++-common/attr-retain-2.c: Likewise. * c-c++-common/attr-retain-3.c: Likewise. * c-c++-common/attr-retain-4.c: Likewise. * c-c++-common/attr-retain-5.c: Likewise. * c-c++-common/attr-retain-6.c: Likewise. * c-c++-common/attr-retain-7.c: Likewise. * c-c++-common/attr-retain-8.c: Likewise. * c-c++-common/attr-retain-9.c: Likewise. * c-c++-common/pr99113.c: Likewise. * gcc.c-torture/compile/attr-retain-1.c: Likewise. * gcc.c-torture/compile/attr-retain-2.c: Likewise. * c-c++-common/attr-used.c: Don't expect SHF_GNU_RETAIN section. * c-c++-common/attr-used-2.c: Likewise. * c-c++-common/attr-used-3.c: Likewise. * c-c++-common/attr-used-4.c: Likewise. * c-c++-common/attr-used-9.c: Likewise. * gcc.c-torture/compile/attr-used-retain-1.c: Likewise. * gcc.c-torture/compile/attr-used-retain-2.c: Likewise. * c-c++-common/attr-used-5.c: Don't expect warning for the used attribute nor SHF_GNU_RETAIN section. * c-c++-common/attr-used-6.c: Likewise. * c-c++-common/attr-used-7.c: Likewise. * c-c++-common/attr-used-8.c: Likewise. --- gcc/c-family/c-attribs.c | 25 ++++++++++++++ gcc/doc/extend.texi | 8 +++-- gcc/testsuite/c-c++-common/attr-retain-1.c | 16 +++++++++ gcc/testsuite/c-c++-common/attr-retain-2.c | 12 +++++++ gcc/testsuite/c-c++-common/attr-retain-3.c | 7 ++++ gcc/testsuite/c-c++-common/attr-retain-4.c | 7 ++++ gcc/testsuite/c-c++-common/attr-retain-5.c | 28 +++++++++++++++ gcc/testsuite/c-c++-common/attr-retain-6.c | 28 +++++++++++++++ gcc/testsuite/c-c++-common/attr-retain-7.c | 10 ++++++ gcc/testsuite/c-c++-common/attr-retain-8.c | 10 ++++++ gcc/testsuite/c-c++-common/attr-retain-9.c | 29 ++++++++++++++++ gcc/testsuite/c-c++-common/attr-used-2.c | 2 +- gcc/testsuite/c-c++-common/attr-used-3.c | 2 +- gcc/testsuite/c-c++-common/attr-used-4.c | 2 +- gcc/testsuite/c-c++-common/attr-used-5.c | 3 +- gcc/testsuite/c-c++-common/attr-used-6.c | 3 +- gcc/testsuite/c-c++-common/attr-used-7.c | 3 +- gcc/testsuite/c-c++-common/attr-used-8.c | 3 +- gcc/testsuite/c-c++-common/attr-used-9.c | 4 +-- gcc/testsuite/c-c++-common/attr-used.c | 2 +- gcc/testsuite/c-c++-common/pr99113.c | 7 ++++ .../gcc.c-torture/compile/attr-retain-1.c | 34 +++++++++++++++++++ .../gcc.c-torture/compile/attr-retain-2.c | 15 ++++++++ .../compile/attr-used-retain-1.c | 10 +++--- .../compile/attr-used-retain-2.c | 22 ++++++------ gcc/varasm.c | 22 ++++++------ 26 files changed, 271 insertions(+), 43 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/attr-retain-1.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-2.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-3.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-4.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-5.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-6.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-7.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-8.c create mode 100644 gcc/testsuite/c-c++-common/attr-retain-9.c create mode 100644 gcc/testsuite/c-c++-common/pr99113.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c create mode 100644 gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 0cb51fddfaa..ae31e4c1f6f 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -163,6 +163,7 @@ static tree handle_objc_root_class_attribute (tree *, tree, tree, int, bool *); static tree handle_objc_nullability_attribute (tree *, tree, tree, int, bool *); static tree handle_signed_bool_precision_attribute (tree *, tree, tree, int, bool *); +static tree handle_retain_attribute (tree *, tree, tree, int, bool *); /* Helper to define attribute exclusions. */ #define ATTR_EXCL(name, function, type, variable) \ @@ -328,6 +329,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_used_attribute, NULL }, { "unused", 0, 0, false, false, false, false, handle_unused_attribute, NULL }, + { "retain", 0, 0, true, false, false, false, + handle_retain_attribute, NULL }, { "externally_visible", 0, 0, true, false, false, false, handle_externally_visible_attribute, NULL }, { "no_reorder", 0, 0, true, false, false, false, @@ -1564,6 +1567,28 @@ handle_unused_attribute (tree *node, tree name, tree ARG_UNUSED (args), return NULL_TREE; } +/* Handle a "retain" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_retain_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + tree node = *pnode; + + if (SUPPORTS_SHF_GNU_RETAIN + && (TREE_CODE (node) == FUNCTION_DECL + || (VAR_P (node) && TREE_STATIC (node)))) + ; + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "externally_visible" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 6eb1d327e97..8bbb93724a9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3913,8 +3913,10 @@ When applied to a member function of a C++ class template, the attribute also means that the function is instantiated if the class itself is instantiated. +@item retain +@cindex @code{retain} function attribute For ELF targets that support the GNU or FreeBSD OSABIs, this attribute -will also save the function from linker garbage collection. To support +will save the function from linker garbage collection. To support this behavior, functions that have not been placed in specific sections (e.g. by the @code{section} attribute, or the @code{-ffunction-sections} option), will be placed in new, unique sections. @@ -7504,8 +7506,10 @@ When applied to a static data member of a C++ class template, the attribute also means that the member is instantiated if the class itself is instantiated. +@item retain +@cindex @code{retain} variable attribute For ELF targets that support the GNU or FreeBSD OSABIs, this attribute -will also save the variable from linker garbage collection. To support +will save the variable from linker garbage collection. To support this behavior, variables that have not been placed in specific sections (e.g. by the @code{section} attribute, or the @code{-fdata-sections} option), will be placed in new, unique sections. diff --git a/gcc/testsuite/c-c++-common/attr-retain-1.c b/gcc/testsuite/c-c++-common/attr-retain-1.c new file mode 100644 index 00000000000..d060fbf22cd --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-O3" } */ + +static void function_declaration_before(void) + __attribute__((__used__, __retain__)); + +static void function_declaration_before(void) {} + +static void function_declaration_after(void) {} + +static void function_declaration_after(void) + __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "function_declaration_before" } } */ +/* { dg-final { scan-assembler "function_declaration_after" } } */ +/* { dg-final { scan-assembler "\.text.*,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-2.c b/gcc/testsuite/c-c++-common/attr-retain-2.c new file mode 100644 index 00000000000..6baba844adc --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2" } */ + +static int xyzzy __attribute__((__used__, __retain__)) = 1; + +void foo() +{ + int x __attribute__((__retain__)); /* { dg-warning "attribute ignored|unused variable" } */ +} + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler "\.data.*,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-3.c b/gcc/testsuite/c-c++-common/attr-retain-3.c new file mode 100644 index 00000000000..a4077a1644d --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-3.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2 -fcommon" } */ + +static int xyzzy __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-4.c b/gcc/testsuite/c-c++-common/attr-retain-4.c new file mode 100644 index 00000000000..590e47cec86 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-options "-Wall -O2 -fcommon" } */ + +int xyzzy __attribute__((__used__, __retain__)); + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-5.c b/gcc/testsuite/c-c++-common/attr-retain-5.c new file mode 100644 index 00000000000..669fa90f24c --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-5.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ +/* { dg-options "-Wall -O2" } */ + +struct dtv_slotinfo_list +{ + struct dtv_slotinfo_list *next; +}; + +extern struct dtv_slotinfo_list *list; + +static int __attribute__ ((section ("__libc_freeres_fn"))) +free_slotinfo (struct dtv_slotinfo_list **elemp) +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ +{ + if (!free_slotinfo (&(*elemp)->next)) + return 0; + return 1; +} + +__attribute__ ((used, retain, section ("__libc_freeres_fn"))) +static void free_mem (void) +{ + free_slotinfo (&list); +} + +/* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-6.c b/gcc/testsuite/c-c++-common/attr-retain-6.c new file mode 100644 index 00000000000..1cf03a7d777 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-6.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ +/* { dg-options "-Wall -O2" } */ + +struct dtv_slotinfo_list +{ + struct dtv_slotinfo_list *next; +}; + +extern struct dtv_slotinfo_list *list; + +static int __attribute__ ((used, retain, section ("__libc_freeres_fn"))) +free_slotinfo (struct dtv_slotinfo_list **elemp) +{ + if (!free_slotinfo (&(*elemp)->next)) + return 0; + return 1; +} + +__attribute__ ((section ("__libc_freeres_fn"))) +void free_mem (void) +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ +{ + free_slotinfo (&list); +} + +/* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-7.c b/gcc/testsuite/c-c++-common/attr-retain-7.c new file mode 100644 index 00000000000..08f52fccc9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-7.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ +/* { dg-options "-Wall -O2" } */ + +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2; +int __attribute__((section(".data.foo"))) foo1 = 1; +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ + +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-8.c b/gcc/testsuite/c-c++-common/attr-retain-8.c new file mode 100644 index 00000000000..2dbec9e14f0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-8.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ +/* { dg-options "-Wall -O2" } */ + +int __attribute__((section(".data.foo"))) foo1 = 1; +/* { dg-warning "'.*' without 'retain' attribute and '.*' with 'retain' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ +int __attribute__((used,retain,section(".data.foo"))) foo2 = 2; + +/* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-retain-9.c b/gcc/testsuite/c-c++-common/attr-retain-9.c new file mode 100644 index 00000000000..f26e25d2b77 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-retain-9.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-skip-if "non-ELF target" { *-*-darwin* } } */ +/* { dg-options "-Wall -O2" } */ + +struct dtv_slotinfo_list +{ + struct dtv_slotinfo_list *next; +}; + +extern struct dtv_slotinfo_list *list; + +static int __attribute__ ((used, retain, section ("__libc_freeres_fn"))) +free_slotinfo (struct dtv_slotinfo_list **elemp) +{ + if (!free_slotinfo (&(*elemp)->next)) + return 0; + return 1; +} + +__attribute__ ((section ("__libc_freeres_fn"))) +static void free_mem (void) +/* { dg-warning "defined but not used" "" { target *-*-* } .-1 } */ +{ + free_slotinfo (&list); +} + +/* { dg-final { scan-assembler-not "__libc_freeres_fn\n" } } */ +/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-2.c b/gcc/testsuite/c-c++-common/attr-used-2.c index eef2519643f..5849747d1e4 100644 --- a/gcc/testsuite/c-c++-common/attr-used-2.c +++ b/gcc/testsuite/c-c++-common/attr-used-2.c @@ -9,4 +9,4 @@ void foo() } /* { dg-final { scan-assembler "xyzzy" } } */ -/* { dg-final { scan-assembler "\.data.*,\"awR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not "\.data.*,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-3.c b/gcc/testsuite/c-c++-common/attr-used-3.c index ca64197929c..5a6ea991dc4 100644 --- a/gcc/testsuite/c-c++-common/attr-used-3.c +++ b/gcc/testsuite/c-c++-common/attr-used-3.c @@ -4,4 +4,4 @@ static int xyzzy __attribute__((__used__)); /* { dg-final { scan-assembler "xyzzy" } } */ -/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-4.c b/gcc/testsuite/c-c++-common/attr-used-4.c index 1cbc4c703e9..40c2c659d3c 100644 --- a/gcc/testsuite/c-c++-common/attr-used-4.c +++ b/gcc/testsuite/c-c++-common/attr-used-4.c @@ -4,4 +4,4 @@ int xyzzy __attribute__((__used__)); /* { dg-final { scan-assembler "xyzzy" } } */ -/* { dg-final { scan-assembler ",\"awR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not ",\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-5.c b/gcc/testsuite/c-c++-common/attr-used-5.c index 5b4924160fd..448e19f6f0e 100644 --- a/gcc/testsuite/c-c++-common/attr-used-5.c +++ b/gcc/testsuite/c-c++-common/attr-used-5.c @@ -11,7 +11,6 @@ extern struct dtv_slotinfo_list *list; static int __attribute__ ((section ("__libc_freeres_fn"))) free_slotinfo (struct dtv_slotinfo_list **elemp) -/* { dg-warning "'.*' without 'used' attribute and '.*' with 'used' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ { if (!free_slotinfo (&(*elemp)->next)) return 0; @@ -25,4 +24,4 @@ static void free_mem (void) } /* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ -/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-6.c b/gcc/testsuite/c-c++-common/attr-used-6.c index 3cf288dd28f..b9974e2a4f2 100644 --- a/gcc/testsuite/c-c++-common/attr-used-6.c +++ b/gcc/testsuite/c-c++-common/attr-used-6.c @@ -19,10 +19,9 @@ free_slotinfo (struct dtv_slotinfo_list **elemp) __attribute__ ((section ("__libc_freeres_fn"))) void free_mem (void) -/* { dg-warning "'.*' without 'used' attribute and '.*' with 'used' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ { free_slotinfo (&list); } /* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ -/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-7.c b/gcc/testsuite/c-c++-common/attr-used-7.c index 1721a8afc4e..9c9862fcafd 100644 --- a/gcc/testsuite/c-c++-common/attr-used-7.c +++ b/gcc/testsuite/c-c++-common/attr-used-7.c @@ -4,7 +4,6 @@ int __attribute__((used,section(".data.foo"))) foo2 = 2; int __attribute__((section(".data.foo"))) foo1 = 1; -/* { dg-warning "'.*' without 'used' attribute and '.*' with 'used' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ /* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */ -/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not ".data.foo,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-8.c b/gcc/testsuite/c-c++-common/attr-used-8.c index 20662cadf70..c907ab11641 100644 --- a/gcc/testsuite/c-c++-common/attr-used-8.c +++ b/gcc/testsuite/c-c++-common/attr-used-8.c @@ -3,8 +3,7 @@ /* { dg-options "-Wall -O2" } */ int __attribute__((section(".data.foo"))) foo1 = 1; -/* { dg-warning "'.*' without 'used' attribute and '.*' with 'used' attribute are placed in a section with the same name" "" { target R_flag_in_section } .-1 } */ int __attribute__((used,section(".data.foo"))) foo2 = 2; /* { dg-final { scan-assembler ".data.foo,\"aw\"" { target R_flag_in_section } } } */ -/* { dg-final { scan-assembler ".data.foo,\"awR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not ".data.foo,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used-9.c b/gcc/testsuite/c-c++-common/attr-used-9.c index 5847b0550ce..049c0beb1ee 100644 --- a/gcc/testsuite/c-c++-common/attr-used-9.c +++ b/gcc/testsuite/c-c++-common/attr-used-9.c @@ -25,5 +25,5 @@ static void free_mem (void) } /* { dg-final { scan-assembler-not "__libc_freeres_fn\n" } } */ -/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ -/* { dg-final { scan-assembler "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler "__libc_freeres_fn,\"ax\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not "__libc_freeres_fn,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/attr-used.c b/gcc/testsuite/c-c++-common/attr-used.c index 2036533c959..96c6d674346 100644 --- a/gcc/testsuite/c-c++-common/attr-used.c +++ b/gcc/testsuite/c-c++-common/attr-used.c @@ -11,4 +11,4 @@ static void function_declaration_after(void) __attribute__((__used__)); /* { dg-final { scan-assembler "function_declaration_before" } } */ /* { dg-final { scan-assembler "function_declaration_after" } } */ -/* { dg-final { scan-assembler "\.text.*,\"axR\"" { target R_flag_in_section } } } */ +/* { dg-final { scan-assembler-not "\.text.*,\"axR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/c-c++-common/pr99113.c b/gcc/testsuite/c-c++-common/pr99113.c new file mode 100644 index 00000000000..01814014ac8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr99113.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall -O2" } */ + +static int xyzzy __attribute__((__used__)) = 1; + +/* { dg-final { scan-assembler "xyzzy" } } */ +/* { dg-final { scan-assembler-not "\.data.*,\"awR\"" { target R_flag_in_section } } } */ diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c b/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c new file mode 100644 index 00000000000..6cab15547cc --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/attr-retain-1.c @@ -0,0 +1,34 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-final { scan-assembler ".text.*,\"axR\"" } } */ +/* { dg-final { scan-assembler ".bss.*,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.*,\"awR\"" } } */ +/* { dg-final { scan-assembler ".rodata.*,\"aR\"" } } */ +/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ + +void __attribute__((used,retain)) used_fn (void) { } +void unused_fn (void) { } +void __attribute__((hot,used,retain)) used_hot_fn (void) { } +void __attribute__((hot)) unused_hot_fn (void) { } +void __attribute__((cold,used,retain)) used_cold_fn (void) { } +void __attribute__((cold)) unused_cold_fn (void) { } +int __attribute__((used,retain)) used_bss = 0; +int __attribute__((used,retain)) used_data = 1; +const int __attribute__((used,retain)) used_rodata = 2; +int __attribute__((used,retain)) used_comm; +static int __attribute__((used,retain)) used_lcomm; + +int unused_bss = 0; +int unused_data = 1; +const int unused_rodata = 2; +int unused_comm; +static int unused_lcomm; + +/* Test switching back to the used,retained sections. */ +void __attribute__((used,retain)) used_fn2 (void) { } +int __attribute__((used,retain)) used_bss2 = 0; +int __attribute__((used,retain)) used_data2 = 1; +const int __attribute__((used,retain)) used_rodata2 = 2; +int __attribute__((used,retain)) used_comm2; +static int __attribute__((used,retain)) used_lcomm2; + +int __attribute__((used,retain,section(".data.used_foo_sec"))) used_foo = 2; diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c new file mode 100644 index 00000000000..0208ffe37ab --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/attr-retain-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target R_flag_in_section } } */ +/* { dg-final { scan-assembler ".text.used_fn,\"axR\"" } } */ +/* { dg-final { scan-assembler ".text.used_fn2,\"axR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_bss,\"awR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_bss2,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.used_data,\"awR\"" } } */ +/* { dg-final { scan-assembler ".data.used_data2,\"awR\"" } } */ +/* { dg-final { scan-assembler ".rodata.used_rodata,\"aR\"" } } */ +/* { dg-final { scan-assembler ".rodata.used_rodata2,\"aR\"" } } */ +/* { dg-final { scan-assembler ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ +/* { dg-options "-ffunction-sections -fdata-sections" } */ + +#include "attr-retain-1.c" diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c index 5f6cbca6e33..bf5ca48c316 100644 --- a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c +++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-1.c @@ -1,10 +1,10 @@ /* { dg-do compile } */ /* { dg-require-effective-target R_flag_in_section } */ -/* { dg-final { scan-assembler ".text.*,\"axR\"" } } */ -/* { dg-final { scan-assembler ".bss.*,\"awR\"" } } */ -/* { dg-final { scan-assembler ".data.*,\"awR\"" } } */ -/* { dg-final { scan-assembler ".rodata.*,\"aR\"" } } */ -/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".text.*,\"axR\"" } } */ +/* { dg-final { scan-assembler-not ".bss.*,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".data.*,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".rodata.*,\"aR\"" } } */ +/* { dg-final { scan-assembler-not ".data.used_foo_sec,\"awR\"" } } */ void __attribute__((used)) used_fn (void) { } void unused_fn (void) { } diff --git a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c index be5f3917ac8..7858e62c154 100644 --- a/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c +++ b/gcc/testsuite/gcc.c-torture/compile/attr-used-retain-2.c @@ -1,16 +1,16 @@ /* { dg-do compile } */ /* { dg-require-effective-target R_flag_in_section } */ -/* { dg-final { scan-assembler ".text.used_fn,\"axR\"" } } */ -/* { dg-final { scan-assembler ".text.used_fn2,\"axR\"" } } */ -/* { dg-final { scan-assembler ".bss.used_bss,\"awR\"" } } */ -/* { dg-final { scan-assembler ".bss.used_bss2,\"awR\"" } } */ -/* { dg-final { scan-assembler ".data.used_data,\"awR\"" } } */ -/* { dg-final { scan-assembler ".data.used_data2,\"awR\"" } } */ -/* { dg-final { scan-assembler ".rodata.used_rodata,\"aR\"" } } */ -/* { dg-final { scan-assembler ".rodata.used_rodata2,\"aR\"" } } */ -/* { dg-final { scan-assembler ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */ -/* { dg-final { scan-assembler ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */ -/* { dg-final { scan-assembler ".data.used_foo_sec,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".text.used_fn,\"axR\"" } } */ +/* { dg-final { scan-assembler-not ".text.used_fn2,\"axR\"" } } */ +/* { dg-final { scan-assembler-not ".bss.used_bss,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".bss.used_bss2,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".data.used_data,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".data.used_data2,\"awR\"" } } */ +/* { dg-final { scan-assembler-not ".rodata.used_rodata,\"aR\"" } } */ +/* { dg-final { scan-assembler-not ".rodata.used_rodata2,\"aR\"" } } */ +/* { dg-final { scan-assembler-not ".bss.used_lcomm,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler-not ".bss.used_lcomm2,\"awR\"" { target arm-*-* } } } */ +/* { dg-final { scan-assembler-not ".data.used_foo_sec,\"awR\"" } } */ /* { dg-options "-ffunction-sections -fdata-sections" } */ #include "attr-used-retain-1.c" diff --git a/gcc/varasm.c b/gcc/varasm.c index 29478ab0d8d..811212244a5 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -297,10 +297,9 @@ get_section (const char *name, unsigned int flags, tree decl, slot = section_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT); flags |= SECTION_NAMED; - if (SUPPORTS_SHF_GNU_RETAIN - && decl != nullptr + if (decl != nullptr && DECL_P (decl) - && DECL_PRESERVE_P (decl)) + && lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) flags |= SECTION_RETAIN; if (*slot == NULL) { @@ -487,7 +486,7 @@ resolve_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED, if (DECL_SECTION_NAME (decl) == NULL && targetm_common.have_named_sections && (flag_function_or_data_sections - || (SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl)) + || lookup_attribute ("retain", DECL_ATTRIBUTES (decl)) || DECL_COMDAT_GROUP (decl))) { targetm.asm_out.unique_section (decl, reloc); @@ -1227,7 +1226,7 @@ get_variable_section (tree decl, bool prefer_noswitch_p) vnode->get_constructor (); if (DECL_COMMON (decl) - && !(SUPPORTS_SHF_GNU_RETAIN && DECL_PRESERVE_P (decl))) + && !lookup_attribute ("retain", DECL_ATTRIBUTES (decl))) { /* If the decl has been given an explicit section name, or it resides in a non-generic address space, then it isn't common, and shouldn't @@ -7761,18 +7760,19 @@ switch_to_section (section *new_section, tree decl) { if (in_section == new_section) { - if (SUPPORTS_SHF_GNU_RETAIN - && (new_section->common.flags & SECTION_NAMED) + bool retain_p; + if ((new_section->common.flags & SECTION_NAMED) && decl != nullptr && DECL_P (decl) - && (!!DECL_PRESERVE_P (decl) + && ((retain_p = !!lookup_attribute ("retain", + DECL_ATTRIBUTES (decl))) != !!(new_section->common.flags & SECTION_RETAIN))) { /* If the SECTION_RETAIN bit doesn't match, switch to a new section. */ tree used_decl, no_used_decl; - if (DECL_PRESERVE_P (decl)) + if (retain_p) { new_section->common.flags |= SECTION_RETAIN; used_decl = decl; @@ -7786,8 +7786,8 @@ switch_to_section (section *new_section, tree decl) no_used_decl = decl; } warning (OPT_Wattributes, - "%+qD without % attribute and %qD with " - "% attribute are placed in a section with " + "%+qD without % attribute and %qD with " + "% attribute are placed in a section with " "the same name", no_used_decl, used_decl); inform (DECL_SOURCE_LOCATION (used_decl), "%qD was declared here", used_decl); -- 2.29.2