From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id D9BF23972022 for ; Tue, 15 Sep 2020 21:48:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D9BF23972022 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-338-Pya9MxCgOi2kZOBafNngQg-1; Tue, 15 Sep 2020 17:48:40 -0400 X-MC-Unique: Pya9MxCgOi2kZOBafNngQg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 96F4D18C9F42 for ; Tue, 15 Sep 2020 21:48:39 +0000 (UTC) Received: from t470.redhat.com (ovpn-114-91.phx2.redhat.com [10.3.114.91]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3C24A1C4; Tue, 15 Sep 2020 21:48:39 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Subject: [committed] analyzer: fix ICE when merging constraints w/o transitivity [PR96650] Date: Tue, 15 Sep 2020 17:48:37 -0400 Message-Id: <20200915214837.9934-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-14.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, 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-List-Received-Date: Tue, 15 Sep 2020 21:48:46 -0000 PR analyzer/96650 reports an assertion failure when merging the intersection of two sets of constraints, due to the resulting constraints being infeasible. It turns out that the two input sets were each infeasible if transitivity were considered, but -fanalyzer-transitivity was off. However for this case, the merging code was "discovering" the transitive infeasibility of the intersection of the constraints even when -fanalyzer-transitivity is off, triggering an assertion failure. I attempted various fixes for this, but each of them would have introduced O(N^2) logic into the constraint-handling code into the -fno-analyzer-transitivity case (with N == the number of constraints). This patch fixes the ICE by tweaking the assertion, so that we silently drop such constraints if -fanalyzer-transitivity is off. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to master as r11-3212-g50ddbd0282e06614b29f0d3f3be5fbe70085a8bd. gcc/analyzer/ChangeLog: PR analyzer/96650 * constraint-manager.cc (merger_fact_visitor::on_fact): Replace assertion that add_constraint succeeded with an assertion that if it fails, -fanalyzer-transitivity is off. gcc/testsuite/ChangeLog: PR analyzer/96650 * gcc.dg/analyzer/pr96650-1-notrans.c: New test. * gcc.dg/analyzer/pr96650-1-trans.c: New test. * gcc.dg/analyzer/pr96650-2-notrans.c: New test. * gcc.dg/analyzer/pr96650-2-trans.c: New test. --- gcc/analyzer/constraint-manager.cc | 10 ++++++- .../gcc.dg/analyzer/pr96650-1-notrans.c | 30 +++++++++++++++++++ .../gcc.dg/analyzer/pr96650-1-trans.c | 30 +++++++++++++++++++ .../gcc.dg/analyzer/pr96650-2-notrans.c | 30 +++++++++++++++++++ .../gcc.dg/analyzer/pr96650-2-trans.c | 30 +++++++++++++++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc index e578e0502f2..521501fd4f4 100644 --- a/gcc/analyzer/constraint-manager.cc +++ b/gcc/analyzer/constraint-manager.cc @@ -1752,7 +1752,15 @@ public: if (m_cm_b->eval_condition (lhs, code, rhs).is_true ()) { bool sat = m_out->add_constraint (lhs, code, rhs); - gcc_assert (sat); + if (!sat) + { + /* If -fanalyzer-transitivity is off, we can encounter cases + where at least one of the two constraint_managers being merged + is infeasible, but we only discover that infeasibility + during merging (PR analyzer/96650). + Silently drop such constraints. */ + gcc_assert (!flag_analyzer_transitivity); + } } } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c new file mode 100644 index 00000000000..94c755540b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-O2 -fno-analyzer-transitivity" } */ + +int *wf; + +void +yd (void); + +int +cy (void); + +int * +ee (int hp) +{ + if (hp != 0) + yd (); + + return 0; +} + +void +z0 (int co) +{ + int l4 = sizeof (int); + + aq: + wf = ee (l4); + if (l4 < co) + l4 = cy () + sizeof (int); + goto aq; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c new file mode 100644 index 00000000000..b20630bb806 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-O2 -fanalyzer-transitivity" } */ + +int *wf; + +void +yd (void); + +int +cy (void); + +int * +ee (int hp) +{ + if (hp != 0) + yd (); + + return 0; +} + +void +z0 (int co) +{ + int l4 = sizeof (int); + + aq: + wf = ee (l4); + if (l4 < co) + l4 = cy () + sizeof (int); + goto aq; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c new file mode 100644 index 00000000000..fc7c045a32f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-fno-analyzer-transitivity" } */ + +#include "analyzer-decls.h" + +int foo (void); + +/* Infeasible path, requiring transitivity to find. */ + +void test_1 (int co, int y) +{ + if (4 < co) + if (co < y) + if (y == 0) + __analyzer_dump_path (); /* { dg-message "path" } */ +} + +/* Infeasible path, requiring transitivity to find, with a merger. */ + +void test_2 (int co, int y, int z) +{ + if (4 < co) + if (co < y) + if (y == 0) + { + while (foo ()) + { + } + __analyzer_dump_path (); /* { dg-message "path" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c new file mode 100644 index 00000000000..8d0c2950876 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-fanalyzer-transitivity" } */ + +#include "analyzer-decls.h" + +int foo (void); + +/* Infeasible path, requiring transitivity to find. */ + +void test_1 (int co, int y) +{ + if (4 < co) + if (co < y) + if (y == 0) + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +/* Infeasible path, requiring transitivity to find, with a merger. */ + +void test_2 (int co, int y, int z) +{ + if (4 < co) + if (co < y) + if (y == 0) + { + while (foo ()) + { + } + __analyzer_dump_path (); /* { dg-bogus "path" } */ + } +} -- 2.26.2