From patchwork Sat Nov 6 00:21:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 47145 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 45BB43857C65 for ; Sat, 6 Nov 2021 00:22:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 45BB43857C65 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1636158141; bh=2DtlLPBP3+C/S3xIqWfkDs+cjFqHcuynzML/uw16hXw=; h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=tmk6hr09XVIPtivbQDx7DKtPYd5gVLc0122lI00EGYcyyOjcEEFSExeK9RYLACNPd xZAHbZ+FvwLMmS6DLXR9qJyNo23SrD4gGGbXxGsgP9F00zRD5cFznCMmm4o/7ap0B+ k73Kw2mG26i77/Cq28H8VPPk08nV5fZeraan4LBk= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 7C9D93858421 for ; Sat, 6 Nov 2021 00:21:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7C9D93858421 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-72-7eMehY6ZNXaDkAybe4skVA-1; Fri, 05 Nov 2021 20:21:48 -0400 X-MC-Unique: 7eMehY6ZNXaDkAybe4skVA-1 Received: by mail-qv1-f71.google.com with SMTP id c15-20020a0cd60f000000b0038509b60a93so9656454qvj.20 for ; Fri, 05 Nov 2021 17:21:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=2DtlLPBP3+C/S3xIqWfkDs+cjFqHcuynzML/uw16hXw=; b=ySRw/g80DTiER9bQsGp2mCqD7Iw8EtyN6UDk0arHWiYnRR4i+oWVdVF9LdLfCjfx2b maweKJIQLCa+dwcnwPZ81HmWyg7i5c7NI5/qmzYfYgcjFgqCv3xGONWpZlXB/1h2nZYk YGguAwmH1izFl6NLnGi7zqjoEkxEFu/Il7EvkmsZuJlK56v+DoVKLaqeQS6T0B35V3rb FNG4SAo5oQQFp9DxnFuXk1uT+HOgmXrmxf6bQrfx8Uw/IOWcL6ePj0jnUUGyf3AqCCo/ /tWCps5CPTO8lFF3/DmrfAQEnVPLLI4akblI+jRSz1az1ZPTs3gcVGtvo7twYp/szx1I B3OQ== X-Gm-Message-State: AOAM532OGZX0lrxeDx96dA0u8c5x9NyBKNXFzfyeIShgLr/L59CT6Shh Q8z2iT3cZZ6dna6ACDOU850eewMlmLySDr7WwsuMT9czcBqWeU+YmqxKF5xMRljJYx4jBw+ehOt WO5O+8sgakl8FWvd+wQ== X-Received: by 2002:a05:622a:170c:: with SMTP id h12mr35787732qtk.248.1636158107220; Fri, 05 Nov 2021 17:21:47 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxHp4LUVXmqfUfxUNMTDrmuWSps27Os04MTJNTcZ3V0tD+n75t3DDpSSKUYI+oOiIKccd7wHQ== X-Received: by 2002:a05:622a:170c:: with SMTP id h12mr35787692qtk.248.1636158106761; Fri, 05 Nov 2021 17:21:46 -0700 (PDT) Received: from redhat.com ([2601:184:4780:4310::aac2]) by smtp.gmail.com with ESMTPSA id y7sm6897441qtj.39.2021.11.05.17.21.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 05 Nov 2021 17:21:45 -0700 (PDT) Date: Fri, 5 Nov 2021 20:21:43 -0400 To: Jason Merrill Subject: [PATCH v5] attribs: Implement -Wno-attributes=vendor::attr [PR101940] Message-ID: References: <20210920170658.28014-1-polacek@redhat.com> <20210920173859.GK304296@tucnak> <20210920190809.GM304296@tucnak> <8636350f-e588-12d1-b687-89245de0b62d@redhat.com> <89690210-3ac3-9486-1fa0-742fc67d3748@redhat.com> MIME-Version: 1.0 In-Reply-To: <89690210-3ac3-9486-1fa0-742fc67d3748@redhat.com> User-Agent: Mutt/2.1.3 (2021-09-10) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Cc: Jakub Jelinek , GCC Patches Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" On Fri, Nov 05, 2021 at 02:48:31PM -0400, Jason Merrill wrote: > On 9/28/21 16:20, Marek Polacek wrote: > > On Thu, Sep 23, 2021 at 02:25:16PM -0400, Jason Merrill wrote: > > > On 9/20/21 18:59, Marek Polacek via Gcc-patches wrote: > > > > + handle_ignored_attributes_option (&v); > > > > + /* ??? We can't free (args); here. */ > > > > > > Perhaps we want to copy strings in handle_ignored_attributes_option rather > > > than here? > > > > Well, the other use doesn't need copying, so I left it be. > > But the other use is modifying the strings passed on the command line, which > also seems questionable. I think it would be better for > handle_ignored_attributes_option to copy the relevant pieces out. > > The patch looks good outside of this issue. Thanks, so like this? I'm including an incremental diff so that it's clear what changed: base-commit: bcf3728abe8488882922005166d3065fc5fdfea1 diff --git a/gcc/attribs.c b/gcc/attribs.c index d5fba7f4bbb..addfe6f6c80 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -237,7 +237,7 @@ check_attribute_tables (void) the end of parsing of all TUs. */ static vec ignored_attributes_table; -/* Parse arguments ARGS of -Wno-attributes=. +/* Parse arguments V of -Wno-attributes=. Currently we accept: vendor::attr vendor:: @@ -252,12 +252,15 @@ handle_ignored_attributes_option (vec *v) for (auto opt : v) { + /* We're going to be modifying the string. */ + opt = xstrdup (opt); char *q = strstr (opt, "::"); /* We don't accept '::attr'. */ if (q == nullptr || q == opt) { error ("wrong argument to ignored attributes"); inform (input_location, "valid format is % or %"); + free (opt); continue; } /* Cut off the vendor part. */ @@ -274,6 +277,7 @@ handle_ignored_attributes_option (vec *v) if (!valid_p (vendor) || !valid_p (attr)) { error ("wrong argument to ignored attributes"); + free (opt); continue; } /* Turn "__attr__" into "attr" so that we have a canonical form of diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 6beba5503f0..a299ceff6a2 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -817,7 +817,7 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) for (char *p = strtok (args, ","); p; p = strtok (NULL, ",")) v.safe_push (p); handle_ignored_attributes_option (&v); - /* ??? We can't free (args); here. */ + free (args); return; } else and here's the complete patch: Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >8 -- It is desirable for -Wattributes to warn about e.g. [[deprecate]] void g(); // typo, should warn However, -Wattributes also warns about vendor-specific attributes (that's because lookup_scoped_attribute_spec -> find_attribute_namespace finds nothing), which, with -Werror, causes grief. We don't want the -Wattributes warning for [[company::attr]] void f(); GCC warns because it doesn't know the "company" namespace; it only knows the "gnu" and "omp" namespaces. We could entirely disable warning about attributes in unknown scopes but then the compiler would also miss typos like [[company::attrx]] void f(); or [[gmu::warn_used_result]] int write(); so that is not a viable solution. A workaround is to use a #pragma: #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wattributes" [[company::attr]] void f() {} #pragma GCC diagnostic pop but that's a mouthful and awkward to use and could also hide typos. In fact, any macro-based solution doesn't seem like a way forward. This patch implements -Wno-attributes=, which takes these arguments: company::attr company:: This option should go well with using @file: the user could have a file containing -Wno-attributes=vendor::attr1,vendor::attr2 and then invoke gcc with '@attrs' or similar. I've also added a new pragma which has the same effect: The pragma along with the new option should help with various static analysis tools. PR c++/101940 gcc/ChangeLog: * attribs.c (struct scoped_attributes): Add a bool member. (lookup_scoped_attribute_spec): Forward declare. (register_scoped_attributes): New bool parameter, defaulted to false. Use it. (handle_ignored_attributes_option): New function. (free_attr_data): New function. (init_attributes): Call handle_ignored_attributes_option. (attr_namespace_ignored_p): New function. (decl_attributes): Check attr_namespace_ignored_p before warning. * attribs.h (free_attr_data): Declare. (register_scoped_attributes): Adjust declaration. (handle_ignored_attributes_option): Declare. * common.opt (Wattributes=): New option with a variable. * doc/extend.texi: Document #pragma GCC diagnostic ignored_attributes. * doc/invoke.texi: Document -Wno-attributes=. * opts.c (common_handle_option) : Handle. * plugin.h (register_scoped_attributes): Adjust declaration. * toplev.c (compile_file): Call free_attr_data. gcc/c-family/ChangeLog: * c-pragma.c (handle_pragma_diagnostic): Handle #pragma GCC diagnostic ignored_attributes. gcc/testsuite/ChangeLog: * c-c++-common/Wno-attributes-1.c: New test. * c-c++-common/Wno-attributes-2.c: New test. --- gcc/attribs.c | 124 +++++++++++++++++- gcc/attribs.h | 5 +- gcc/c-family/c-pragma.c | 37 +++++- gcc/common.opt | 9 +- gcc/doc/extend.texi | 19 +++ gcc/doc/invoke.texi | 20 +++ gcc/opts.c | 20 +++ gcc/plugin.h | 4 +- gcc/testsuite/c-c++-common/Wno-attributes-1.c | 55 ++++++++ gcc/testsuite/c-c++-common/Wno-attributes-2.c | 56 ++++++++ gcc/toplev.c | 2 + 11 files changed, 342 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/Wno-attributes-1.c create mode 100644 gcc/testsuite/c-c++-common/Wno-attributes-2.c diff --git a/gcc/attribs.c b/gcc/attribs.c index 83fafc98b7d..addfe6f6c80 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -87,6 +87,8 @@ struct scoped_attributes const char *ns; vec attributes; hash_table *attribute_hash; + /* True if we should not warn about unknown attributes in this NS. */ + bool ignored_p; }; /* The table of scope attributes. */ @@ -95,6 +97,8 @@ static vec attributes_table; static scoped_attributes* find_attribute_namespace (const char*); static void register_scoped_attribute (const struct attribute_spec *, scoped_attributes *); +static const struct attribute_spec *lookup_scoped_attribute_spec (const_tree, + const_tree); static bool attributes_initialized = false; @@ -121,12 +125,14 @@ extract_attribute_substring (struct substring *str) /* Insert an array of attributes ATTRIBUTES into a namespace. This array must be NULL terminated. NS is the name of attribute - namespace. The function returns the namespace into which the - attributes have been registered. */ + namespace. IGNORED_P is true iff all unknown attributes in this + namespace should be ignored for the purposes of -Wattributes. The + function returns the namespace into which the attributes have been + registered. */ scoped_attributes * register_scoped_attributes (const struct attribute_spec *attributes, - const char *ns) + const char *ns, bool ignored_p /*=false*/) { scoped_attributes *result = NULL; @@ -144,9 +150,12 @@ register_scoped_attributes (const struct attribute_spec *attributes, memset (&sa, 0, sizeof (sa)); sa.ns = ns; sa.attributes.create (64); + sa.ignored_p = ignored_p; result = attributes_table.safe_push (sa); result->attribute_hash = new hash_table (200); } + else + result->ignored_p |= ignored_p; /* Really add the attributes to their namespace now. */ for (unsigned i = 0; attributes[i].name != NULL; ++i) @@ -224,6 +233,96 @@ check_attribute_tables (void) attribute_tables[j][l].name)); } +/* Used to stash pointers to allocated memory so that we can free them at + the end of parsing of all TUs. */ +static vec ignored_attributes_table; + +/* Parse arguments V of -Wno-attributes=. + Currently we accept: + vendor::attr + vendor:: + This functions also registers the parsed attributes so that we don't + warn that we don't recognize them. */ + +void +handle_ignored_attributes_option (vec *v) +{ + if (v == nullptr) + return; + + for (auto opt : v) + { + /* We're going to be modifying the string. */ + opt = xstrdup (opt); + char *q = strstr (opt, "::"); + /* We don't accept '::attr'. */ + if (q == nullptr || q == opt) + { + error ("wrong argument to ignored attributes"); + inform (input_location, "valid format is % or %"); + free (opt); + continue; + } + /* Cut off the vendor part. */ + *q = '\0'; + char *vendor = opt; + char *attr = q + 2; + /* Verify that they look valid. */ + auto valid_p = [](const char *s) { + for (; *s != '\0'; ++s) + if (!ISALNUM (*s) && *s != '_') + return false; + return true; + }; + if (!valid_p (vendor) || !valid_p (attr)) + { + error ("wrong argument to ignored attributes"); + free (opt); + continue; + } + /* Turn "__attr__" into "attr" so that we have a canonical form of + attribute names. Likewise for vendor. */ + auto strip = [](char *&s) { + const size_t l = strlen (s); + if (l > 4 && s[0] == '_' && s[1] == '_' + && s[l - 1] == '_' && s[l - 2] == '_') + { + s[l - 2] = '\0'; + s += 2; + } + }; + strip (attr); + strip (vendor); + /* If we've already seen this vendor::attr, ignore it. Attempting to + register it twice would lead to a crash. */ + if (lookup_scoped_attribute_spec (get_identifier (vendor), + get_identifier (attr))) + continue; + /* In the "vendor::" case, we should ignore *any* attribute coming + from this attribute namespace. */ + if (attr[0] == '\0') + attr = nullptr; + /* Create a table with extra attributes which we will register. + We can't free it here, so squirrel away the pointers. */ + attribute_spec *table = new attribute_spec[2]; + ignored_attributes_table.safe_push (table); + table[0] = { attr, 0, 0, false, false, false, false, nullptr, nullptr }; + table[1] = { nullptr, 0, 0, false, false, false, false, nullptr, + nullptr }; + register_scoped_attributes (table, vendor, !attr); + } +} + +/* Free data we might have allocated when adding extra attributes. */ + +void +free_attr_data () +{ + for (auto x : ignored_attributes_table) + delete[] x; + ignored_attributes_table.release (); +} + /* Initialize attribute tables, and make some sanity checks if checking is enabled. */ @@ -252,6 +351,9 @@ init_attributes (void) /* Put all the GNU attributes into the "gnu" namespace. */ register_scoped_attributes (attribute_tables[i], "gnu"); + vec *ignored = (vec *) flag_ignored_attributes; + handle_ignored_attributes_option (ignored); + invoke_plugin_callbacks (PLUGIN_ATTRIBUTES, NULL); attributes_initialized = true; } @@ -456,6 +558,19 @@ diag_attr_exclusions (tree last_decl, tree node, tree attrname, return found; } +/* Return true iff we should not complain about unknown attributes + coming from the attribute namespace NS. This is the case for + the -Wno-attributes=ns:: command-line option. */ + +static bool +attr_namespace_ignored_p (tree ns) +{ + if (ns == NULL_TREE) + return false; + scoped_attributes *r = find_attribute_namespace (IDENTIFIER_POINTER (ns)); + return r && r->ignored_p; +} + /* Process the attributes listed in ATTRIBUTES and install them in *NODE, which is either a DECL (including a TYPE_DECL) or a TYPE. If a DECL, it should be modified in place; if a TYPE, a copy should be created @@ -556,7 +671,8 @@ decl_attributes (tree *node, tree attributes, int flags, if (spec == NULL) { - if (!(flags & (int) ATTR_FLAG_BUILT_IN)) + if (!(flags & (int) ATTR_FLAG_BUILT_IN) + && !attr_namespace_ignored_p (ns)) { if (ns == NULL_TREE || !cxx11_attr_p) warning (OPT_Wattributes, "%qE attribute directive ignored", diff --git a/gcc/attribs.h b/gcc/attribs.h index 138c509bce1..96a527f67a9 100644 --- a/gcc/attribs.h +++ b/gcc/attribs.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_ATTRIBS_H extern const struct attribute_spec *lookup_attribute_spec (const_tree); +extern void free_attr_data (); extern void init_attributes (void); /* Process the attributes listed in ATTRIBUTES and install them in *NODE, @@ -40,12 +41,14 @@ extern void apply_tm_attr (tree, tree); extern tree make_attribute (const char *, const char *, tree); extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *, - const char *); + const char *, + bool = false); extern char *sorted_attr_string (tree); extern bool common_function_versions (tree, tree); extern tree make_dispatcher_decl (const tree); extern bool is_function_default_version (const tree); +extern void handle_ignored_attributes_option (vec *); /* Return a type like TTYPE except that its TYPE_ATTRIBUTES is ATTRIBUTE. diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index a9be8df0384..a299ceff6a2 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -764,7 +764,7 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) if (token != CPP_NAME) { warning_at (loc, OPT_Wpragmas, - "missing [error|warning|ignored|push|pop]" + "missing [error|warning|ignored|push|pop|ignored_attributes]" " after %<#pragma GCC diagnostic%>"); return; } @@ -787,10 +787,43 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) diagnostic_pop_diagnostics (global_dc, input_location); return; } + else if (strcmp (kind_string, "ignored_attributes") == 0) + { + token = pragma_lex (&x, &loc); + if (token != CPP_STRING) + { + warning_at (loc, OPT_Wpragmas, + "missing attribute name after %<#pragma GCC diagnostic " + "ignored_attributes%>"); + return; + } + char *args = xstrdup (TREE_STRING_POINTER (x)); + const size_t l = strlen (args); + if (l == 0) + { + warning_at (loc, OPT_Wpragmas, "missing argument to %<#pragma GCC " + "diagnostic ignored_attributes%>"); + free (args); + return; + } + else if (args[l - 1] == ',') + { + warning_at (loc, OPT_Wpragmas, "trailing %<,%> in arguments for " + "%<#pragma GCC diagnostic ignored_attributes%>"); + free (args); + return; + } + auto_vec v; + for (char *p = strtok (args, ","); p; p = strtok (NULL, ",")) + v.safe_push (p); + handle_ignored_attributes_option (&v); + free (args); + return; + } else { warning_at (loc, OPT_Wpragmas, - "expected [error|warning|ignored|push|pop]" + "expected [error|warning|ignored|push|pop|ignored_attributes]" " after %<#pragma GCC diagnostic%>"); return; } diff --git a/gcc/common.opt b/gcc/common.opt index 1a5b9bfcca9..de9b848eda5 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -83,7 +83,7 @@ int flag_gen_aux_info = 0 Variable int flag_shlib -; These two are really VEC(char_p,heap) *. +; These three are really VEC(char_p,heap) *. Variable void *flag_instrument_functions_exclude_functions @@ -91,6 +91,9 @@ void *flag_instrument_functions_exclude_functions Variable void *flag_instrument_functions_exclude_files +Variable +void *flag_ignored_attributes + ; Generic structs (e.g. templates not explicitly specialized) ; may not have a compilation unit associated with them, and so ; may need to be treated differently from ordinary structs. @@ -549,6 +552,10 @@ Wattributes Common Var(warn_attributes) Init(1) Warning Warn about inappropriate attribute usage. +Wattributes= +Common Joined +Do not warn about specified attributes. + Wattribute-alias Common Alias(Wattribute_alias=, 1, 0) Warning Warn about type safety and similar errors and mismatches in declarations with alias attributes. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index eee4c6737bb..6e6c580e329 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -23767,6 +23767,25 @@ restored. foo(d); /* depends on command-line options */ @end smallexample +@item #pragma GCC diagnostic ignored_attributes + +Similarly to @option{-Wno-attributes=}, this pragma allows users to suppress +warnings about unknown scoped attributes (in C++11 and C2X). For example, +@code{#pragma GCC diagnostic ignored_attributes "vendor::attr"} disables +warning about the following declaration: + +@smallexample +[[vendor::attr]] void f(); +@end smallexample + +whereas @code{#pragma GCC diagnostic ignored_attributes "vendor::"} prevents +warning about both of these declarations: + +@smallexample +[[vendor::safe]] void f(); +[[vendor::unsafe]] void f2(); +@end smallexample + @end table GCC also offers a simple mechanism for printing messages during diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9fb74d34920..3b3b0a87fb3 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -8707,6 +8707,26 @@ unrecognized attributes, function attributes applied to variables, etc. This does not stop errors for incorrect use of supported attributes. +Additionally, using @option{-Wno-attributes=}, it is possible to suppress +warnings about unknown scoped attributes (in C++11 and C2X). For example, +@option{-Wno-attributes=vendor::attr} disables warning about the following +declaration: + +@smallexample +[[vendor::attr]] void f(); +@end smallexample + +It is also possible to disable warning about all attributes in a namespace +using @option{-Wno-attributes=vendor::} which prevents warning about both +of these declarations: + +@smallexample +[[vendor::safe]] void f(); +[[vendor::unsafe]] void f2(); +@end smallexample + +Note that @option{-Wno-attributes=} does not imply @option{-Wno-attributes}. + @item -Wno-builtin-declaration-mismatch @opindex Wno-builtin-declaration-mismatch @opindex Wbuiltin-declaration-mismatch diff --git a/gcc/opts.c b/gcc/opts.c index caed6255500..175b4635bb4 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2611,6 +2611,26 @@ common_handle_option (struct gcc_options *opts, /* Currently handled in a prescan. */ break; + case OPT_Wattributes_: + if (lang_mask == CL_DRIVER) + break; + + if (value) + { + error_at (loc, "arguments ignored for %<-Wattributes=%>; use " + "%<-Wno-attributes=%> instead"); + break; + } + else if (arg[strlen (arg) - 1] == ',') + { + error_at (loc, "trailing %<,%> in arguments for " + "%<-Wno-attributes=%>"); + break; + } + + add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg); + break; + case OPT_Werror: dc->warning_as_error_requested = value; break; diff --git a/gcc/plugin.h b/gcc/plugin.h index 1640e253ca5..5556763d1bf 100644 --- a/gcc/plugin.h +++ b/gcc/plugin.h @@ -197,7 +197,9 @@ invoke_plugin_callbacks (int event ATTRIBUTE_UNUSED, /* In attribs.c. */ extern void register_attribute (const struct attribute_spec *attr); +/* The default argument for the third parameter is given in attribs.h. */ extern struct scoped_attributes* register_scoped_attributes (const struct attribute_spec *, - const char *); + const char *, + bool); #endif /* PLUGIN_H */ diff --git a/gcc/testsuite/c-c++-common/Wno-attributes-1.c b/gcc/testsuite/c-c++-common/Wno-attributes-1.c new file mode 100644 index 00000000000..aac1a69fd85 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wno-attributes-1.c @@ -0,0 +1,55 @@ +/* PR c++/101940 */ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c++11" { target c++ } } */ +/* { dg-additional-options "-Wno-attributes=company::,yoyodyne::attr" } */ +/* { dg-additional-options "-Wno-attributes=c1::attr,c1::attr,c1::__attr__" } */ +/* { dg-additional-options "-Wno-attributes=c2::,c2::attr" } */ +/* { dg-additional-options "-Wno-attributes=c3::attr,c3::" } */ +/* { dg-additional-options "-Wno-attributes=x::" } */ +/* { dg-additional-options "-Wno-attributes=yoyodyne::attr_new" } */ +/* { dg-additional-options "-Wno-attributes=c4::__attr__" } */ +/* { dg-additional-options "-Wno-attributes=c5::attr" } */ +/* { dg-additional-options "-Wno-attributes=__c6__::attr" } */ + +[[company::attr]] void f1(); +[[company::attr2]] void f2(); + +[[yoyodyne::attr]] void f3(); +[[yoyodyne::__attr__]] void f3__(); +[[yoyodyne::attrx]] void f4(); /* { dg-warning "ignored" } */ +[[yoyodyne::__attrx__]] void f4__(); /* { dg-warning "ignored" } */ + +[[c1::attr]] void f5(); + +[[c2::attr]] void f6(); +[[c2::attrx]] void f7(); +[[c2::__attr__]] void f6__(); +[[c2::__attrx__]] void f7__(); + +[[c3::attr]] void f8(); +[[c3::attrx]] void f9(); + +[[x::x]] void f10(); + +[[yoyodyne::attr_new]] void f11(); +[[yoyodyne::__attr_new__]] void f11__(); +[[yoyodyne::attr_mew]] void f12(); /* { dg-warning "ignored" } */ +[[yoyodyne::__attr_mew__]] void f12__(); /* { dg-warning "ignored" } */ + +[[c4::attr]] void f13(); +[[c4::__attr__]] void f13__(); +[[c4::attrx]] void f14(); /* { dg-warning "ignored" } */ + +[[c5::attr]] void f15(); +[[c5::__attr__]] void f15__(); +[[__c5__::attr]] void __f15(); +[[__c5__::__attr__]] void __f15__(); +[[c5::attrx]] void f15x(); /* { dg-warning "ignored" } */ +[[__c5__::attrx]] void f15x(); /* { dg-warning "ignored" } */ + +[[c6::attr]] void f16(); +[[c6::__attr__]] void f16__(); +[[__c6__::attr]] void __f16(); +[[__c6__::__attr__]] void __f16__(); +[[c6::attrx]] void f16x(); /* { dg-warning "ignored" } */ +[[__c6__::attrx]] void f16x(); /* { dg-warning "ignored" } */ diff --git a/gcc/testsuite/c-c++-common/Wno-attributes-2.c b/gcc/testsuite/c-c++-common/Wno-attributes-2.c new file mode 100644 index 00000000000..4307c74b048 --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wno-attributes-2.c @@ -0,0 +1,56 @@ +/* PR c++/101940 */ +/* { dg-do compile } */ +/* { dg-additional-options "-std=c++11" { target c++ } } */ + +#pragma GCC diagnostic ignored_attributes "company::,yoyodyne::attr" +#pragma GCC diagnostic ignored_attributes "c1::attr,c1::attr,c1::__attr__" +#pragma GCC diagnostic ignored_attributes "c2::,c2::attr" +#pragma GCC diagnostic ignored_attributes "c3::attr,c3::" +#pragma GCC diagnostic ignored_attributes "x::" +#pragma GCC diagnostic ignored_attributes "yoyodyne::attr_new" +#pragma GCC diagnostic ignored_attributes "c4::__attr__" +#pragma GCC diagnostic ignored_attributes "c5::attr" +#pragma GCC diagnostic ignored_attributes "__c6__::attr" + +[[company::attr]] void f1(); +[[company::attr2]] void f2(); + +[[yoyodyne::attr]] void f3(); +[[yoyodyne::__attr__]] void f3__(); +[[yoyodyne::attrx]] void f4(); /* { dg-warning "ignored" } */ +[[yoyodyne::__attrx__]] void f4__(); /* { dg-warning "ignored" } */ + +[[c1::attr]] void f5(); + +[[c2::attr]] void f6(); +[[c2::attrx]] void f7(); +[[c2::__attr__]] void f6__(); +[[c2::__attrx__]] void f7__(); + +[[c3::attr]] void f8(); +[[c3::attrx]] void f9(); + +[[x::x]] void f10(); + +[[yoyodyne::attr_new]] void f11(); +[[yoyodyne::__attr_new__]] void f11__(); +[[yoyodyne::attr_mew]] void f12(); /* { dg-warning "ignored" } */ +[[yoyodyne::__attr_mew__]] void f12__(); /* { dg-warning "ignored" } */ + +[[c4::attr]] void f13(); +[[c4::__attr__]] void f13__(); +[[c4::attrx]] void f14(); /* { dg-warning "ignored" } */ + +[[c5::attr]] void f15(); +[[c5::__attr__]] void f15__(); +[[__c5__::attr]] void __f15(); +[[__c5__::__attr__]] void __f15__(); +[[c5::attrx]] void f15x(); /* { dg-warning "ignored" } */ +[[__c5__::attrx]] void f15x(); /* { dg-warning "ignored" } */ + +[[c6::attr]] void f16(); +[[c6::__attr__]] void f16__(); +[[__c6__::attr]] void __f16(); +[[__c6__::__attr__]] void __f16__(); +[[c6::attrx]] void f16x(); /* { dg-warning "ignored" } */ +[[__c6__::attrx]] void f16x(); /* { dg-warning "ignored" } */ diff --git a/gcc/toplev.c b/gcc/toplev.c index e91f083f8ff..99276bde87d 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -457,6 +457,8 @@ compile_file (void) if (flag_dump_locations) dump_location_info (stderr); + free_attr_data (); + /* Compilation is now finished except for writing what's left of the symbol table output. */