From patchwork Mon May 24 22:07:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Sebor X-Patchwork-Id: 1482981 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=UuXfU0q2; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.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 4FprtX4t7Qz9sRN for ; Tue, 25 May 2021 08:07:47 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D89EE3851C1B; Mon, 24 May 2021 22:07:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D89EE3851C1B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1621894063; bh=m7y38+9TpVqg6/FkUqHk6gqcamVSLMn7usgZknR/abc=; h=Subject:To:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=UuXfU0q2IL22awsakbQeXJlX9fzGCRlbISrvBQ+C4Gq+Z0LlK5W5tdw4w3Nshq3wf ynMd/1FiUp2yO1JFcxwhY5PHVQOQbt+Y8fxN1/E9UXYpqbde+xQGOGEMMQIu28Ltqx EPf4K+4k1+HPntlLznJTzkQTajeHIBwxHQp+8dy0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-ot1-x335.google.com (mail-ot1-x335.google.com [IPv6:2607:f8b0:4864:20::335]) by sourceware.org (Postfix) with ESMTPS id 4533B3858022 for ; Mon, 24 May 2021 22:07:40 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 4533B3858022 Received: by mail-ot1-x335.google.com with SMTP id h24-20020a9d64180000b029036edcf8f9a6so2380888otl.3 for ; Mon, 24 May 2021 15:07:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:from:to:cc:references:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=m7y38+9TpVqg6/FkUqHk6gqcamVSLMn7usgZknR/abc=; b=E3QTzt8uWjxZ7Fsivs1oaIDxIYYb2f4yvg9juDvq9My4ieZnGrWKdiP+hjQrG6N/OP aoEgvwkxoDOq7Wk260nK+xUbQUT+/TdEnfc7CAfhp9HFeLmS5rb/TDEn/w8gvtQckuv6 2JLjeOs+ThVzeTpJCByqPIZnLd+Itr23pwqPUuUthHJyxSy+f+0qHj127FMYV7Z7uR9U xOYZG60Ta2826DoFlTfrUxRIIMZlBuHHDjCK5wBiAFgyZBFUUMJpBVoIQnLOqtanVkqg KRVBOfwbACs5m6EJSBozCuG/QbygEFcUkthfIxBQuZ9qf9YwmL8Ig1UAGZ9TJXqD0ZQC mpFA== X-Gm-Message-State: AOAM533xfTNdO4FZH9zX6RHYLmq6WPjlfeJ6UxTC3AYFuR038flbw9TO 4Kjv2cmB2ezGJpYo2x6YYI4= X-Google-Smtp-Source: ABdhPJyqkoyJbU2fpkX4cC3UUqppe5mYwJ7FPfLeRbl0v2dYt9xYAF6PerdRgdsuInpZfUox1zviyw== X-Received: by 2002:a9d:c24:: with SMTP id 33mr19985015otr.289.1621894059744; Mon, 24 May 2021 15:07:39 -0700 (PDT) Received: from [192.168.0.41] (174-16-126-108.hlrn.qwest.net. [174.16.126.108]) by smtp.gmail.com with ESMTPSA id v22sm2849511oic.37.2021.05.24.15.07.38 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 24 May 2021 15:07:38 -0700 (PDT) Subject: [PATCH 1/11] introduce xxx_no_warning APIs To: gcc-patches References: <92db3776-af59-fa20-483b-aa67b17d0751@gmail.com> Message-ID: <535d1b55-fc0a-63c3-08b5-48a017674d1e@gmail.com> Date: Mon, 24 May 2021 16:07:38 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 In-Reply-To: <92db3776-af59-fa20-483b-aa67b17d0751@gmail.com> Content-Language: en-US X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, 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: Martin Sebor via Gcc-patches From: Martin Sebor Reply-To: Martin Sebor Cc: Martin Sebor Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The attached patch introduces the get_no_warning(), set_no_warning(), and copy_no_warning() APIs without making use of them in the rest of GCC. They are in three files: diagnostic-spec.{h,c}: Location-centric overloads. warning-control.cc: Tree- and gimple*-centric overloads. The location-centric overloads are suitable to use from the diagnostic subsystem. The rest can be used from the front ends and the middle end. Add support for per-location warning groups. gcc/ChangeLog: * Makefile.in (OBJS-libcommon): Add diagnostic-spec.o. * gengtype.c (open_base_files): Add diagnostic-spec.h. * diagnostic-spec.c: New file. * diagnostic-spec.h: New file. * warning-control.cc: New file. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1164554e6d6..b7bbcb60051 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1696,6 +1696,7 @@ OBJS = \ vmsdbgout.o \ vr-values.o \ vtable-verify.o \ + warning-control.o \ web.o \ wide-int.o \ wide-int-print.o \ @@ -1707,8 +1708,8 @@ OBJS = \ # Objects in libcommon.a, potentially used by all host binaries and with # no target dependencies. -OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \ - diagnostic-format-json.o json.o \ +OBJS-libcommon = diagnostic-spec.o diagnostic.o diagnostic-color.o \ + diagnostic-show-locus.o diagnostic-format-json.o json.o \ edit-context.o \ pretty-print.o intl.o \ sbitmap.o \ @@ -2648,6 +2649,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \ $(srcdir)/ipa-modref.h $(srcdir)/ipa-modref.c \ $(srcdir)/ipa-modref-tree.h \ $(srcdir)/signop.h \ + $(srcdir)/diagnostic-spec.h $(srcdir)/diagnostic-spec.c \ $(srcdir)/dwarf2out.h \ $(srcdir)/dwarf2asm.c \ $(srcdir)/dwarf2cfi.c \ diff --git a/gcc/diagnostic-spec.c b/gcc/diagnostic-spec.c new file mode 100644 index 00000000000..582ae3f3fe2 --- /dev/null +++ b/gcc/diagnostic-spec.c @@ -0,0 +1,172 @@ +/* Functions to enable and disable individual warnings on an expression + and statement basis. + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Martin Sebor + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "bitmap.h" +#include "tree.h" +#include "cgraph.h" +#include "hash-map.h" +#include "diagnostic-spec.h" +#include "pretty-print.h" + +/* Initialize *THIS from warning option OPT. */ + +nowarn_spec_t::nowarn_spec_t (int opt) +{ + /* Create a very simple mapping based on testing and experience. + It should become more refined with time. */ + switch (opt) + { + case 0: + case -1: + bits = opt; + break; + + /* Flow-sensitive warnings about pointer problems issued by both + front ends and the middle end. */ + case OPT_Waddress: + case OPT_Wnonnull: + bits = NW_NONNULL; + break; + + /* Flow-sensitive warnings about arithmetic overflow issued by both + front ends and the middle end. */ + case OPT_Woverflow: + case OPT_Wshift_count_negative: + case OPT_Wshift_count_overflow: + case OPT_Wstrict_overflow: + bits = NW_VFLOW; + break; + + /* Lexical warnings issued by front ends. */ + case OPT_Wabi: + case OPT_Wlogical_op: + case OPT_Wparentheses: + case OPT_Wreturn_type: + case OPT_Wsizeof_array_div: + case OPT_Wstrict_aliasing: + case OPT_Wunused: + case OPT_Wunused_function: + case OPT_Wunused_but_set_variable: + case OPT_Wunused_variable: + case OPT_Wunused_but_set_parameter: + bits = NW_LEXICAL; + break; + + /* Access warning group. */ + case OPT_Warray_bounds: + case OPT_Warray_bounds_: + case OPT_Wformat_overflow_: + case OPT_Wformat_truncation_: + case OPT_Wrestrict: + case OPT_Wstrict_aliasing_: + case OPT_Wstringop_overflow_: + case OPT_Wstringop_overread: + case OPT_Wstringop_truncation: + bits = NW_ACCESS; + break; + + /* Initialization warning group. */ + case OPT_Winit_self: + case OPT_Wuninitialized: + case OPT_Wmaybe_uninitialized: + bits = NW_UNINIT; + break; + + default: + /* A catchall group for everything else. */ + bits = NW_OTHER; + } +} + +/* Map from location to its no-warning disposition. */ + +GTY(()) xint_hash_map_t *nowarn_map; + +/* Return the no-warning disposition for location LOC and option OPT + or for all/any otions by default. */ + +bool +get_no_warning (location_t loc, int opt /* = -1 */) +{ + if (!nowarn_map) + return false; + + if (const nowarn_spec_t* const pspec = nowarn_map->get (loc)) + { + const nowarn_spec_t optspec (opt); + return *pspec & optspec; + } + + return false; +} + +/* Set the no-warning disposition for location LOC and option OPT when + DIS is true, or clear it when it's false. Return true if LOC has any + warnings disabled at the end of processing. */ + +bool +set_no_warning (location_t loc, int opt /* = -1 */, bool dis /* = true */) +{ + const nowarn_spec_t optspec (dis ? opt : 0); + + if (nowarn_spec_t *pspec = nowarn_map ? nowarn_map->get (loc) : NULL) + { + if (dis) + { + *pspec |= optspec; + return true; + } + + *pspec &= optspec; + if (*pspec) + return true; + + nowarn_map->remove (loc); + return false; + } + + if (!dis) + return false; + + if (!nowarn_map) + nowarn_map = xint_hash_map_t::create_ggc (32); + + nowarn_map->put (loc, optspec); + return true; +} + +/* Copy the no-warning disposition from one location to another. */ + +void +copy_no_warning (location_t to, location_t from) +{ + if (!nowarn_map) + return; + + if (nowarn_spec_t *pspec = nowarn_map->get (from)) + nowarn_map->put (to, *pspec); + else + nowarn_map->remove (to); +} diff --git a/gcc/diagnostic-spec.h b/gcc/diagnostic-spec.h new file mode 100644 index 00000000000..e0c02753923 --- /dev/null +++ b/gcc/diagnostic-spec.h @@ -0,0 +1,140 @@ +/* Language-independent APIs to enable/disable per-location warnings. + + Copyright (C) 2021 Free Software Foundation, Inc. + Contributed by Martin Sebor + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifndef DIAGNOSTIC_SPEC_H_INCLUDED +#define DIAGNOSTIC_SPEC_H_INCLUDED + +#include "hash-map.h" + +/* A "bitset" of warning groups. */ + +struct nowarn_spec_t +{ + enum + { + /* Middle end warnings about invalid accesses. */ + NW_ACCESS = 1 << 0, + /* Front end/lexical warnings. */ + NW_LEXICAL = 1 << 1, + /* Warnings about null pointers. */ + NW_NONNULL = 1 << 2, + /* Warnings about uninitialized reads. */ + NW_UNINIT = 1 << 3, + /* Warnings about arithmetic overflow. */ + NW_VFLOW = 1 << 4, + /* All other unclassified warnings. */ + NW_OTHER = 1 << 5, + /* All groups of warnings. */ + NW_ALL = (NW_ACCESS | NW_LEXICAL | NW_NONNULL + | NW_UNINIT | NW_VFLOW | NW_OTHER) + }; + + nowarn_spec_t (): bits () { } + + nowarn_spec_t (int); + + /* Return the raw bitset. */ + operator unsigned() const + { + return bits; + } + + /* Return true if the bitset is clear. */ + bool operator!() const + { + return !bits; + } + + /* Return the inverse of the bitset. */ + nowarn_spec_t operator~() const + { + nowarn_spec_t res (*this); + res.bits &= ~NW_ALL; + return res; + } + + /* Set *THIS to the bitwise OR of *THIS and RHS. */ + nowarn_spec_t& operator|= (const nowarn_spec_t &rhs) + { + bits |= rhs.bits; + return *this; + } + + /* Set *THIS to the bitwise AND of *THIS and RHS. */ + nowarn_spec_t& operator&= (const nowarn_spec_t &rhs) + { + bits &= rhs.bits; + return *this; + } + + /* Set *THIS to the bitwise exclusive OR of *THIS and RHS. */ + nowarn_spec_t& operator^= (const nowarn_spec_t &rhs) + { + bits ^= rhs.bits; + return *this; + } + +private: + /* Bitset of warning groups. */ + unsigned bits; +}; + +/* Return the bitwise OR of LHS and RHS. */ + +inline nowarn_spec_t +operator| (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return nowarn_spec_t (lhs) |= rhs; +} + +/* Return the bitwise AND of LHS and RHS. */ + +inline nowarn_spec_t +operator& (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return nowarn_spec_t (lhs) &= rhs; +} + +/* Return true if LHS is equal RHS. */ + +inline bool +operator== (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return static_cast(lhs) == static_cast(rhs); +} + +/* Return true if LHS is not equal RHS. */ + +inline bool +operator!= (const nowarn_spec_t &lhs, const nowarn_spec_t &rhs) +{ + return !(lhs == rhs); +} + +typedef location_t key_type_t; +typedef int_hash xint_hash_t; +typedef hash_map xint_hash_map_t; + +/* A mapping from the location of an expression to the warning spec + set for it. */ +extern GTY(()) xint_hash_map_t *nowarn_map; + +#endif // DIAGNOSTIC_SPEC_H_INCLUDED diff --git a/gcc/gengtype.c b/gcc/gengtype.c index b94e2f126ec..c1fa6d35c87 100644 --- a/gcc/gengtype.c +++ b/gcc/gengtype.c @@ -1727,7 +1727,7 @@ open_base_files (void) "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h", "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-general.h", "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h", "symtab-thunks.h", - "symtab-clones.h", + "symtab-clones.h", "diagnostic-spec.h", NULL }; const char *const *ifp; diff --git a/gcc/warning-control.cc b/gcc/warning-control.cc new file mode 100644 index 00000000000..73147b618ad --- /dev/null +++ b/gcc/warning-control.cc @@ -0,0 +1,230 @@ +/* Functions to enable and disable individual warnings on an expression + and statement basis. + + Copyright (C) 2021 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 3, or (at your option) any later + version. + + GCC is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "bitmap.h" +#include "tree.h" +#include "gimple.h" +#include "cgraph.h" +#include "hash-map.h" +#include "diagnostic-spec.h" + +/* Return the no-warning bit for EXPR. */ + +static inline bool +get_no_warning_bit (const_tree expr) +{ + return expr->base.nowarning_flag; +} + +/* Return the no-warning bit for statement STMT. */ + +static inline bool +get_no_warning_bit (const gimple *stmt) +{ + return stmt->no_warning; +} + +/* Set the no-warning bit for EXPR to VALUE. */ + +static inline void +set_no_warning_bit (tree expr, bool value) +{ + expr->base.nowarning_flag = value; +} + +/* Set the no-warning bit for statement STMT to VALUE. */ + +static inline void +set_no_warning_bit (gimple *stmt, bool value) +{ + stmt->no_warning = value; +} + +/* Return EXPR location of zero. */ + +static inline key_type_t +convert_to_key (const_tree expr) +{ + if (DECL_P (expr)) + return DECL_SOURCE_LOCATION (expr); + if (EXPR_P (expr)) + return EXPR_LOCATION (expr); + return 0; +} + +/* Return STMT location (may be zero). */ + +static inline key_type_t +convert_to_key (const gimple *stmt) +{ + return gimple_location (stmt); +} + +/* Return the no-warning bitmap for decl/expression EXPR. */ + +static nowarn_spec_t* +get_nowarn_spec (const_tree expr) +{ + const key_type_t key = convert_to_key (expr); + + if (!get_no_warning_bit (expr) || !key) + return NULL; + + return nowarn_map ? nowarn_map->get (key) : NULL; +} + +/* Return the no-warning bitmap for stateemt STMT. */ + +static nowarn_spec_t* +get_nowarn_spec (const gimple *stmt) +{ + const key_type_t key = convert_to_key (stmt); + + if (!get_no_warning_bit (stmt)) + return NULL; + + return nowarn_map ? nowarn_map->get (key) : NULL; +} + +/* Return true if warning OPT is enabled for decl/expression EXPR. + The wildcard OPT of -1 tests for all warnings being disabled. */ + +bool +get_no_warning (const_tree expr, int opt /* = -1 */) +{ + const nowarn_spec_t *spec = get_nowarn_spec (expr); + + if (!spec) + return get_no_warning_bit (expr); + + nowarn_spec_t optspec (opt); + bool dis = *spec & optspec; + gcc_assert (get_no_warning_bit (expr) || !dis); + return dis; +} + +/* Return true if warning OPT is enabled for statement STMT. + The wildcard OPT of -1 tests for all warnings being disabled. */ + +bool +get_no_warning (const gimple *stmt, int opt /* = -1 */) +{ + const nowarn_spec_t *spec = get_nowarn_spec (stmt); + + if (!spec) + /* Fall back on the single no-warning bit. */ + return get_no_warning_bit (stmt); + + nowarn_spec_t optspec (opt); + bool dis = *spec & optspec; + gcc_assert (get_no_warning_bit (stmt) || !dis); + return dis; +} + +/* Enable, or by default disable, a warning for the expression. + The wildcard OPT of -1 controls all warnings. */ + +void +set_no_warning (tree expr, int opt /* = -1 */, bool dis /* = true */) +{ + const key_type_t key = convert_to_key (expr); + + dis = set_no_warning (key, opt, dis) || dis; + set_no_warning_bit (expr, dis); +} + +/* Enable, or by default disable, a warning for the statement STMT. + The wildcard OPT of -1 controls all warnings. */ + +void +set_no_warning (gimple *stmt, int opt /* = -1 */, bool dis /* = true */) +{ + const key_type_t key = convert_to_key (stmt); + const nowarn_spec_t optspec (opt); + dis = set_no_warning (key, opt, dis) || dis; + set_no_warning_bit (stmt, dis); +} + +/* Copy the warning disposition mapping between an expression and/or + a statement. */ + +template +void copy_no_warning (ToType to, FromType from) +{ + const key_type_t to_key = convert_to_key (to); + + if (nowarn_spec_t *from_map = get_nowarn_spec (from)) + { + /* If there's an entry in the map the no-warning bit must be set. */ + gcc_assert (get_no_warning_bit (from)); + + if (!nowarn_map) + nowarn_map = xint_hash_map_t::create_ggc (32); + + nowarn_map->put (to_key, *from_map); + set_no_warning_bit (to, true); + } + else + { + if (nowarn_map) + nowarn_map->remove (to_key); + + /* The no-warning bit might be set even if there's no entry + in the map. */ + set_no_warning_bit (to, get_no_warning_bit (from)); + } +} + +/* Copy the warning disposition mapping from one expression to another. */ + +void +copy_no_warning (tree to, const_tree from) +{ + copy_no_warning(to, from); +} + +/* Copy the warning disposition mapping from a statement to an expression. */ + +void +copy_no_warning (tree to, const gimple *from) +{ + copy_no_warning(to, from); +} + +/* Copy the warning disposition mapping from an expression to a statement. */ + +void +copy_no_warning (gimple *to, const_tree from) +{ + copy_no_warning(to, from); +} + +/* Copy the warning disposition mapping from one statement to another. */ + +void +copy_no_warning (gimple *to, const gimple *from) +{ + copy_no_warning(to, from); +}