From patchwork Wed Sep 6 19:16:20 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: 137596 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ab0a:0:b0:3f2:4152:657d with SMTP id m10csp2525047vqo; Wed, 6 Sep 2023 12:30:41 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEf8fSOoMJeDhtSjdEY5R7LWZbH/9gbGLQ23q7Jgs7PMrdTjbhqR8ll1s1FoIsVbpB8iqx7 X-Received: by 2002:a05:651c:14e:b0:2bc:b29e:8ff6 with SMTP id c14-20020a05651c014e00b002bcb29e8ff6mr2909133ljd.7.1694028640687; Wed, 06 Sep 2023 12:30:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694028640; cv=none; d=google.com; s=arc-20160816; b=xByFIoJcw8gd2FaGNewqv2i9EhTm978LJX0gJryG0ZeOUdjN3s9KF1C4cLgQXblEFb KxbOvKeQm0lkUCbzn6VvhztXYz65PbfYG0fpEK5wp00M9R2wF/JafiMolpkcDoWuNOBM Tl+vEUv2KJjQOCimkGR3hMOhF4bk0NLYlgGg5xJ5Uzsk09Hv2swLk0lwDQh5dKSkegAW roADypBcqWOvC3WxN6VJ5slOoiQHOo7bjR+dykxYYPIJt5PDvZ+F8AV3lEIHBeUzaNCB o/VqdY8qBs1pZY1nG768Sg/USWIGcw4l6IAnCFFLDpD6k69Dg4T0TjmcrE+zAPVS/sXh ZoRg== 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:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=9hHeRGc7LpN/IsBbkcmJrujKSXV1K4UVyWunfXehnyY=; fh=ZlB0koxfnHOTo42bNZcmZz9kKPmSXops0NJDj86lBGk=; b=OfqG9Fj00gJynK9XIASarMWZwpmVXn+Y83C+S24VQZTGOBA53sVxYvZ6AXeShwaPr6 uGVBsRD2hwXMeQrzobVVTB2+WaO9bDLoSqH6RiMzk3Jk8qMmldCth+wSewBhZJpp9JkQ wBE3fJDANI06hhWdpiSbR9woxlLQQBdllblmVSrGMH8SCwDsilzeR8WbuT0oJCWfak7H XsLOOEq3M77OrrXXZrJAjkxELaFn+jAht2xqMCrXeNMK+6HFc71ErFTVmagzJko8mfI9 1ECJMkOVDwkjybmksuxKwJsOcGp3ihdIKJDsSN+u+uLzHlxVbXo1BLf3bxkgzGKnDCuC Fmrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=cDwcvD0a; 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 tk28-20020a170907c29c00b0099d61f05e05si9368010ejc.1023.2023.09.06.12.30.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 12:30:40 -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=cDwcvD0a; 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 EB7C4385DC1A for ; Wed, 6 Sep 2023 19:29:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org EB7C4385DC1A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1694028600; bh=9hHeRGc7LpN/IsBbkcmJrujKSXV1K4UVyWunfXehnyY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=cDwcvD0aAqIlG+sH4x1rtfCaDwbbRNtXozG33tpar/L/mov+ItjIJR03Aj1oEKnIM oOq0oUoN/FGck+xUhD6RUYY0w93SiMSnPxEXaGbzL8m6oey2zWv6lYAjJ055/BSHUt DxV8sub0NvRj1XPZYEnSHpiSv3jHd+bvMJRjkbWY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 8EBC3385828E; Wed, 6 Sep 2023 19:29:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8EBC3385828E Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-401bdff4cb4so2327305e9.3; Wed, 06 Sep 2023 12:29:12 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694028551; x=1694633351; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9hHeRGc7LpN/IsBbkcmJrujKSXV1K4UVyWunfXehnyY=; b=UclZcEh5AlXJ+R61AqNrZvPpKkv482JrGM+uLninuOgmQ/JMAZzM6hK13445gBr7zN MP9SSNwTcRy2rtkDfF5mZHfhvZn3zbWmgU08AudrZH/tbgbo+C0TGNCNLgB/v9iIhOW0 AMEUJyUjKPIF2qprAnLyzZU2+ZvxfBepwvIeimJGRdiYbeZjxOMlMTw6wTAG2kLh+Z33 UYj7Pf9OHRoN0NzuP5m8a9R4wvUuqFnfJIIV6GBWYFK89ZsEWvZgz0gU/d/iX0NVkiRu maAawk6/f66lD9/QhxALIzPj5wcIjrctWTXATGzbpUo3bIHjJXxGyGE9DzO1pI4sYUK/ 3Asg== X-Gm-Message-State: AOJu0YxzZjrxP6Vjn0H3KHliQfTd3TG7+/Pg59Czfz5dKu97pPYY6/7B +L7kehfIOk/ComCEoCJKmr8EQB2vu/Q9 X-Received: by 2002:a7b:c7c7:0:b0:402:cc9a:31a7 with SMTP id z7-20020a7bc7c7000000b00402cc9a31a7mr2889744wmk.19.1694028550661; Wed, 06 Sep 2023 12:29:10 -0700 (PDT) Received: from localhost ([2a01:e0a:2ec:f0d0:3d88:1139:2678:af1b]) by smtp.gmail.com with UTF8SMTPSA id f12-20020a1c6a0c000000b003fee8793911sm377990wmc.44.2023.09.06.12.29.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 06 Sep 2023 12:29:10 -0700 (PDT) X-Google-Original-From: vultkayn@gcc.gnu.org To: gcc-patches@gcc.gnu.org Subject: [PATCH v2] analyzer: Call off a superseding when diagnostics are unrelated [PR110830] Date: Wed, 6 Sep 2023 21:16:20 +0200 Message-Id: <20230906191618.3187438-1-vultkayn@gcc.gnu.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 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: 1776317775697854991 X-GMAIL-MSGID: 1776317775697854991 From: benjamin priour Hi, Second version of this patch after David's suggestions. Thanks David for pointing out how I could implement it using sedges. I hadn't thought of them being independent of the exploded path taken, and unique for a conditional block's outcome. I had mistaken them with eedges, those that we see in the *exploded*-graph, therefore since the two saved_diagnostics can have arbitrary different paths I had to use a nested loop. It is much more efficient this way. Regstrapped off trunk a7d052b3200c7928d903a0242b8cfd75d131e374 on x86_64-linux-gnu. Is it ready 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 - i.e. 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 Co-authored-by: david malcolm 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 | 90 +++++++++++++- .../c-c++-common/analyzer/pr110830.c | 111 ++++++++++++++++++ 2 files changed, 200 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..90c56a350e7 100644 --- a/gcc/analyzer/diagnostic-manager.cc +++ b/gcc/analyzer/diagnostic-manager.cc @@ -887,6 +887,88 @@ saved_diagnostic::add_duplicate (saved_diagnostic *other) m_duplicates.safe_push (other); } +/* Walk up the sedges of each of the two paths. + If the two sequences of sedges do not perfectly correspond, + then paths are incompatible. + If there is at least one sedge that either cannot be paired up + or its counterpart is not equal, 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); + gcc_assert (rhs_path->length () > 0); + gcc_assert (rhs_path->length () > 0); + int lhs_eedge_idx = lhs_path->length () -1; + int rhs_eedge_idx = rhs_path->length () -1; + const exploded_edge *lhs_eedge; + const exploded_edge *rhs_eedge; + + while (lhs_eedge_idx >= 0 && rhs_eedge_idx >= 0) + { + while (lhs_eedge_idx >= 0) + { + /* Find LHS_PATH's next superedge. */ + lhs_eedge = lhs_path->m_edges[lhs_eedge_idx]; + if (lhs_eedge->m_sedge) + break; + else + lhs_eedge_idx--; + } + while (rhs_eedge_idx >= 0) + { + /* Find RHS_PATH's next superedge. */ + rhs_eedge = rhs_path->m_edges[rhs_eedge_idx]; + if (rhs_eedge->m_sedge) + break; + else + rhs_eedge_idx--; + } + + if (lhs_eedge->m_sedge && rhs_eedge->m_sedge) + { + if (lhs_eedge->m_sedge != rhs_eedge->m_sedge) + /* Both superedges do not match. + Superedges are not dependent on the exploded path, so even + different epaths will have similar sedges if they follow + the same outcome of a conditional node. */ + return false; + + lhs_eedge_idx--; + rhs_eedge_idx--; + continue; + } + else if (lhs_eedge->m_sedge == nullptr && rhs_eedge->m_sedge == nullptr) + /* Both paths were drained up entirely. + No discriminant was found. */ + return true; + + /* A superedge was found for only one of the two paths. */ + return false; + } +} + + /* Return true if this diagnostic supercedes OTHER, and that OTHER should therefore not be emitted. */ @@ -896,7 +978,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..f5a39b7a067 --- /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'" } */ +}