From patchwork Wed Oct 5 17:56:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1686453 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.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+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.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=Ml6xYtpH; 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 ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MjMhp75Qbz20Pd for ; Thu, 6 Oct 2022 04:56:57 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A350C3857353 for ; Wed, 5 Oct 2022 17:56:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A350C3857353 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1664992614; bh=cllsMVMR/K7kcirlTNUye2AK9fYWTPyKtxAX8Ov3qdo=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Ml6xYtpHD5/YrYX7N3taBRuwS1KRDwp/RciZm4M3IhBejbn/0GlxVEvz4cfxn6pqF jU415oX70uIYF9VnYVW7roB1jQND17eu6mDXed44IdPQRnmduhM8tfYtG44SmMMYO7 9TctpN+iT18e5rfjOtvS2pEiyDUxrsPG8hJAwoW8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 915773858C54 for ; Wed, 5 Oct 2022 17:56:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 915773858C54 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-221-Hh4wLdtnNdekWq3iOo_Arg-1; Wed, 05 Oct 2022 13:56:32 -0400 X-MC-Unique: Hh4wLdtnNdekWq3iOo_Arg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 284F8862FDC for ; Wed, 5 Oct 2022 17:56:32 +0000 (UTC) Received: from t14s.localdomain.com (unknown [10.2.17.92]) by smtp.corp.redhat.com (Postfix) with ESMTP id 013494B3FC6; Wed, 5 Oct 2022 17:56:31 +0000 (UTC) To: gcc-patches@gcc.gnu.org Subject: [committed] analyzer: fix ICEs seen with call summaries on PR 107060 Date: Wed, 5 Oct 2022 13:56:30 -0400 Message-Id: <20221005175630.748655-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, 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: David Malcolm via Gcc-patches From: David Malcolm Reply-To: David Malcolm Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" This doesn't fix the various false positives seen with -fanalyzer-call-summaries on PR 107060, but stops it crashing at -O2. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to trunk as r13-3094-g6832c95c0e1a58. gcc/analyzer/ChangeLog: PR analyzer/107060 * call-summary.cc (call_summary_replay::convert_svalue_from_summary_1): Handle NULL results from convert_svalue_from_summary in SK_UNARY_OP and SK_BIN_OP. * engine.cc (impl_region_model_context::on_unknown_change): Bail out on svalues that can't have associated state. * region-model-impl-calls.cc (region_model::impl_call_analyzer_get_unknown_ptr): New. * region-model.cc (region_model::on_stmt_pre): Handle "__analyzer_get_unknown_ptr". * region-model.h (region_model::impl_call_analyzer_get_unknown_ptr): New decl. * store.cc (store::replay_call_summary_cluster): Avoid trying to create binding clusters for base regions that shouldn't have them. gcc/ChangeLog: PR analyzer/107060 * doc/analyzer.texi (__analyzer_get_unknown_ptr): Document. gcc/testsuite/ChangeLog: PR analyzer/107060 * gcc.dg/analyzer/analyzer-decls.h (__analyzer_get_unknown_ptr): New decl. * gcc.dg/analyzer/call-summaries-2.c (test_summarized_writes_param_to_ptr_unknown): New test. Signed-off-by: David Malcolm --- gcc/analyzer/call-summary.cc | 28 +++++++++++++------ gcc/analyzer/engine.cc | 2 ++ gcc/analyzer/region-model-impl-calls.cc | 10 +++++++ gcc/analyzer/region-model.cc | 6 ++++ gcc/analyzer/region-model.h | 1 + gcc/analyzer/store.cc | 16 +++++++---- gcc/doc/analyzer.texi | 4 +++ .../gcc.dg/analyzer/analyzer-decls.h | 3 ++ .../gcc.dg/analyzer/call-summaries-2.c | 7 +++++ 9 files changed, 62 insertions(+), 15 deletions(-) diff --git a/gcc/analyzer/call-summary.cc b/gcc/analyzer/call-summary.cc index a8e881472ea..33916547e1e 100644 --- a/gcc/analyzer/call-summary.cc +++ b/gcc/analyzer/call-summary.cc @@ -298,23 +298,33 @@ call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval) { const unaryop_svalue *unaryop_summary_sval = as_a (summary_sval); + const svalue *summary_arg = unaryop_summary_sval->get_arg (); + const svalue *caller_arg = convert_svalue_from_summary (summary_arg); + if (!caller_arg) + return NULL; region_model_manager *mgr = get_manager (); - return mgr->get_or_create_unaryop - (summary_sval->get_type (), - unaryop_summary_sval->get_op (), - convert_svalue_from_summary (unaryop_summary_sval->get_arg ())); + return mgr->get_or_create_unaryop (summary_sval->get_type (), + unaryop_summary_sval->get_op (), + caller_arg); } break; case SK_BINOP: { const binop_svalue *binop_summary_sval = as_a (summary_sval); + const svalue *summary_arg0 = binop_summary_sval->get_arg0 (); + const svalue *caller_arg0 = convert_svalue_from_summary (summary_arg0); + if (!caller_arg0) + return NULL; + const svalue *summary_arg1 = binop_summary_sval->get_arg1 (); + const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1); + if (!caller_arg1) + return NULL; region_model_manager *mgr = get_manager (); - return mgr->get_or_create_binop - (summary_sval->get_type (), - binop_summary_sval->get_op (), - convert_svalue_from_summary (binop_summary_sval->get_arg0 ()), - convert_svalue_from_summary (binop_summary_sval->get_arg1 ())); + return mgr->get_or_create_binop (summary_sval->get_type (), + binop_summary_sval->get_op (), + caller_arg0, + caller_arg1); } break; case SK_SUB: diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index 735b5a3c061..faef0bd15b0 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -172,6 +172,8 @@ void impl_region_model_context::on_unknown_change (const svalue *sval, bool is_mutable) { + if (!sval->can_have_associated_state_p ()) + return; for (sm_state_map *smap : m_new_state->m_checker_states) smap->on_unknown_change (sval, is_mutable, m_ext_state); } diff --git a/gcc/analyzer/region-model-impl-calls.cc b/gcc/analyzer/region-model-impl-calls.cc index 71fb2770143..5cc590716b4 100644 --- a/gcc/analyzer/region-model-impl-calls.cc +++ b/gcc/analyzer/region-model-impl-calls.cc @@ -374,6 +374,16 @@ region_model::impl_call_analyzer_eval (const gcall *call, warning_at (call->location, 0, "%s", t.as_string ()); } +/* Handle the on_call_pre part of "__analyzer_get_unknown_ptr". */ + +void +region_model::impl_call_analyzer_get_unknown_ptr (const call_details &cd) +{ + const svalue *ptr_sval + = m_mgr->get_or_create_unknown_svalue (cd.get_lhs_type ()); + cd.maybe_set_lhs (ptr_sval); +} + /* Handle the on_call_pre part of "__builtin_expect" etc. */ void diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index d14f3a1840e..aa3d2054131 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1256,6 +1256,12 @@ region_model::on_stmt_pre (const gimple *stmt, { /* This is handled elsewhere. */ } + else if (is_special_named_call_p (call, "__analyzer_get_unknown_ptr", + 0)) + { + call_details cd (call, this, ctxt); + impl_call_analyzer_get_unknown_ptr (cd); + } else *out_unknown_side_effects = on_call_pre (call, ctxt, out_terminate_path); diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 6903090fcd3..e81595e8bc4 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -344,6 +344,7 @@ class region_model void impl_call_analyzer_dump_escaped (const gcall *call); void impl_call_analyzer_eval (const gcall *call, region_model_context *ctxt); + void impl_call_analyzer_get_unknown_ptr (const call_details &cd); void impl_call_builtin_expect (const call_details &cd); void impl_call_calloc (const call_details &cd); bool impl_call_error (const call_details &cd, unsigned min_args, diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc index 74b481dce48..1ca12142e47 100644 --- a/gcc/analyzer/store.cc +++ b/gcc/analyzer/store.cc @@ -3176,12 +3176,16 @@ store::replay_call_summary_cluster (call_summary_replay &r, = r.convert_region_from_summary (summary_base_reg)) { const region *caller_base_reg = caller_reg->get_base_region (); - binding_cluster *caller_cluster - = get_or_create_cluster (caller_base_reg); - if (summary_cluster->escaped_p ()) - caller_cluster->mark_as_escaped (); - if (summary_cluster->touched_p ()) - caller_cluster->m_touched = true; + if (caller_base_reg->tracked_p () + && !caller_base_reg->symbolic_for_unknown_ptr_p ()) + { + binding_cluster *caller_cluster + = get_or_create_cluster (caller_base_reg); + if (summary_cluster->escaped_p ()) + caller_cluster->mark_as_escaped (); + if (summary_cluster->touched_p ()) + caller_cluster->m_touched = true; + } } switch (summary_base_reg->get_kind ()) diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi index 06eb98fe4d3..ec49f951435 100644 --- a/gcc/doc/analyzer.texi +++ b/gcc/doc/analyzer.texi @@ -544,6 +544,10 @@ __analyzer_eval (expr); will emit a warning with text "TRUE", FALSE" or "UNKNOWN" based on the truthfulness of the argument. This is useful for writing DejaGnu tests. +@smallexample +__analyzer_get_unknown_ptr (); +@end smallexample +will obtain an unknown @code{void *}. @subsection Other Debugging Techniques diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h index d05257949ff..4478d740b58 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h @@ -47,4 +47,7 @@ extern void __analyzer_dump_state (const char *name, ...); truthfulness of the argument. */ extern void __analyzer_eval (int); +/* Obtain an "unknown" void *. */ +extern void *__analyzer_get_unknown_ptr (void); + #endif /* #ifndef ANALYZER_DECLS_H. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c index 0aaf67b8fd4..85cece72b34 100644 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/call-summaries-2.c @@ -72,6 +72,13 @@ void test_summarized_writes_param_to_ptr (int j) __analyzer_eval (y == j); /* { dg-warning "TRUE" } */ } +void test_summarized_writes_param_to_ptr_unknown (int j) +{ + int *p = (int *)__analyzer_get_unknown_ptr (); + writes_param_to_ptr (j, p); + __analyzer_eval (*p == j); /* { dg-warning "UNKNOWN" } */ +} + int g; void writes_to_global (int i)