From patchwork Thu Nov 2 13:19:30 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 160878 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:8f47:0:b0:403:3b70:6f57 with SMTP id j7csp348772vqu; Thu, 2 Nov 2023 06:21:29 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFtyW/s3KGDEF9UY/FQUtHvlBPVE1P7NGbN79AvwvS37nBC2PDdj+HmGdKECmtY3vSMnkaf X-Received: by 2002:a05:6870:3d86:b0:1e9:a70c:1323 with SMTP id lm6-20020a0568703d8600b001e9a70c1323mr24635077oab.39.1698931288992; Thu, 02 Nov 2023 06:21:28 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698931288; cv=pass; d=google.com; s=arc-20160816; b=Wh0TxSmv4DLjMklFvudmRAwZiODBNqA+8/0QmK61vQDxJWOW4FS10tK0PdAFXuwldW Od0w3AsxErq0m6Z74mUoFq7+a3d0jVP7o8MEN3GeReI8uA39TfPxqdpFNBsdrO6zceJz 4RoBZ3m+i8B4+gwTWJuolERhQXaFrn6kx53rDI/0nwU4yVwaS9hmFYAnE4GRYo3ZIggx bxc9fFl+iouZFPxbd+pWS0bIkFSm2vSUlRIEuJamtS+bJ604IQMvbVCJnZfNr/ziGKl5 LVEKkPtBROgETp/ObJMj48Miz4mCQuY45mvaICv4n/tb5cMCQ2x0R4WqhkiRA/bcn/HW YXyw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=rlrJ/ve+H/eWw/sqOgKUjy7QQFaTeRwBBoq4gRdJQDk=; fh=NXemEfxTRbZtBxUkxR2ehQUaYlcDfMdzPkO8MChVQE4=; b=N6cr3nDpK18wfYjWqCJXz7AXG8OgKc3CPwWCGB9pU2KCnIZAkBoAOqu4wyrQOg9yUz ROJfFVb5/yBdqJ2doqlQTCXOSsqctMdbCpmJG7IruKq6OL3yYk2G5WPb9KQ7JuZEJgJx Bf6nnkRnYBCYnVpd7cAilp/Eon492T7YyfBvlwYqGkgwCgW5dO6fYChmKKchE0q5tXna aT3QB2XRJs8mD+577LIknOV8iAD/26ilUTv31MfUIvduU7v+ZlTGHvd+LD3ag6iQyWEf Y3P9v5QAVmnY9YT5QYB3ybRE5UCoA4EK1oGptyoieRrb0yrQLbMJAQucWbahiFHqfadG TMHg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=dKv0yDtP; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id c21-20020a05622a025500b00410a9ddbcf7si4205849qtx.163.2023.11.02.06.21.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Nov 2023 06:21:28 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=dKv0yDtP; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B8B36385DC18 for ; Thu, 2 Nov 2023 13:21:28 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTPS id E296B3858C41 for ; Thu, 2 Nov 2023 13:19:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E296B3858C41 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org E296B3858C41 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698931190; cv=none; b=SkgiKAMQTAwYlAd5kdxcK+o53FJpsNYqWJDWmg1Aga0egOh2NeINTwYOui6zO57tkbBrFxm+KwhN4bGPRkb7WR43rhCiQaAYrPeeZggsnlfUOEgdhMcfjIvHdE4dsaUXvxwoIkA2o4tQwB55Vns6jL6jZq7U/gzcaCfPphxuBdk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1698931190; c=relaxed/simple; bh=JytmiPVWL5mnCJusJq6TEDcJgfnwYdmBdvejTzO+SWE=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=SLj78WYROuKF5dSD0pcY9cAyBh3dVvfdK0MVQCnBBfVwbrLSSnrGxuCD68R7Pm5z5vWzlNOvQIG/Xcw+jcKGc4ryCOK+lgmJ6bJPHQWOiRJW3HQ6iQnrSXIzbGNfQ/8pDnrSDYQnsec4uotQF/tONLsEsifTEtdlaX49WwU97FE= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1698931180; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rlrJ/ve+H/eWw/sqOgKUjy7QQFaTeRwBBoq4gRdJQDk=; b=dKv0yDtPvc2hZDaoRmTBoZD6vlR30zVqwdnTXsn/D3wyK0cITjiDH6wXisrHb8JjRf7nZ7 vm5UPBWrXvdQ1w+2mUEYRJaLqVp5Qdhe6zVBKr51pC85MXwhM4UvL21/QKEsGgeyS0moYr LCulYkRDceCWgbfhCEV/8Htpc58cW1s= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-85-tbRo6pjcMM65XIwwZgu_Pw-1; Thu, 02 Nov 2023 09:19:37 -0400 X-MC-Unique: tbRo6pjcMM65XIwwZgu_Pw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BFF83185A784 for ; Thu, 2 Nov 2023 13:19:36 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.22.8.62]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8B2BC1C060BA; Thu, 2 Nov 2023 13:19:36 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [PATCH 1/4] c/c++: rework pragma parsing Date: Thu, 2 Nov 2023 09:19:30 -0400 Message-Id: <20231102131933.2161191-2-dmalcolm@redhat.com> In-Reply-To: <20231102131933.2161191-1-dmalcolm@redhat.com> References: <20231102131933.2161191-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781458575160244925 X-GMAIL-MSGID: 1781458575160244925 This patch reworks pragma parsing in c-pragma.cc, with the following improvements: - it replaces the GCC_BAD* macros (that contained "return") in favor of helper classes and functions for emitting diagnostics, making control flow more explicit - the -Wpragmas diagnostics are reworded from the form e.g.: DESCRIPTION OF PROBLEM; ignored to: ignoring malformed '#pragma FOO': DESCRIPTION OF PROBLEM - the locations of the warnings are fixed to more accurately reflect the location of the problem - the names of the pragmas are URLified into links to the documentation for the pragma. For example, in: warning: ignoring malformed '#pragma weak': expected name [-Wpragmas] in a suitable terminal, the "#pragma weak" within quotes is a link to https://gcc.gnu.org/onlinedocs/gcc/Weak-Pragmas.html; similarly with warning: '#pragma pack' has no effect with '-fpack-struct' - ignored [-Wpragmas] the "#pragma pack" text is linkified to https://gcc.gnu.org/onlinedocs/gcc/Structure-Layout-Pragmas.html and the "-fpack-struct" text is linkified to: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fpack-struct I have a more general and maintainable approach to adding URLs to diagnostics which is in a followup. gcc/c-family/ChangeLog: * c-pragma.cc (GCC_BAD): Delete. (GCC_BAD2): Delete. (GCC_BAD_AT): Delete. (GCC_BAD2_AT): Delete. (get_doc_url): New. (class pragma_parser): New. (handle_pragma_pack): Delete redundant forward decl. (pop_alignment): Add param "p" and use it to get doc urls. (enum class pack_action): Move here from within handle_pragma_pack. (class pragma_pack_parser): New. (handle_pragma_pack): Rewrite using pragma_pack_parser and enum class pack_action, eliminating uses of GCC_BAD*, rewording diagnostics. (handle_pragma_weak): Rewrite using pragma_parser, eliminating uses of GCC_BAD*, rewording diagnostics. (class pragma_scalar_storage_order_parser): New. (handle_pragma_scalar_storage_order): Rewrite using above, eliminating uses of GCC_BAD*, rewording diagnostics. (handle_pragma_redefine_extname): Rewrite using pragma_parser, eliminating uses of GCC_BAD*, rewording diagnostics. Fix overlong line. (handle_pragma_visibility): Remove redundant forward decl. (push_visibility): Add "const pragma_parser *" param. Rewrite to eliminate uses of GCC_BAD*. Add note that warning was ignored. (handle_pragma_visibility): Rewrite using pragma_parser, eliminating uses of GCC_BAD*, rewording diagnostics. (handle_pragma_target): Fix name of pragma in "error". Eliminate uses of GCC_BAD*. (handle_pragma_optimize): Eliminate uses of GCC_BAD. (handle_pragma_message): Rewrite using pragma_parser, eliminating uses of GCC_BAD*, rewording diagnostics. * c-pragma.h (class pragma_parser): New forward decl. (push_visibility): Add optional "const pragma_parser *" param. gcc/testsuite/ChangeLog: * c-c++-common/pragma-message-parsing.c: New test. * c-c++-common/pragma-optimize-parsing.c: New test. * c-c++-common/pragma-pack-parsing-1.c: New test. * c-c++-common/pragma-pack-parsing-2.c: New test. * c-c++-common/pragma-redefine_extname-parsing.c: New test. * c-c++-common/pragma-target-parsing.c: New test. * c-c++-common/pragma-visibility-parsing.c: New test. * c-c++-common/pragma-weak-parsing.c: New test. * gcc.dg/bad-pragma-locations.c: Update for changes to wording and location of -Wpragmas. * gcc.dg/pragma-scalar_storate_order-parsing.c: New test. * gcc.dg/sso-6.c: Update for changes to wording of -Wpragmas. --- gcc/c-family/c-pragma.cc | 569 ++++++++++++++---- gcc/c-family/c-pragma.h | 5 +- .../c-c++-common/pragma-message-parsing.c | 21 + .../c-c++-common/pragma-optimize-parsing.c | 16 + .../c-c++-common/pragma-pack-parsing-1.c | 19 + .../c-c++-common/pragma-pack-parsing-2.c | 4 + .../pragma-redefine_extname-parsing.c | 9 + .../c-c++-common/pragma-target-parsing.c | 14 + .../c-c++-common/pragma-visibility-parsing.c | 13 + .../c-c++-common/pragma-weak-parsing.c | 24 + gcc/testsuite/gcc.dg/bad-pragma-locations.c | 22 +- .../pragma-scalar_storate_order-parsing.c | 8 + gcc/testsuite/gcc.dg/sso-6.c | 2 +- 13 files changed, 588 insertions(+), 138 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pragma-message-parsing.c create mode 100644 gcc/testsuite/c-c++-common/pragma-optimize-parsing.c create mode 100644 gcc/testsuite/c-c++-common/pragma-pack-parsing-1.c create mode 100644 gcc/testsuite/c-c++-common/pragma-pack-parsing-2.c create mode 100644 gcc/testsuite/c-c++-common/pragma-redefine_extname-parsing.c create mode 100644 gcc/testsuite/c-c++-common/pragma-target-parsing.c create mode 100644 gcc/testsuite/c-c++-common/pragma-visibility-parsing.c create mode 100644 gcc/testsuite/c-c++-common/pragma-weak-parsing.c create mode 100644 gcc/testsuite/gcc.dg/pragma-scalar_storate_order-parsing.c diff --git a/gcc/c-family/c-pragma.cc b/gcc/c-family/c-pragma.cc index df3e3e6b3b0..6df8683af77 100644 --- a/gcc/c-family/c-pragma.cc +++ b/gcc/c-family/c-pragma.cc @@ -35,14 +35,161 @@ along with GCC; see the file COPYING3. If not see #include "plugin.h" #include "opt-suggestions.h" -#define GCC_BAD(gmsgid) \ - do { warning (OPT_Wpragmas, gmsgid); return; } while (0) -#define GCC_BAD2(gmsgid, arg) \ - do { warning (OPT_Wpragmas, gmsgid, arg); return; } while (0) -#define GCC_BAD_AT(loc, gmsgid) \ - do { warning_at (loc, OPT_Wpragmas, gmsgid); return; } while (0) -#define GCC_BAD2_AT(loc, gmsgid, arg) \ - do { warning_at (loc, OPT_Wpragmas, gmsgid, arg); return; } while (0) +label_text +get_doc_url (const char *doc_url_suffix) +{ + if (!doc_url_suffix) + return label_text (); + return label_text::take (concat (DOCUMENTATION_ROOT_URL, + doc_url_suffix, + nullptr)); +} + +/* A class for implementing parsing within pragma-handling callbacks. + Provides various wrappers around pragma_lex. */ + +class pragma_parser +{ +public: + pragma_parser (const char *space, const char *name, + const char *doc_url_suffix) + : m_start_loc (input_location), + m_space (space), + m_name (name), + m_doc_url_suffix (doc_url_suffix), + m_last_loc (m_start_loc) + { + // SPACE can be null. + gcc_assert (name); + // DOC_URL_SUFFIX can be null + } + + location_t + get_last_location () const + { + return m_last_loc; + } + + bool + require_token (enum cpp_ttype required_ttype, const char *desc) + { + tree x = NULL_TREE; + + enum cpp_ttype ttype = pragma_lex (&x, &m_last_loc); + if (ttype != required_ttype) + { + label_text doc_url (get_doc_url ()); + if (m_space) + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s %s%}%>:" + " expected %qs", + doc_url.get (), m_space, m_name, + desc); + else + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s%}%>:" + " expected %qs", + doc_url.get (), m_name, + desc); + return false; + } + return true; + } + + bool + require_open_paren () + { + return require_token (CPP_OPEN_PAREN, "("); + } + + bool + require_close_paren () + { + return require_token (CPP_CLOSE_PAREN, ")"); + } + + tree require_name () + { + tree x = NULL_TREE; + + enum cpp_ttype ttype = pragma_lex (&x, &m_last_loc); + if (ttype != CPP_NAME) + { + label_text doc_url (get_doc_url ()); + if (m_space) + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s %s%}%>:" + "expected name", + doc_url.get (), m_space, m_name); + else + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s%}%>:" + " expected name", + doc_url.get (), m_name); + return NULL_TREE; + } + + return x; + } + + tree require_symbol_name () + { + tree x = NULL_TREE; + + enum cpp_ttype ttype = pragma_lex (&x, &m_last_loc); + if (ttype != CPP_NAME) + { + label_text doc_url (get_doc_url ()); + if (m_space) + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s %s%}%>:" + " expected symbol name", + doc_url.get (), m_space, m_name); + else + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma %s%}%>:" + " expected symbol name", + doc_url.get (), m_name); + return NULL_TREE; + } + + return x; + } + + void + check_for_trailing_junk () + { + tree x = NULL_TREE; + enum cpp_ttype t = pragma_lex (&x, &m_last_loc); + warn_about_any_trailing_junk (t, m_last_loc); + } + + void + warn_about_any_trailing_junk (enum cpp_ttype t, location_t loc) const + { + if (t == CPP_EOF) + return; + label_text doc_url (get_doc_url ()); + if (m_space) + warning_at (loc, OPT_Wpragmas, "junk at end of %<%{#pragma %s %s%}%>", + doc_url.get (), m_space, m_name); + else + warning_at (loc, OPT_Wpragmas, "junk at end of %<%{#pragma %s%}%>", + doc_url.get (), m_name); + } + + label_text + get_doc_url () const + { + return ::get_doc_url (m_doc_url_suffix); + } + + const location_t m_start_loc; + const char *const m_space; + const char *const m_name; + const char *m_doc_url_suffix; + location_t m_last_loc; +}; struct GTY(()) align_stack { int alignment; @@ -52,8 +199,6 @@ struct GTY(()) align_stack { static GTY(()) struct align_stack * alignment_stack; -static void handle_pragma_pack (cpp_reader *); - /* If we have a "global" #pragma pack() in effect when the first #pragma pack(push,) is encountered, this stores the value of maximum_field_alignment in effect. When the final pop_alignment() @@ -65,7 +210,7 @@ static int default_alignment; : &alignment_stack->alignment) = (ALIGN)) static void push_alignment (int, tree); -static void pop_alignment (tree); +static void pop_alignment (tree, const pragma_parser &p); /* Push an alignment value onto the stack. */ static void @@ -90,13 +235,19 @@ push_alignment (int alignment, tree id) /* Undo a push of an alignment onto the stack. */ static void -pop_alignment (tree id) +pop_alignment (tree id, const pragma_parser &p) { align_stack * entry; if (alignment_stack == NULL) - GCC_BAD ("%<#pragma pack (pop)%> encountered without matching " - "%<#pragma pack (push)%>"); + { + label_text doc_url (p.get_doc_url ()); + warning (OPT_Wpragmas, + "%<%{#pragma pack (pop)%}%> encountered without matching " + "%<%{#pragma pack (push)%}%>", + doc_url.get (), doc_url.get ()); + return; + } /* If we got an identifier, strip away everything above the target entry so that the next step will restore the state just below it. */ @@ -109,10 +260,12 @@ pop_alignment (tree id) break; } if (entry == NULL) - warning (OPT_Wpragmas, - "%<#pragma pack(pop, %E)%> encountered without matching " - "%<#pragma pack(push, %E)%>" - , id, id); + { + warning (OPT_Wpragmas, + "%<#pragma pack(pop, %E)%> encountered without matching " + "%<#pragma pack(push, %E)%>", + id, id); + } } entry = alignment_stack->prev; @@ -122,6 +275,41 @@ pop_alignment (tree id) alignment_stack = entry; } +enum class pack_action { set, push, pop }; + +class pragma_pack_parser : public pragma_parser +{ +public: + pragma_pack_parser () + : pragma_parser (nullptr, "pack", "gcc/Structure-Layout-Pragmas.html") + { + } + + bool require_integer (tree x, location_t loc) const + { + if (TREE_CODE (x) == INTEGER_CST) + return true; + + label_text doc_url (get_doc_url ()); + warning_at (loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma pack%}%>:" + " invalid constant", + doc_url.get ()); + return false; + } + + void complain_about_malformed_action (pack_action action) const + { + label_text doc_url (get_doc_url ()); + if (action != pack_action::pop) + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<#pragma pack(push[, id][, ])%>"); + else + warning_at (m_last_loc, OPT_Wpragmas, + "ignoring malformed %<#pragma pack(pop[, id])%>"); + } +}; + /* #pragma pack () #pragma pack (N) @@ -134,46 +322,50 @@ pop_alignment (tree id) static void handle_pragma_pack (cpp_reader *) { + pragma_pack_parser p; + location_t loc; tree x, id = 0; int align = -1; + location_t align_loc = input_location; enum cpp_ttype token; - enum { set, push, pop } action; + enum pack_action action; - if (pragma_lex (&x) != CPP_OPEN_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma pack%> - ignored"); + if (!p.require_open_paren ()) + return; token = pragma_lex (&x, &loc); if (token == CPP_CLOSE_PAREN) { - action = set; + action = pack_action::set; align = initial_max_fld_align; } else if (token == CPP_NUMBER) { - if (TREE_CODE (x) != INTEGER_CST) - GCC_BAD_AT (loc, "invalid constant in %<#pragma pack%> - ignored"); + if (!p.require_integer (x, loc)) + return; align = TREE_INT_CST_LOW (x); - action = set; - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("malformed %<#pragma pack%> - ignored"); + align_loc = loc; + action = pack_action::set; + if (!p.require_close_paren ()) + return; } else if (token == CPP_NAME) { -#define GCC_BAD_ACTION do { if (action != pop) \ - GCC_BAD ("malformed %<#pragma pack(push[, id][, ])%> - ignored"); \ - else \ - GCC_BAD ("malformed %<#pragma pack(pop[, id])%> - ignored"); \ - } while (0) - const char *op = IDENTIFIER_POINTER (x); if (!strcmp (op, "push")) - action = push; + action = pack_action::push; else if (!strcmp (op, "pop")) - action = pop; + action = pack_action::pop; else - GCC_BAD2_AT (loc, "unknown action %qE for %<#pragma pack%> - ignored", - x); + { + label_text doc_url (p.get_doc_url ()); + warning_at (loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma pack%}%>:" + " unknown action %qE", + doc_url.get (), x); + return; + } while ((token = pragma_lex (&x)) == CPP_COMMA) { @@ -182,33 +374,56 @@ handle_pragma_pack (cpp_reader *) { id = x; } - else if (token == CPP_NUMBER && action == push && align == -1) + else if (token == CPP_NUMBER + && action == pack_action::push + && align == -1) { - if (TREE_CODE (x) != INTEGER_CST) - GCC_BAD_AT (loc, - "invalid constant in %<#pragma pack%> - ignored"); + if (!p.require_integer (x, loc)) + return; align = TREE_INT_CST_LOW (x); + align_loc = loc; if (align == -1) - action = set; + action = pack_action::set; } else - GCC_BAD_ACTION; + { + p.complain_about_malformed_action (action); + return; + } } if (token != CPP_CLOSE_PAREN) - GCC_BAD_ACTION; -#undef GCC_BAD_ACTION + { + p.complain_about_malformed_action (action); + return; + } } else - GCC_BAD ("malformed %<#pragma pack%> - ignored"); + { + label_text doc_url (p.get_doc_url ()); + warning_at (loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma pack%}%>:" + " expected %<)%>, integer, %, or %", + doc_url.get ()); + return; + } if (pragma_lex (&x, &loc) != CPP_EOF) warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma pack%>"); if (flag_pack_struct) - GCC_BAD ("%<#pragma pack%> has no effect with %<-fpack-struct%> - ignored"); + { + label_text pragma_doc_url (p.get_doc_url ()); + label_text option_doc_url + (get_doc_url ("gcc/Code-Gen-Options.html#index-fpack-struct")); + warning (OPT_Wpragmas, + "%<%{#pragma pack%}%> has no effect with %<%{-fpack-struct%}%>" + " - ignored", + pragma_doc_url.get (), option_doc_url.get ()); + return; + } - if (action != pop) + if (action != pack_action::pop) switch (align) { case 0: @@ -220,21 +435,28 @@ handle_pragma_pack (cpp_reader *) align *= BITS_PER_UNIT; break; case -1: - if (action == push) + if (action == pack_action::push) { align = maximum_field_alignment; break; } /* FALLTHRU */ default: - GCC_BAD2 ("alignment must be a small power of two, not %d", align); + { + label_text doc_url (p.get_doc_url ()); + warning_at (align_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma pack%}%>:" + " alignment must be a small power of two, not %d", + doc_url.get (), align); + return; + } } switch (action) { - case set: SET_GLOBAL_ALIGNMENT (align); break; - case push: push_alignment (align, id); break; - case pop: pop_alignment (id); break; + case pack_action::set: SET_GLOBAL_ALIGNMENT (align); break; + case pack_action::push: push_alignment (align, id); break; + case pack_action::pop: pop_alignment (id, p); break; } } @@ -357,29 +579,46 @@ maybe_apply_pending_pragma_weaks (void) static void handle_pragma_weak (cpp_reader *) { - tree name, value, x, decl; + pragma_parser p (nullptr, "weak", "gcc/Weak-Pragmas.html"); + + tree x, decl; enum cpp_ttype t; + location_t loc; + location_t name_loc; - value = 0; + tree name = p.require_name (); + if (!name) + return; + name_loc = p.get_last_location (); - if (pragma_lex (&name) != CPP_NAME) - GCC_BAD ("malformed %<#pragma weak%>, ignored"); - t = pragma_lex (&x); + tree value = NULL_TREE; + t = pragma_lex (&x, &loc); if (t == CPP_EQ) { - if (pragma_lex (&value) != CPP_NAME) - GCC_BAD ("malformed %<#pragma weak%>, ignored"); - t = pragma_lex (&x); + value = p.require_name (); + if (!value) + return; + t = pragma_lex (&x, &loc); } - if (t != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma weak%>"); + p.warn_about_any_trailing_junk (t, loc); decl = identifier_global_value (name); if (decl && DECL_P (decl)) { if (!VAR_OR_FUNCTION_DECL_P (decl)) - GCC_BAD2 ("%<#pragma weak%> declaration of %q+D not allowed," - " ignored", decl); + { + auto_diagnostic_group d; + label_text doc_url (p.get_doc_url ()); + if (warning_at (name_loc, OPT_Wpragmas, + "%<%{#pragma weak%}%> declaration of %qD not allowed," + " ignored", + doc_url.get (), decl)) + if (DECL_SOURCE_LOCATION (decl) != UNKNOWN_LOCATION) + inform (DECL_SOURCE_LOCATION (decl), + "%qD is not a variable or function", + decl); + return; + } apply_pragma_weak (decl, value); if (value) { @@ -417,12 +656,29 @@ maybe_apply_pragma_scalar_storage_order (tree type) gcc_unreachable (); } +class pragma_scalar_storage_order_parser : public pragma_parser +{ +public: + pragma_scalar_storage_order_parser () + : pragma_parser (nullptr, "scalar_storage_order", + "gcc/Structure-Layout-Pragmas.html") + { + } + + void complain_about_arg (location_t arg_loc) const + { + label_text doc_url (get_doc_url ()); + warning_at (arg_loc, OPT_Wpragmas, + "ignoring malformed %<%{#pragma scalar_storage_order%}%>:" + " expected %, %, or %", + doc_url.get ()); + } +}; + static void handle_pragma_scalar_storage_order (cpp_reader *) { - const char *kind_string; - enum cpp_ttype token; - tree x; + pragma_scalar_storage_order_parser p; if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) { @@ -439,11 +695,15 @@ handle_pragma_scalar_storage_order (cpp_reader *) return; } - token = pragma_lex (&x); + tree x; + location_t arg_loc; + enum cpp_ttype token = pragma_lex (&x, &arg_loc); if (token != CPP_NAME) - GCC_BAD ("missing %, %, or % after " - "%<#pragma scalar_storage_order%>"); - kind_string = IDENTIFIER_POINTER (x); + { + p.complain_about_arg (arg_loc); + return; + } + const char *kind_string = IDENTIFIER_POINTER (x); if (strcmp (kind_string, "default") == 0) global_sso = default_sso; else if (strcmp (kind_string, "big") == 0) @@ -451,8 +711,7 @@ handle_pragma_scalar_storage_order (cpp_reader *) else if (strcmp (kind_string, "little") == 0) global_sso = SSO_LITTLE_ENDIAN; else - GCC_BAD ("expected %, %, or % after " - "%<#pragma scalar_storage_order%>"); + p.complain_about_arg (arg_loc); } /* GCC supports two #pragma directives for renaming the external @@ -501,20 +760,19 @@ static void handle_pragma_redefine_extname (cpp_reader *); static void handle_pragma_redefine_extname (cpp_reader *) { - tree oldname, newname, decls, x; - enum cpp_ttype t; - bool found; - - if (pragma_lex (&oldname) != CPP_NAME) - GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored"); - if (pragma_lex (&newname) != CPP_NAME) - GCC_BAD ("malformed %<#pragma redefine_extname%>, ignored"); - t = pragma_lex (&x); - if (t != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); - - found = false; - for (decls = c_linkage_bindings (oldname); + pragma_parser p (nullptr, "redefine_extname", + "gcc/Symbol-Renaming-Pragmas.html"); + + tree oldname = p.require_symbol_name (); + if (!oldname) + return; + tree newname = p.require_symbol_name (); + if (!newname) + return; + p.check_for_trailing_junk (); + + bool found = false; + for (tree decls = c_linkage_bindings (oldname); decls; ) { tree decl; @@ -535,7 +793,8 @@ handle_pragma_redefine_extname (cpp_reader *) found = true; if (DECL_ASSEMBLER_NAME_SET_P (decl)) { - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + const char *name + = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); name = targetm.strip_name_encoding (name); if (!id_equal (newname, name)) @@ -671,8 +930,6 @@ maybe_apply_renaming_pragma (tree decl, tree asmname) } -static void handle_pragma_visibility (cpp_reader *); - static vec visstack; /* Push the visibility indicated by STR onto the top of the #pragma @@ -683,7 +940,7 @@ static vec visstack; KIND and pop using a different one. */ void -push_visibility (const char *str, int kind) +push_visibility (const char *str, int kind, const pragma_parser *p) { visstack.safe_push (((int) default_visibility) | (kind << 8)); if (!strcmp (str, "default")) @@ -695,8 +952,23 @@ push_visibility (const char *str, int kind) else if (!strcmp (str, "protected")) default_visibility = VISIBILITY_PROTECTED; else - GCC_BAD ("%<#pragma GCC visibility push()%> must specify %, " - "%, % or %"); + { + auto_diagnostic_group d; + location_t loc = p ? p->get_last_location () : input_location; + if (warning_at (loc, + OPT_Wpragmas, + "%<#pragma GCC visibility push()%> must specify" + " %, %, %" + " or %")) + if (p) + { + label_text doc_url (p->get_doc_url ()); + inform (loc, + "ignoring malformed %<%{#pragma GCC visibility%}%>", + doc_url.get ()); + } + return; + } visibility_options.inpragma = 1; } @@ -723,6 +995,8 @@ pop_visibility (int kind) static void handle_pragma_visibility (cpp_reader *) { + pragma_parser p ("GCC", "visibility", "gcc/Visibility-Pragmas.html"); + /* Form is #pragma GCC visibility push(hidden)|pop */ tree x; enum cpp_ttype token; @@ -738,30 +1012,41 @@ handle_pragma_visibility (cpp_reader *) action = pop; } if (bad == action) - GCC_BAD ("%<#pragma GCC visibility%> must be followed by % " - "or %"); + { + label_text doc_url (p.get_doc_url ()); + warning (OPT_Wpragmas, + "%<%{#pragma GCC visibility%}%> must be followed by % " + "or %", + doc_url.get ()); + return; + } else { if (pop == action) { if (! pop_visibility (0)) - GCC_BAD ("no matching push for %<#pragma GCC visibility pop%>"); + { + label_text doc_url (p.get_doc_url ()); + warning (OPT_Wpragmas, + "no matching push for" + " %<%{#pragma GCC visibility pop%}%>", + doc_url.get ()); + return; + } } else { - if (pragma_lex (&x) != CPP_OPEN_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); - token = pragma_lex (&x); - if (token != CPP_NAME) - GCC_BAD ("malformed %<#pragma GCC visibility push%>"); - else - push_visibility (IDENTIFIER_POINTER (x), 0); - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("missing %<(%> after %<#pragma GCC visibility push%> - ignored"); + if (!p.require_open_paren ()) + return; + x = p.require_name (); + if (!x) + return; + push_visibility (IDENTIFIER_POINTER (x), 0, &p); + if (!p.require_close_paren ()) + return; } } - if (pragma_lex (&x) != CPP_EOF) - warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>"); + p.check_for_trailing_junk (); } /* Helper routines for parsing #pragma GCC diagnostic. */ @@ -1051,7 +1336,7 @@ handle_pragma_target(cpp_reader *) if (cfun) { - error ("%<#pragma GCC option%> is not allowed inside functions"); + error ("%<#pragma GCC target option%> is not allowed inside functions"); return; } @@ -1063,7 +1348,12 @@ handle_pragma_target(cpp_reader *) } if (token != CPP_STRING) - GCC_BAD_AT (loc, "%<#pragma GCC option%> is not a string"); + { + warning_at (loc, OPT_Wpragmas, + "ignoring malformed %<#pragma GCC target%>:" + " expected a string option"); + return; + } /* Strings are user options. */ else @@ -1088,8 +1378,12 @@ handle_pragma_target(cpp_reader *) if (token == CPP_CLOSE_PAREN) token = pragma_lex (&x); else - GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does " - "not have a final %<)%>"); + { + warning (OPT_Wpragmas, + "%<#pragma GCC target (string [,string]...)%> does " + "not have a final %<)%>"); + return; + } } if (token != CPP_EOF) @@ -1135,7 +1429,11 @@ handle_pragma_optimize (cpp_reader *) } if (token != CPP_STRING && token != CPP_NUMBER) - GCC_BAD ("%<#pragma GCC optimize%> is not a string or number"); + { + warning (OPT_Wpragmas, + "%<#pragma GCC optimize%> is not a string or number"); + return; + } /* Strings/numbers are user options. */ else @@ -1159,8 +1457,12 @@ handle_pragma_optimize (cpp_reader *) if (token == CPP_CLOSE_PAREN) token = pragma_lex (&x); else - GCC_BAD ("%<#pragma GCC optimize (string [,string]...)%> does " - "not have a final %<)%>"); + { + warning (OPT_Wpragmas, + "%<#pragma GCC optimize (string [,string]...)%> does " + "not have a final %<)%>"); + return; + } } if (token != CPP_EOF) @@ -1336,33 +1638,50 @@ handle_pragma_reset_options (cpp_reader *) static void handle_pragma_message (cpp_reader *) { + pragma_parser p (nullptr, "message", "gcc/Diagnostic-Pragmas.html"); + location_t loc; enum cpp_ttype token; tree x, message = 0; - token = pragma_lex (&x); + token = pragma_lex (&x, &loc); if (token == CPP_OPEN_PAREN) { - token = pragma_lex (&x); + token = pragma_lex (&x, &loc); if (token == CPP_STRING) message = x; else - GCC_BAD ("expected a string after %<#pragma message%>"); - if (pragma_lex (&x) != CPP_CLOSE_PAREN) - GCC_BAD ("malformed %<#pragma message%>, ignored"); + { + label_text doc_url (p.get_doc_url ()); + warning_at (loc, OPT_Wpragmas, + "expected a string after %<%{#pragma message%}%>", + doc_url.get ()); + return; + } + if (!p.require_close_paren ()) + return; } else if (token == CPP_STRING) message = x; else if (token == CPP_STRING_USERDEF) - GCC_BAD ("string literal with user-defined suffix is invalid in this " - "context"); + { + warning_at (loc, OPT_Wpragmas, + "string literal with user-defined suffix is invalid in this " + "context"); + return; + } else - GCC_BAD ("expected a string after %<#pragma message%>"); + { + label_text doc_url (p.get_doc_url ()); + warning_at (loc, OPT_Wpragmas, + "expected a string after %<%{#pragma message%}%>", + doc_url.get ()); + return; + } gcc_assert (message); - if (pragma_lex (&x, &loc) != CPP_EOF) - warning_at (loc, OPT_Wpragmas, "junk at end of %<#pragma message%>"); + p.check_for_trailing_junk (); if (TREE_STRING_LENGTH (message) > 1) inform (input_location, "%<#pragma message: %s%>", diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h index 682157a4517..abaf897d84d 100644 --- a/gcc/c-family/c-pragma.h +++ b/gcc/c-family/c-pragma.h @@ -203,10 +203,13 @@ enum pragma_omp_clause { extern struct cpp_reader* parse_in; +class pragma_parser; + /* It's safe to always leave visibility pragma enabled as if visibility is not supported on the host OS platform the statements are ignored. */ -extern void push_visibility (const char *, int); +extern void push_visibility (const char *, int, + const pragma_parser *p = nullptr); extern bool pop_visibility (int); extern void init_pragma (void); diff --git a/gcc/testsuite/c-c++-common/pragma-message-parsing.c b/gcc/testsuite/c-c++-common/pragma-message-parsing.c new file mode 100644 index 00000000000..4acb9d16c51 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-message-parsing.c @@ -0,0 +1,21 @@ +/* Test that we provide good warnings for malformed '#pragma message'. */ + +#pragma message /* { dg-line no_arg } */ +/* { dg-warning "expected a string after '#pragma message'" "" { target *-*-* } no_arg } */ + +#pragma message 1066 /* { dg-line bad_arg } */ +/* { dg-warning "17: expected a string after '#pragma message'" "" { target *-*-* } bad_arg } */ + +#pragma message "foo" /* { dg-message "#pragma message: foo" } */ + +#pragma message(1066) /* { dg-line parens_bad_arg } */ +/* { dg-warning "17: expected a string after '#pragma message'" "" { target *-*-* } parens_bad_arg } */ + +#pragma message("bar") /* { dg-message "#pragma message: bar" } */ + +#pragma message("foo") bar /* { dg-warning "24: junk at end of '#pragma message'" } */ + +#if defined(__cplusplus) && __cplusplus >= 201103L +unsigned operator ""_w(const char*); +#pragma message "foo"_w /* { dg-message "17: string literal with user-defined suffix is invalid in this context" "" { target { c++11 } } } */ +#endif diff --git a/gcc/testsuite/c-c++-common/pragma-optimize-parsing.c b/gcc/testsuite/c-c++-common/pragma-optimize-parsing.c new file mode 100644 index 00000000000..4808ce3992a --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-optimize-parsing.c @@ -0,0 +1,16 @@ +/* Test that we provide good warnings for malformed '#pragma GCC optimize'. */ + +#pragma GCC optimize /* { dg-warning "'#pragma GCC optimize' is not a string or number" } */ +#pragma GCC optimize 3 +#pragma GCC optimize( /* { dg-warning "'#pragma GCC optimize' is not a string or number" } */ +#pragma GCC optimize() /* { dg-warning "'#pragma GCC optimize' is not a string or number" } */ +#pragma GCC optimize(3, ) +#pragma GCC optimize("-O3", ) +#pragma GCC optimize(3, /* { dg-warning "'#pragma GCC optimize \\(string \\\[,string\\\]...\\)' does not have a final '\\)'" } */ + +void foo () +{ +#pragma GCC optimize /* { dg-error "#pragma GCC optimize' is not allowed inside functions" } */ +} + +#pragma GCC optimize("-Ofan-noise", ) /* { dg-error "argument to '-O' should be a non-negative integer, 'g', 's', 'z' or 'fast'" } */ diff --git a/gcc/testsuite/c-c++-common/pragma-pack-parsing-1.c b/gcc/testsuite/c-c++-common/pragma-pack-parsing-1.c new file mode 100644 index 00000000000..0e3d806388a --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-pack-parsing-1.c @@ -0,0 +1,19 @@ +/* Test that we provide good warnings for malformed '#pragma pack'. */ + +#pragma pack /* { dg-warning "ignoring malformed '#pragma pack': expected '\\('" } */ + +#pragma pack 42 /* { dg-warning "14: ignoring malformed '#pragma pack': expected '\\('" } */ + +#pragma pack(3.141) /* { dg-warning "14: ignoring malformed '#pragma pack': invalid constant" } */ + +#pragma pack(( /* { dg-warning "14: ignoring malformed '#pragma pack': expected '\\)', integer, 'push', or 'pop'" } */ + +#pragma pack(42 /* { dg-warning "ignoring malformed '#pragma pack': expected '\\)'" } */ + +#pragma pack(42) /* { dg-warning "14: ignoring malformed '#pragma pack': alignment must be a small power of two, not 42" } */ + +#pragma pack(foo /* { dg-warning "14: ignoring malformed '#pragma pack': unknown action 'foo'" } */ + +#pragma pack(push, 3.141 /* { dg-warning "20: ignoring malformed '#pragma pack': invalid constant" } */ + +#pragma pack(push, 42) /* { dg-warning "20: ignoring malformed '#pragma pack': alignment must be a small power of two, not 42" } */ diff --git a/gcc/testsuite/c-c++-common/pragma-pack-parsing-2.c b/gcc/testsuite/c-c++-common/pragma-pack-parsing-2.c new file mode 100644 index 00000000000..efca44e8734 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-pack-parsing-2.c @@ -0,0 +1,4 @@ +/* Test that we provide good warnings for malformed '#pragma pack'. */ +/* { dg-options "-fpack-struct" } */ + +#pragma pack(16) /* { dg-warning "'#pragma pack' has no effect with '-fpack-struct' - ignored" } */ diff --git a/gcc/testsuite/c-c++-common/pragma-redefine_extname-parsing.c b/gcc/testsuite/c-c++-common/pragma-redefine_extname-parsing.c new file mode 100644 index 00000000000..19f4f1b766e --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-redefine_extname-parsing.c @@ -0,0 +1,9 @@ +/* Test that we provide good warnings for malformed '#pragma redefine_extname'. */ + +/* Missing old name. */ +#pragma redefine_extname /* { dg-warning "ignoring malformed '#pragma redefine_extname': expected symbol name" } */ +#pragma redefine_extname 42 /* { dg-warning "26: ignoring malformed '#pragma redefine_extname': expected symbol name" } */ + +/* Missing new name. */ +#pragma redefine_extname foo /* { dg-warning "ignoring malformed '#pragma redefine_extname': expected symbol name" } */ +#pragma redefine_extname foo 42 /* { dg-warning "30: ignoring malformed '#pragma redefine_extname': expected symbol name" } */ diff --git a/gcc/testsuite/c-c++-common/pragma-target-parsing.c b/gcc/testsuite/c-c++-common/pragma-target-parsing.c new file mode 100644 index 00000000000..37e331626e9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-target-parsing.c @@ -0,0 +1,14 @@ +/* Test that we provide good warnings for malformed '#pragma target'. */ + +#pragma GCC target /* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" } */ +#pragma GCC target 1066 /* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" } */ +#pragma GCC target( /* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" } */ +#pragma GCC target() /* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" } */ +#pragma GCC target("", ) +#pragma GCC target("", /* { dg-warning "'#pragma GCC target \\(string \\\[,string\\\]...\\)' does not have a final '\\)'" } */ + +void foo () +{ +#pragma GCC target /* { dg-error "#pragma GCC target option' is not allowed inside functions" } */ + /* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" "" { target c++ } .-1 } */ +} diff --git a/gcc/testsuite/c-c++-common/pragma-visibility-parsing.c b/gcc/testsuite/c-c++-common/pragma-visibility-parsing.c new file mode 100644 index 00000000000..19ad6758b8c --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-visibility-parsing.c @@ -0,0 +1,13 @@ +/* Test that we provide good warnings for malformed '#pragma GCC visibility'. */ + +#pragma GCC visibility /* { dg-line no_action } */ +/* { dg-warning "'#pragma GCC visibility' must be followed by 'push' or 'pop'" "" { target *-*-* } no_action } */ + +#pragma GCC visibility push 1066 /* { dg-warning "29: ignoring malformed '#pragma GCC visibility': expected '\\('" } */ + +#pragma GCC visibility push(foo) /* { dg-line bad_push_arg } */ +/* { dg-warning "29: '#pragma GCC visibility push\\(\\)' must specify 'default', 'internal', 'hidden' or 'protected'" "" { target *-*-* } bad_push_arg } + { dg-message "ignoring malformed '#pragma GCC visibility'" "" { target *-*-* } bad_push_arg } */ + +#pragma GCC visibility push(default) +#pragma GCC visibility pop 1066 /* { dg-warning "28: junk at end of '#pragma GCC visibility'" } */ diff --git a/gcc/testsuite/c-c++-common/pragma-weak-parsing.c b/gcc/testsuite/c-c++-common/pragma-weak-parsing.c new file mode 100644 index 00000000000..902044a2b20 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pragma-weak-parsing.c @@ -0,0 +1,24 @@ +/* Test that we provide good warnings for malformed '#pragma weak'. */ + +int bar; + +#pragma weak /* { dg-warning "ignoring malformed '#pragma weak': expected name" } */ + +#pragma weak 42 /* { dg-warning "14: ignoring malformed '#pragma weak': expected name" } */ + +/* This should be OK. */ +#pragma weak foo + +#pragma weak foo 1066 /* { dg-warning "18: junk at end of '#pragma weak'" } */ + +#pragma weak foo = /* { dg-warning "ignoring malformed '#pragma weak': expected name" } */ + +#pragma weak foo = 1066 /* { dg-warning "20: ignoring malformed '#pragma weak': expected name" } */ + +/* This should be OK. */ +#pragma weak foo = bar + +#pragma weak foo = bar baz /* { dg-warning "24: junk at end of '#pragma weak'" } */ + +typedef int foo_t; /* { dg-message "13: 'foo_t' is not a variable or function" } */ +#pragma weak foo_t /* { dg-warning "14: '#pragma weak' declaration of 'foo_t' not allowed, ignored" } */ diff --git a/gcc/testsuite/gcc.dg/bad-pragma-locations.c b/gcc/testsuite/gcc.dg/bad-pragma-locations.c index 8068839881d..6bf821d8e2a 100644 --- a/gcc/testsuite/gcc.dg/bad-pragma-locations.c +++ b/gcc/testsuite/gcc.dg/bad-pragma-locations.c @@ -7,42 +7,42 @@ /* pack ****************************************************************************/ #pragma pack -/* { dg-warning "missing '\\(' after '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': expected '\\('" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack - ^~~~ + ^ { dg-end-multiline-output "" } */ #pragma pack ( -/* { dg-warning "malformed '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': expected '\\)', integer, 'push', or 'pop'" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack ( - ^~~~ + ^ { dg-end-multiline-output "" } */ #pragma pack (32 -/* { dg-warning "malformed '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': expected '\\)'" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack (32 - ^~~~ + ^ { dg-end-multiline-output "" } */ #pragma pack (3.14159 -/* { dg-warning "invalid constant in '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': invalid constant" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack (3.14159 ^~~~~~~ { dg-end-multiline-output "" } */ #pragma pack (push, 3.14159 -/* { dg-warning "invalid constant in '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': invalid constant" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack (push, 3.14159 ^~~~~~~ { dg-end-multiline-output "" } */ #pragma pack (toothbrush -/* { dg-warning "unknown action 'toothbrush' for '#pragma pack' - ignored" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma pack': unknown action 'toothbrush'" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma pack (toothbrush ^~~~~~~~~~ @@ -58,14 +58,14 @@ /* target ****************************************************************************/ #pragma GCC target 42 -/* { dg-warning "#pragma GCC option' is not a string" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma GCC target 42 ^~ { dg-end-multiline-output "" } */ #pragma GCC target ( 1776 -/* { dg-warning "#pragma GCC option' is not a string" "" { target *-*-* } .-1 } +/* { dg-warning "ignoring malformed '#pragma GCC target': expected a string option" "" { target *-*-* } .-1 } { dg-begin-multiline-output "" } #pragma GCC target ( 1776 ^~~~ diff --git a/gcc/testsuite/gcc.dg/pragma-scalar_storate_order-parsing.c b/gcc/testsuite/gcc.dg/pragma-scalar_storate_order-parsing.c new file mode 100644 index 00000000000..b20f41caba8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pragma-scalar_storate_order-parsing.c @@ -0,0 +1,8 @@ +/* Test that we provide good warnings for malformed '#pragma scalar_storage_order'. */ + +#pragma scalar_storage_order /* { dg-warning "ignoring malformed '#pragma scalar_storage_order': expected 'big-endian', 'little-endian', or 'default'" } */ +#pragma scalar_storage_order 1066 /* { dg-warning "ignoring malformed '#pragma scalar_storage_order': expected 'big-endian', 'little-endian', or 'default'" } */ +#pragma scalar_storage_order foo /* { dg-warning "ignoring malformed '#pragma scalar_storage_order': expected 'big-endian', 'little-endian', or 'default'" } */ +#pragma scalar_storage_order little-endian +#pragma scalar_storage_order big-endian +#pragma scalar_storage_order default diff --git a/gcc/testsuite/gcc.dg/sso-6.c b/gcc/testsuite/gcc.dg/sso-6.c index 559253293b5..3654ffcb847 100644 --- a/gcc/testsuite/gcc.dg/sso-6.c +++ b/gcc/testsuite/gcc.dg/sso-6.c @@ -3,7 +3,7 @@ /* { dg-do run } */ /* { dg-require-effective-target int32plus } */ -#pragma scalar_storage_order /* { dg-warning "missing .big-endian., .little-endian., or .default." } */ +#pragma scalar_storage_order /* { dg-warning "expected .big-endian., .little-endian., or .default." } */ #pragma scalar_storage_order big-endian