From patchwork Fri Aug 11 11:51:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 134434 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b824:0:b0:3f2:4152:657d with SMTP id z4csp1029247vqi; Fri, 11 Aug 2023 04:52:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHv5HUVwIQJZYILMbP7dQ/c19DLqLmomInWkp3Kk4sJZ9GtkxoSXvH6PbNNeRwN1VvfWxfQ X-Received: by 2002:a17:906:53d0:b0:99c:55a9:3925 with SMTP id p16-20020a17090653d000b0099c55a93925mr1447326ejo.24.1691754724805; Fri, 11 Aug 2023 04:52:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691754724; cv=none; d=google.com; s=arc-20160816; b=FcqdYDA9yCDg3V/h+v5yR7i+hC4RQx027vH3FX597wSGJF/AhcZM+vQqWKXAgYjUCd StULXdUwDFNBCwUXSB48yfXsULf/k4I5Ty2xV2UB7JEAXdkZbLd3/JvARbMHHMZ4Dd8n vGIWxVR2p3mKSVAcF2Uqgu8zTtNn/rQcOaXCkFtPfXhVWeZFTXyGTR7tg1/Vc7us0RQm ouUPvkYNkf6yD/yoIODUniSKbxphMqZefWUxephIqxO3SG95h6EkSBuHjVIhMw73eK6D 6ja7g/D21gv4Cbk2Lb/SwkStoQaETWm59dgQvDrZGHhWyN1uef2FWMXb8suP8B/rjRAe I6Yg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=vTrCMUrBMEjdhLrG+Vl0FGiLgtr4mkGWnRcaFMlwN98=; fh=se9AvlvO6nAQ+5ltUc700CnLSEFsJZH/SLcWO+v9loY=; b=vEeR+lVqFFHqHN5Vd5Qhg97dD+xIr39BtwMzZrfh7G3eNHUxq15195gs3dK42pToI8 Ie+goqDDmnUYbnXQ8+Tw5J0EcQPq8S6B/guh4doJVBM+r3xVJ36fkRHCSKdr+4UrrhcS eWKtEImBAz6OJUWKOFpNK1g1OywrKQzole7OBnCo/8JoPYdwcnzUxUt3yruKejOvy3/8 +QaQAmqZAsX8TV5NvsSqByjNmKQ6Ju0iRsXFaqi5CgZ0O3eqx/3FdVfp3pzu4j/5spTN PGKv0MHyvMGYKTNYr7cY6Uidc3LVKTbisaBsP/FpBrOAFRyW7vLiYUnsuBsB8wZCHd5t CODA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=NdaZxzeN; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id h15-20020a1709063c0f00b0099329251046si3149167ejg.14.2023.08.11.04.52.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Aug 2023 04:52:04 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=NdaZxzeN; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 792803858415 for ; Fri, 11 Aug 2023 11:52:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 792803858415 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691754723; bh=vTrCMUrBMEjdhLrG+Vl0FGiLgtr4mkGWnRcaFMlwN98=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=NdaZxzeNknLhnE1oqatq2xlNkPKlLuW6F7B4bQ6mFhG4ySBhvf+7NmuNZ5U8gVAS9 p6NbRw6wDS4bOHrKoPuM7tluuGdWh60m/CLlinzRT8XymIeTG3EJSnLQXII5NqbLNJ Xn5iXucMEQiPWtDBej6pvo3pWP39RXttFe4Np+us= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by sourceware.org (Postfix) with ESMTPS id 46F0C3858D20; Fri, 11 Aug 2023 11:51:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 46F0C3858D20 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-3fbea147034so16637375e9.0; Fri, 11 Aug 2023 04:51:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691754677; x=1692359477; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vTrCMUrBMEjdhLrG+Vl0FGiLgtr4mkGWnRcaFMlwN98=; b=hWB8t44EXTRgeiE1el2RRXlEKeWFV8JC5uJswn6hMm7/SPSGtMZZTSSpTcEej+x4M2 M3WUeYndr/WRiGNxeWX2fu/Xh+hLbVPAzmyBN03JfJ+CARLB/9GanGAzhifoFPxPK2ka VtPgdZNVyzP3x6nj6kXxlMGWvyncbWP4fKQRKPK6NfVoedU6J18u/gnmdPhWq8pN1PMu r5hl7d2cScaIDpRF6J7HdoTspfhdhYbWto6l1kbNqWzM9dgY9ZLIvZx13z/x4W+wv/Yp nVLbiLo3DzwfeEt7/5rF34+SZrCfvAzctUscIERDfdqqjWOixs+imZSsWDOXhyoBD2ON t0yw== X-Gm-Message-State: AOJu0Yx8/D/fyyud94oFVaPYfkCBuqHjm49fDWlkMApeNTrUOy7n1vqz Z3dblwxBubxdxgYvYVOy8NyNAaNGLQ== X-Received: by 2002:a05:600c:c8:b0:3fb:a102:6d7a with SMTP id u8-20020a05600c00c800b003fba1026d7amr1389787wmm.28.1691754677166; Fri, 11 Aug 2023 04:51:17 -0700 (PDT) Received: from localhost ([2a01:e0a:2ec:f0d0:5142:1049:b199:3ae6]) by smtp.gmail.com with UTF8SMTPSA id s13-20020a7bc38d000000b003fe2ebf479fsm5003034wmj.36.2023.08.11.04.51.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 11 Aug 2023 04:51:16 -0700 (PDT) X-Google-Original-From: vultkayn@gcc.gnu.org To: gcc-patches@gcc.gnu.org Cc: dmalcolm@redhat.com, benjamin priour Subject: [PATCH] analyzer: New option fanalyzer-show-events-in-system-headers [PR110543] Date: Fri, 11 Aug 2023 13:51:15 +0200 Message-Id: <20230811115115.2277873-1-vultkayn@gcc.gnu.org> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 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, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Benjamin Priour via Gcc-patches From: "Li, Pan2 via Gcc-patches" Reply-To: priour.be@gmail.com Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1773933401979387551 X-GMAIL-MSGID: 1773933401979387551 From: benjamin priour This patch introduces -fanalyzer-show-events-in-system-headers, disabled by default. This option reduce the noise of the analyzer emitted diagnostics when dealing with system headers. The new option only affects the display of the diagnostics, but doesn't hinder the actual analysis. Given a diagnostics path diving into a system header in the form [ prefix events..., system header call, system header entry, events within system headers..., system header return, suffix events... ] then disabling the option (either by default or explicitly) will shorten the path into: [ prefix events..., system header call, system header return, suffix events... ] Signed-off-by: benjamin priour gcc/analyzer/ChangeLog: PR analyzer/110543 * analyzer.cc (is_std_function_p): No longer static. * analyzer.h (is_std_function_p): Add declaration. * analyzer.opt: Add new option. * diagnostic-manager.cc (INCLUDE_VECTOR): Include vector from system.h (diagnostic_manager::prune_path): Call prune_system_headers. (prune_frame): New function that deletes all events in a frame. (diagnostic_manager::prune_system_headers): New function. * diagnostic-manager.h: Add prune_system_headers declaration. gcc/testsuite/ChangeLog: PR analyzer/110543 * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C: New test. * g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C: New test. --- gcc/analyzer/analyzer.cc | 2 +- gcc/analyzer/analyzer.h | 1 + gcc/analyzer/analyzer.opt | 4 ++ gcc/analyzer/diagnostic-manager.cc | 65 +++++++++++++++++++ gcc/analyzer/diagnostic-manager.h | 1 + ...er-show-events-in-system-headers-default.C | 19 ++++++ ...nalyzer-show-events-in-system-headers-no.C | 19 ++++++ 7 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C create mode 100644 gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc index 5091fb7a583..b27d8e359db 100644 --- a/gcc/analyzer/analyzer.cc +++ b/gcc/analyzer/analyzer.cc @@ -274,7 +274,7 @@ is_named_call_p (const_tree fndecl, const char *funcname) Compare with cp/typeck.cc: decl_in_std_namespace_p, but this doesn't rely on being the C++ FE (or handle inline namespaces inside of std). */ -static inline bool +bool is_std_function_p (const_tree fndecl) { tree name_decl = DECL_NAME (fndecl); diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index 579517c23e6..31597079153 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -386,6 +386,7 @@ extern bool is_special_named_call_p (const gcall *call, const char *funcname, extern bool is_named_call_p (const_tree fndecl, const char *funcname); extern bool is_named_call_p (const_tree fndecl, const char *funcname, const gcall *call, unsigned int num_args); +extern bool is_std_function_p (const_tree fndecl); extern bool is_std_named_call_p (const_tree fndecl, const char *funcname); extern bool is_std_named_call_p (const_tree fndecl, const char *funcname, const gcall *call, unsigned int num_args); diff --git a/gcc/analyzer/analyzer.opt b/gcc/analyzer/analyzer.opt index 2760aaa8151..d97cd569f52 100644 --- a/gcc/analyzer/analyzer.opt +++ b/gcc/analyzer/analyzer.opt @@ -290,6 +290,10 @@ fanalyzer-transitivity Common Var(flag_analyzer_transitivity) Init(0) Enable transitivity of constraints during analysis. +fanalyzer-show-events-in-system-headers +Common Var(flag_analyzer_show_events_in_system_headers) Init(0) +Trim diagnostics path that are too long before emission. + fanalyzer-call-summaries Common Var(flag_analyzer_call_summaries) Init(0) Approximate the effect of function calls to simplify analysis. diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index cfca305d552..2a9705a464f 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -20,9 +20,11 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #define INCLUDE_MEMORY +#define INCLUDE_VECTOR #include "system.h" #include "coretypes.h" #include "tree.h" +#include "input.h" #include "pretty-print.h" #include "gcc-rich-location.h" #include "gimple-pretty-print.h" @@ -2281,6 +2283,8 @@ diagnostic_manager::prune_path (checker_path *path, path->maybe_log (get_logger (), "path"); prune_for_sm_diagnostic (path, sm, sval, state); prune_interproc_events (path); + if (! flag_analyzer_show_events_in_system_headers) + prune_system_headers (path); consolidate_conditions (path); finish_pruning (path); path->maybe_log (get_logger (), "pruned"); @@ -2667,6 +2671,67 @@ diagnostic_manager::prune_interproc_events (checker_path *path) const while (changed); } +/* Remove everything within [call point, IDX]. For consistency, + IDX should represent the return event of the frame to delete, + or if there is none it should be the last event of the frame. + After this function, IDX designates the event prior to calling + this frame. */ + +static void +prune_frame (checker_path *path, int &idx) +{ + gcc_assert (idx >= 0); + int nesting = 1; + if (path->get_checker_event (idx)->is_return_p ()) + nesting = 0; + do + { + if (path->get_checker_event (idx)->is_call_p ()) + nesting--; + else if (path->get_checker_event (idx)->is_return_p ()) + nesting++; + + path->delete_event (idx--); + } while (idx >= 0 && nesting != 0); +} + +void +diagnostic_manager::prune_system_headers (checker_path *path) const +{ + int idx = (signed)path->num_events () - 1; + while (idx >= 0) + { + const checker_event *event = path->get_checker_event (idx); + /* Prune everything between + [..., system entry, (...), system return, ...]. */ + if (event->is_return_p () + && in_system_header_at (event->get_location ())) + { + int ret_idx = idx; + label_text desc + (path->get_checker_event (ret_idx)->get_desc (false)); + prune_frame (path, idx); + + if (get_logger ()) + { + log ("filtering event %i-%i:" + " system header event: %s", + idx, ret_idx, desc.get ()); + } + // Delete function entry within system headers. + if (idx >= 0) + { + event = path->get_checker_event (idx); + if (event->is_function_entry_p () + && in_system_header_at (event->get_location ())) + path->delete_event (idx); + } + } + + idx--; + } +} + /* Return true iff event IDX within PATH is on the same line as REF_EXP_LOC. */ static bool diff --git a/gcc/analyzer/diagnostic-manager.h b/gcc/analyzer/diagnostic-manager.h index 9b3e903fc5d..d3022b888dd 100644 --- a/gcc/analyzer/diagnostic-manager.h +++ b/gcc/analyzer/diagnostic-manager.h @@ -180,6 +180,7 @@ private: state_machine::state_t state) const; void update_for_unsuitable_sm_exprs (tree *expr) const; void prune_interproc_events (checker_path *path) const; + void prune_system_headers (checker_path *path) const; void consolidate_conditions (checker_path *path) const; void finish_pruning (checker_path *path) const; diff --git a/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C b/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C new file mode 100644 index 00000000000..828afbdd9b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-default.C @@ -0,0 +1,19 @@ +/* { dg-additional-options "-fdiagnostics-plain-output" } */ +/* { dg-skip-if "no shared_ptr in C++98" { c++98_only } } */ + +#include + +struct A {int x; int y;}; + +int main () { + std::shared_ptr a; /* { dg-line declare_a } */ + a->x = 4; /* { dg-line deref_a } */ + /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a } */ + + return 0; +} + +/* { dg-note "\\(1\\) 'a\\.std::.+::_M_ptr' is NULL" "" { target c++14_down } declare_a } */ +/* { dg-note "dereference of NULL 'a\\.std.+::operator->\\(\\)'" "" { target *-*-* } deref_a } */ +/* { dg-note "calling 'std::.+::operator->' from 'main'" "" { target *-*-* } deref_a } */ +/* { dg-note "returning to 'main' from 'std::.+::operator->'" "" { target *-*-* } deref_a } */ diff --git a/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C b/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C new file mode 100644 index 00000000000..a6e991b0f08 --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C @@ -0,0 +1,19 @@ +/* { dg-additional-options "-fdiagnostics-plain-output -fno-analyzer-show-events-in-system-headers" } */ +/* { dg-skip-if "no shared_ptr in C++98" { c++98_only } } */ + +#include + +struct A {int x; int y;}; + +int main () { + std::shared_ptr a; /* { dg-line declare_a } */ + a->x = 4; /* { dg-line deref_a } */ + /* { dg-warning "dereference of NULL" "" { target *-*-* } deref_a } */ + + return 0; +} + +/* { dg-note "\\(1\\) 'a\\.std::.+::_M_ptr' is NULL" "" { target c++14_down } declare_a } */ +/* { dg-note "dereference of NULL 'a\\.std.+::operator->\\(\\)'" "" { target *-*-* } deref_a } */ +/* { dg-note "calling 'std::.+::operator->' from 'main'" "" { target *-*-* } deref_a } */ +/* { dg-note "returning to 'main' from 'std::.+::operator->'" "" { target *-*-* } deref_a } */