From patchwork Fri Sep 1 19:59:06 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: 137411 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c792:0:b0:3f2:4152:657d with SMTP id b18csp1113794vqu; Fri, 1 Sep 2023 13:01:24 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEn9MM9UXXn7slVMR3ApbWcTMAbktooDr4Laqw27VBQS5GH6J/1+pQvxdg6C5xFgnHfVaAA X-Received: by 2002:ac2:5bc4:0:b0:500:af82:5543 with SMTP id u4-20020ac25bc4000000b00500af825543mr2095881lfn.35.1693598484536; Fri, 01 Sep 2023 13:01:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693598484; cv=none; d=google.com; s=arc-20160816; b=M7DW2Dt0IeOqGWvV1cU+6hkNjuq9cLsE64r0lULRpEwegnV4Ykl967IlZu/pMlxYzs 9Fkk2SdRtJ2MNYh4e+v7A2OhBOa+X3qI2y1DHOJHn+egxsZ+bhGE7sfbuQj2WHlm6u5/ Bn3ZSz05o2P2sf3BAw7MipEgZvixuTheTbJ1mM7jpwLCS11xAuRBQGT7zwEls+pTedaG /EGWMwbV89qulzmVM3F6hnqRlcmdXOKLiA7NW3o1fsvbcfZvM+ii2iVdAIidevUd98V7 qmjO22+L9a3WTwaFg5wjGbc9JiEcEZCHKD5vSSQSaMuzAbbynwIFWZIGEyRT+BYj7HFH JLZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc: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:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=hcKBlOJ5APv+iqlRF+ZssajDnM0LTGlxnr/OaH15OcM=; fh=ZlB0koxfnHOTo42bNZcmZz9kKPmSXops0NJDj86lBGk=; b=N3TrEv7sn+Qd4/DyyGGg6HYilp9S69lQRNaoz6kw3fnE3AJcFEMJG2KpqkDG4Ll5/q nX2ArSMLcxkb6jCOLJECMXX+4GtqrGfuNdrQg3o2wg20n8sUERh7J+OETg7lsyP4tcqd vKG2KXZDI+C7dNe274GUF23xVwDfIWKqRWLnUqsSTaHG7CaygCnFbYrZajTzcSwCskLr rkCaIlUc98AXPNvfXa6YxXlzGwVbOqyDBUCZuClRv6qR7TxxI3wgFXv3eXl8eoBLWoIL Vyre0j74iiyYOaUxDufQm8eLGcWuBezMbMxYCxm48XpeEpCtWoGsyrFTTRxMSZ4+A3Q5 CMAA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=eew2DeuA; 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=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id n19-20020aa7c453000000b00523ae81218csi2975865edr.242.2023.09.01.13.01.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 01 Sep 2023 13:01:24 -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=@gcc.gnu.org header.s=default header.b=eew2DeuA; 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=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6CF943858C66 for ; Fri, 1 Sep 2023 20:01:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6CF943858C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1693598483; bh=hcKBlOJ5APv+iqlRF+ZssajDnM0LTGlxnr/OaH15OcM=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=eew2DeuAqEY8jwfRQAHt0jKMBGY59mcuk8Bn1D7VzuTOsl6TQjfvKOaTu811F+mmx U+J/uyIg4m8pGCDQh9j1dq5570l9HXcFYI8N5LM7ipb0NKSjSarsKOvFVmAsofCmCQ 6LYiXU2sOh1+Jx9Xoix7c3MZEk6hE/+eAloruLys= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by sourceware.org (Postfix) with ESMTPS id 54F113858D1E; Fri, 1 Sep 2023 20:00:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 54F113858D1E Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-31c3726cc45so2046369f8f.0; Fri, 01 Sep 2023 13:00:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693598434; x=1694203234; 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=hcKBlOJ5APv+iqlRF+ZssajDnM0LTGlxnr/OaH15OcM=; b=hinzeH5AxNB3pPxRvvD1t/T9BugdqLGrVV51z23WcDWciKWn/xhgwXAeJivBzCm87a EJjCpLgsvecuVmJYFKnTQwhxhVi63h9D0pgtfJ59dgBlrFnku3mdU7EkkTHCpx8JRDKH eRXr0xT0EKBdTVVgJQQr0oGZ4H6cbsyJyeSgA6lfEb8xyuWFDD9Q1o9luPM1crDDoQgn L66i1xvg8o8zpRXkjnMULSueULxfbh2z9mPkmGa1QH6fyvDEwmH4qtKcp43eGWsl9ao/ CM1spJMuKi8eWfwe6OBue2VwbwunXfvO/TR9PHJItGzqBS7xOs6QNIvhPxoVNoZ36emf 5s3g== X-Gm-Message-State: AOJu0YyyV6+IfWnQP2b/1595Gv8A6oe5gXG+9TOpyNu44qOh0e/U556b sU+e8qXV4h2uAo6q7lVe3w8QkbghsZSi X-Received: by 2002:a5d:4ac8:0:b0:319:8333:9052 with SMTP id y8-20020a5d4ac8000000b0031983339052mr2486870wrs.26.1693598433833; Fri, 01 Sep 2023 13:00:33 -0700 (PDT) Received: from localhost ([2a01:e0a:2ec:f0d0:9d3:4f28:21c5:4e05]) by smtp.gmail.com with UTF8SMTPSA id m3-20020a5d56c3000000b0031762e89f94sm5978929wrw.117.2023.09.01.13.00.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 01 Sep 2023 13:00:33 -0700 (PDT) X-Google-Original-From: vultkayn@gcc.gnu.org To: gcc-patches@gcc.gnu.org Subject: [PATCH] analyzer: call off a superseding when diagnostics are unrelated [PR110830] Date: Fri, 1 Sep 2023 21:59:06 +0200 Message-Id: <20230901195905.2800474-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.30 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 Cc: benjamin priour Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1775866724790898168 X-GMAIL-MSGID: 1775866724790898168 From: benjamin priour Hi, Patch succesfully regstrapped off trunk 7f2ed06ddc825e8a4e0edfd1d66b5156e6dc1d34 on x86_64-linux-gnu. Is it OK for trunk ? Thanks, Benjamin. Patch below. --- Before this patch, a saved_diagnostic would supersede another at the same statement if and only its vfunc supercedes_p returned true for the other diagnostic's kind. That both warning were unrelated, that is resolving one would not fix the other was not considered in making the above choice. This patch makes it so that two saved_diagnostics taking a different outcome of at least one common conditional branching cannot supersede each other. Signed-off-by: benjamin priour gcc/analyzer/ChangeLog: PR analyzer/110830 * diagnostic-manager.cc (compatible_epaths_p): New function. (saved_diagnostic::supercedes_p): Now calls the above to determine if the diagnostics do overlap and the superseding may proceed. gcc/testsuite/ChangeLog: PR analyzer/110830 * c-c++-common/analyzer/pr110830.c: New test. --- gcc/analyzer/diagnostic-manager.cc | 89 +++++++++++++- .../c-c++-common/analyzer/pr110830.c | 111 ++++++++++++++++++ 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr110830.c diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc index 10fea486b8c..7cf181e7972 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -887,6 +887,87 @@ saved_diagnostic::add_duplicate (saved_diagnostic *other) m_duplicates.safe_push (other); } +/* Walk up the two paths to each of their common conditional + branching. At each branching, make sure both diagnostics' + paths branched similarly. If there is at least one where + both paths go down a different outcome, then the paths + are incompatible and this function returns FALSE. + Otherwise return TRUE. + + Incompatible paths: + + + / \ + / \ + true false + | | + ... ... + | | + ... stmt x + | + stmt x + + Both LHS_PATH and RHS_PATH final enodes should be + over the same gimple statement. */ + +static bool +compatible_epath_p (const exploded_path *lhs_path, + const exploded_path *rhs_path) +{ + gcc_assert (lhs_path); + gcc_assert (rhs_path); + int i; + const exploded_edge *outer_eedge; + FOR_EACH_VEC_ELT_REVERSE (lhs_path->m_edges, i, outer_eedge) + { + const superedge *outer_sedge = outer_eedge->m_sedge; + if (!outer_sedge || !outer_eedge->m_src) + continue; + const program_point &outer_src_point = outer_eedge->m_src->get_point (); + switch (outer_src_point.get_kind ()) + { + case PK_AFTER_SUPERNODE: + if (const cfg_superedge *cfg_outer_sedge + = outer_sedge->dyn_cast_cfg_superedge ()) + { + int j; + const exploded_edge *inner_eedge; + FOR_EACH_VEC_ELT_REVERSE (rhs_path->m_edges, j, inner_eedge) + { + const superedge *inner_sedge = inner_eedge->m_sedge; + if (!inner_sedge || !inner_eedge->m_src) + continue; + const program_point &inner_src_point + = inner_eedge->m_src->get_point (); + switch (inner_src_point.get_kind ()) + { + case PK_AFTER_SUPERNODE: + if (inner_src_point.get_stmt () + != outer_src_point.get_stmt ()) + continue; + if (const cfg_superedge *cfg_inner_sedge + = inner_sedge->dyn_cast_cfg_superedge ()) + { + if (cfg_inner_sedge->true_value_p () + != cfg_outer_sedge->true_value_p ()) + return false; + } + break; + default: + break; + } + } + } + break; + + default: + break; + } + } + return true; +} + + /* Return true if this diagnostic supercedes OTHER, and that OTHER should therefore not be emitted. */ @@ -896,7 +977,13 @@ saved_diagnostic::supercedes_p (const saved_diagnostic &other) const /* They should be at the same stmt. */ if (m_stmt != other.m_stmt) return false; - return m_d->supercedes_p (*other.m_d); + /* return early if OTHER won't be superseded anyway. */ + if (!m_d->supercedes_p (*other.m_d)) + return false; + + /* If the two saved_diagnostics' path are not compatible + then they cannot supersede one another. */ + return compatible_epath_p (m_best_epath.get (), other.m_best_epath.get ()); } /* Move any saved checker_events from this saved_diagnostic to diff --git a/gcc/testsuite/c-c++-common/analyzer/pr110830.c b/gcc/testsuite/c-c++-common/analyzer/pr110830.c new file mode 100644 index 00000000000..9f6675ab693 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr110830.c @@ -0,0 +1,111 @@ +typedef __SIZE_TYPE__ size_t; + +void free(void *); +void *malloc(__SIZE_TYPE__); + +extern int ext(); + +void test_supersedes () +{ + int *p = (int *)malloc(sizeof(int)); + free(p); + int x = *p + 4; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-bogus "use of uninitialized value '\\*p" "" { target *-*-* } .-1 } */ +} + +int *called_by_test0() +{ + int *p = 0; + if (ext()) + { + p = (int *)malloc(sizeof(int)); + free(p); + return p; + } + else + return (int *)malloc(sizeof(int)); +} + +void test0() +{ + int *y = called_by_test0(); + int x = 0; + if (y != 0) + x = *y; /* { dg-warning "use after 'free' of 'y'" } */ + /* { dg-warning "use of uninitialized value '\\*y" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(y); /* { dg-warning "double-'free'" } */ +} + +void test1() +{ + int *p = 0; + if (ext()) + { + p = (int *)malloc(sizeof(int)); + free(p); + } + else + p = (int *)malloc(sizeof(int)); + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +} + +void test2() +{ + int *p = 0; + p = (int *)malloc(sizeof(int)); + if (ext()) + free(p); + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +} + +void test3() +{ + int *p = 0; + p = (int *)malloc(sizeof(int)); + int i = 100; + while (i--) + { + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p" "don't supersede warnings with incompatible cfg path" { target *-*-* } .-1 } */ + p = (int *)malloc(sizeof(int)); + free(p); + } + + free(p); /* { dg-warning "double-'free'" } */ +} + + +void test4() +{ + int *p = 0; + if (ext()) + { + p = (int *) malloc(sizeof(int)); + if (ext () > 5) + { + mal: + free (p); + } + } + else { + goto mal; + } + + int x = 0; + if (p != 0) + x = *p; /* { dg-warning "use after 'free' of 'p'" } */ + /* { dg-warning "use of uninitialized value '\\*p" "" { target *-*-* } .-1 } */ + free(p); /* { dg-warning "double-'free'" } */ +}