From patchwork Mon Feb 24 23:33:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1243707 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-520041-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha1 header.s=default header.b=aw6JAkHi; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=J57Yt1cH; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48RJKm4CqFz9sPR for ; Tue, 25 Feb 2020 10:33:46 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=Jui5A95HFFCj6jeP T3ATyWLhWDJY2uCsWsdxblmf/FKCqFQHMHqLxHI1wqmVYqJavAjXkPtXZV9rmyCZ FBJ8xGuNHHlwdnpHKiUHc8z3noMlxNctwSpkKgoikbtp9ZkBStQCfJjYOqNsDy2k XEHXCWXOtpKYSVJve3p/uJsjw/8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=g8TKNAfHjyB4Y5PKy3qDl9 kj+Wg=; b=aw6JAkHijZ1gXw3fSb29vuvqW1PKvyx6S0ftzS0wkGGiKu7zIzz9Wv td6/DCYFBn/NUCJyxADIxL0bCL63mv/SjNBoIWcwLCO0oWBqsmgfvq4MOHNQTmwZ JnMavCtarV3M0Q9Ew7t+pfNVNvlcsOFwxvG8IGyw5SwDWpahbv1c8= Received: (qmail 1899 invoked by alias); 24 Feb 2020 23:33:38 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 1840 invoked by uid 89); 24 Feb 2020 23:33:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.1 required=5.0 tests=AWL, BAYES_00, FILL_THIS_FORM_SHORT, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy= X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-1.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 24 Feb 2020 23:33:34 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1582587213; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=QnGvTueW8fqB3Ix9EtTuPJw0/CfY8zU/gupR6n09RUI=; b=J57Yt1cHBlUvK+mfEdeysntHRykaGVC5u0j9czkzN11atUwXne+tVXIm4pTpcYyPasZ/9R iZd5llHGKpQboBWd9P6CGeLWKtEYFWJ4ZJf0at+GO6dwfELesAqGTGOjl2CxkUDYUdid0S FlsPXASh0dCfRXV14F3KaBkqE0kwpsQ= 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-339-9WWvB-I_OjSoVNWhS5I-5Q-1; Mon, 24 Feb 2020 18:33:26 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6EDB11882CCC for ; Mon, 24 Feb 2020 23:33:25 +0000 (UTC) Received: from t470.redhat.com (ovpn-116-56.phx2.redhat.com [10.3.116.56]) by smtp.corp.redhat.com (Postfix) with ESMTP id CC03160BF7; Mon, 24 Feb 2020 23:33:24 +0000 (UTC) From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [committed] analyzer: fix ICE with OFFSET_TYPE [PR 93899] Date: Mon, 24 Feb 2020 18:33:22 -0500 Message-Id: <20200224233322.12334-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-IsSubscribed: yes PR analyzer/93899 reports an ICE within make_region_for_type when handling a param of type OFFSET_TYPE within exploded_graph::add_function_entry. This patch fixes the ICE by further generalizing the "give up on this tree code" logic from r10-6667-gf76a88ebf089871dcce215aa0cb1956ccc060895 for PR analyzer/93388 and r10-6695-g2e6233935c77b56a68e939c629702f960b8e6fb2 for PR analyzer/93778 by replacing the gcc_unreachable in make_region_for_type with a return of NULL, and handling this in add_region_for_type by notifying the ctxt. Doing so means that numerous places that create regions now need to have a context passed to them, so most of the patch is churn involved in passing a context around to where it's needed. Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to master as r10-6827-g3a25f345d1fbe2de8c12cae84b0c7d2a76c0b78e. gcc/analyzer/ChangeLog: PR analyzer/93899 * engine.cc (impl_region_model_context::impl_region_model_context): Add logger param. * engine.cc (exploded_graph::add_function_entry): Create an impl_region_model_context and pass it to the push_frame call. Bail if the resulting state is invalid. (exploded_graph::build_initial_worklist): Likewise. (exploded_graph::build_initial_worklist): Handle the case where add_function_entry fails. * exploded-graph.h (impl_region_model_context::impl_region_model_context): Add logger param. * region-model.cc (map_region::get_or_create): Add ctxt param and pass it to add_region_for_type. (map_region::can_merge_p): Pass NULL as a ctxt to call to get_or_create. (array_region::get_element): Pass ctxt to call to get_or_create. (array_region::get_or_create): Add ctxt param and pass it to add_region_for_type. (root_region::push_frame): Pass ctxt to get_or_create calls. (region_model::get_lvalue_1): Likewise. (region_model::make_region_for_unexpected_tree_code): Assert that ctxt is non-NULL. (region_model::get_rvalue_1): Pass ctxt to get_svalue_for_fndecl and get_svalue_for_label calls. (region_model::get_svalue_for_fndecl): Add ctxt param and pass it to get_region_for_fndecl. (region_model::get_region_for_fndecl): Add ctxt param and pass it to get_or_create. (region_model::get_svalue_for_label): Add ctxt param and pass it to get_region_for_label. (region_model::get_region_for_label): Add ctxt param and pass it to get_region_for_fndecl and get_or_create. (region_model::get_field_region): Add ctxt param and pass it to get_or_create_view and get_or_create. (make_region_for_type): Replace gcc_unreachable with return NULL. (region_model::add_region_for_type): Add ctxt param. Handle a return of NULL from make_region_for_type by calling make_region_for_unexpected_tree_code. (region_model::get_or_create_mem_ref): Pass ctxt to calls to get_or_create_view. (region_model::get_or_create_view): Add ctxt param and pass it to add_region_for_type. (selftest::test_state_merging): Pass ctxt to get_or_create_view. * region-model.h (region_model::get_or_create): Add ctxt param. (region_model::add_region_for_type): Likewise. (region_model::get_svalue_for_fndecl): Likewise. (region_model::get_svalue_for_label): Likewise. (region_model::get_region_for_fndecl): Likewise. (region_model::get_region_for_label): Likewise. (region_model::get_field_region): Likewise. (region_model::get_or_create_view): Likewise. gcc/testsuite/ChangeLog: PR analyzer/93899 * g++.dg/analyzer/pr93899.C: New test. --- gcc/analyzer/engine.cc | 20 +++- gcc/analyzer/exploded-graph.h | 3 +- gcc/analyzer/region-model.cc | 118 ++++++++++++++---------- gcc/analyzer/region-model.h | 25 +++-- gcc/testsuite/g++.dg/analyzer/pr93899.C | 2 + 5 files changed, 106 insertions(+), 62 deletions(-) create mode 100644 gcc/testsuite/g++.dg/analyzer/pr93899.C diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc index de6bf1d394f..7f8a4223eed 100644 --- a/gcc/analyzer/engine.cc +++ b/gcc/analyzer/engine.cc @@ -90,8 +90,9 @@ impl_region_model_context (exploded_graph &eg, impl_region_model_context:: impl_region_model_context (program_state *state, state_change *change, - const extrinsic_state &ext_state) -: m_eg (NULL), m_logger (NULL), m_enode_for_diag (NULL), + const extrinsic_state &ext_state, + logger *logger) +: m_eg (NULL), m_logger (logger), m_enode_for_diag (NULL), m_old_state (NULL), m_new_state (state), m_change (change), @@ -1829,7 +1830,11 @@ exploded_graph::add_function_entry (function *fun) { program_point point = program_point::from_function_entry (m_sg, fun); program_state state (m_ext_state); - state.m_region_model->push_frame (fun, NULL, NULL); + impl_region_model_context ctxt (&state, NULL, m_ext_state, get_logger ()); + state.m_region_model->push_frame (fun, NULL, &ctxt); + + if (!state.m_valid) + return NULL; exploded_node *enode = get_or_create_node (point, state, NULL); /* We should never fail to add such a node. */ @@ -2150,8 +2155,13 @@ exploded_graph::build_initial_worklist () continue; exploded_node *enode = add_function_entry (fun); if (logger) - logger->log ("created EN %i for %qE entrypoint", - enode->m_index, fun->decl); + { + if (enode) + logger->log ("created EN %i for %qE entrypoint", + enode->m_index, fun->decl); + else + logger->log ("did not create enode for %qE entrypoint", fun->decl); + } } } diff --git a/gcc/analyzer/exploded-graph.h b/gcc/analyzer/exploded-graph.h index a851dd929c9..7c2612d7b85 100644 --- a/gcc/analyzer/exploded-graph.h +++ b/gcc/analyzer/exploded-graph.h @@ -43,7 +43,8 @@ class impl_region_model_context : public region_model_context impl_region_model_context (program_state *state, state_change *change, - const extrinsic_state &ext_state); + const extrinsic_state &ext_state, + logger *logger = NULL); void warn (pending_diagnostic *d) FINAL OVERRIDE; diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index d061552da37..a71884d7b11 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1660,20 +1660,22 @@ map_region::dump_child_label (const region_model &model, If it doesn't already exist, create a child map_region, using TYPE for its type. Return the region_id of the child (whether pre-existing, or - newly-created). */ + newly-created). + Notify CTXT if we don't know how to handle TYPE. */ region_id map_region::get_or_create (region_model *model, region_id this_rid, tree key, - tree type) + tree type, + region_model_context *ctxt) { gcc_assert (key); gcc_assert (valid_key_p (key)); region_id *slot = m_map.get (key); if (slot) return *slot; - region_id child_rid = model->add_region_for_type (this_rid, type); + region_id child_rid = model->add_region_for_type (this_rid, type, ctxt); m_map.put (key, child_rid); return child_rid; } @@ -1906,7 +1908,8 @@ map_region::can_merge_p (const map_region *map_region_a, = merged_map_region->get_or_create (merger->m_merged_model, merged_rid, key_a, - child_region_a->get_type ()); + child_region_a->get_type (), + NULL); region *child_merged_region = merger->m_merged_model->get_region (child_merged_rid); @@ -2194,7 +2197,7 @@ region_id array_region::get_element (region_model *model, region_id this_rid, svalue_id index_sid, - region_model_context *ctxt ATTRIBUTE_UNUSED) + region_model_context *ctxt) { tree element_type = TREE_TYPE (get_type ()); svalue *index_sval = model->get_svalue (index_sid); @@ -2202,11 +2205,11 @@ array_region::get_element (region_model *model, { key_t key = key_from_constant (cst_index); region_id element_rid - = get_or_create (model, this_rid, key, element_type); + = get_or_create (model, this_rid, key, element_type, ctxt); return element_rid; } - return model->get_or_create_view (this_rid, element_type); + return model->get_or_create_view (this_rid, element_type, ctxt); } /* Implementation of region::clone vfunc for array_region. */ @@ -2323,18 +2326,20 @@ array_region::dump_child_label (const region_model &model, If it doesn't already exist, create a child array_region, using TYPE for its type. Return the region_id of the child (whether pre-existing, or - newly-created). */ + newly-created). + Notify CTXT if we don't know how to handle TYPE. */ region_id array_region::get_or_create (region_model *model, region_id this_rid, key_t key, - tree type) + tree type, + region_model_context *ctxt) { region_id *slot = m_map.get (key); if (slot) return *slot; - region_id child_rid = model->add_region_for_type (this_rid, type); + region_id child_rid = model->add_region_for_type (this_rid, type, ctxt); m_map.put (key, child_rid); return child_rid; } @@ -2890,7 +2895,7 @@ root_region::push_frame (region_model *model, function *fun, svalue_id arg_sid = (*arg_sids)[idx]; region_id parm_rid = region->get_or_create (model, frame_rid, iter_parm, - TREE_TYPE (iter_parm)); + TREE_TYPE (iter_parm), ctxt); model->set_value (parm_rid, arg_sid, ctxt); /* Also do it for default SSA name (sharing the same unknown @@ -2900,7 +2905,7 @@ root_region::push_frame (region_model *model, function *fun, { region_id defssa_rid = region->get_or_create (model, frame_rid, parm_default_ssa, - TREE_TYPE (iter_parm)); + TREE_TYPE (iter_parm), ctxt); model->set_value (defssa_rid, arg_sid, ctxt); } } @@ -2917,7 +2922,7 @@ root_region::push_frame (region_model *model, function *fun, { region_id parm_rid = region->get_or_create (model, frame_rid, iter_parm, - TREE_TYPE (iter_parm)); + TREE_TYPE (iter_parm), ctxt); svalue_id parm_sid = model->set_to_new_unknown_value (parm_rid, TREE_TYPE (iter_parm), ctxt); @@ -2929,7 +2934,7 @@ root_region::push_frame (region_model *model, function *fun, { region_id defssa_rid = region->get_or_create (model, frame_rid, parm_default_ssa, - TREE_TYPE (iter_parm)); + TREE_TYPE (iter_parm), ctxt); model->get_region (defssa_rid)->set_value (*model, defssa_rid, parm_sid, ctxt); } @@ -4665,7 +4670,8 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) { /* For now, create a view, as if a cast, ignoring the bit positions. */ tree obj = TREE_OPERAND (expr, 0); - return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr)); + return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr), + ctxt); }; break; @@ -4688,7 +4694,7 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) = get_root_region ()->ensure_globals_region (this); map_region *globals = get_region (globals_rid); region_id var_rid = globals->get_or_create (this, globals_rid, expr, - TREE_TYPE (expr)); + TREE_TYPE (expr), ctxt); return var_rid; } @@ -4710,7 +4716,7 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) frame_region *frame = get_region (frame_rid); gcc_assert (frame); region_id child_rid = frame->get_or_create (this, frame_rid, expr, - TREE_TYPE (expr)); + TREE_TYPE (expr), ctxt); return child_rid; } @@ -4726,15 +4732,15 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) dump_location_t ()); region_id obj_rid = get_lvalue (obj, ctxt); region_id struct_or_union_rid - = get_or_create_view (obj_rid, TREE_TYPE (obj)); - return get_field_region (struct_or_union_rid, field); + = get_or_create_view (obj_rid, TREE_TYPE (obj), ctxt); + return get_field_region (struct_or_union_rid, field, ctxt); } break; case CONST_DECL: { tree cst_type = TREE_TYPE (expr); - region_id cst_rid = add_region_for_type (m_root_rid, cst_type); + region_id cst_rid = add_region_for_type (m_root_rid, cst_type, ctxt); if (tree value = DECL_INITIAL (expr)) { svalue_id sid = get_rvalue (value, ctxt); @@ -4758,7 +4764,8 @@ region_model::get_lvalue_1 (path_var pv, region_model_context *ctxt) case VIEW_CONVERT_EXPR: { tree obj = TREE_OPERAND (expr, 0); - return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr)); + return get_or_create_view (get_lvalue (obj, ctxt), TREE_TYPE (expr), + ctxt); }; break; } @@ -4776,6 +4783,7 @@ region_model::make_region_for_unexpected_tree_code (region_model_context *ctxt, tree t, const dump_location_t &loc) { + gcc_assert (ctxt); region_id new_rid = add_region (new symbolic_region (m_root_rid, NULL_TREE, false)); ctxt->on_unexpected_tree_code (t, loc); @@ -4840,9 +4848,9 @@ region_model::get_rvalue_1 (path_var pv, region_model_context *ctxt) tree expr = pv.m_tree; tree op0 = TREE_OPERAND (expr, 0); if (TREE_CODE (op0) == FUNCTION_DECL) - return get_svalue_for_fndecl (TREE_TYPE (expr), op0); + return get_svalue_for_fndecl (TREE_TYPE (expr), op0, ctxt); else if (TREE_CODE (op0) == LABEL_DECL) - return get_svalue_for_label (TREE_TYPE (expr), op0); + return get_svalue_for_label (TREE_TYPE (expr), op0, ctxt); region_id expr_rid = get_lvalue (op0, ctxt); return get_or_create_ptr_svalue (TREE_TYPE (expr), expr_rid); } @@ -4945,10 +4953,11 @@ region_model::get_or_create_constant_svalue (tree cst_expr) creating the function_region if necessary. */ svalue_id -region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl) +region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl, + region_model_context *ctxt) { gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL); - region_id function_rid = get_region_for_fndecl (fndecl); + region_id function_rid = get_region_for_fndecl (fndecl, ctxt); return get_or_create_ptr_svalue (ptr_type, function_rid); } @@ -4956,24 +4965,27 @@ region_model::get_svalue_for_fndecl (tree ptr_type, tree fndecl) creating it if necessary. */ region_id -region_model::get_region_for_fndecl (tree fndecl) +region_model::get_region_for_fndecl (tree fndecl, + region_model_context *ctxt) { gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL); region_id code_rid = get_root_region ()->ensure_code_region (this); code_region *code = get_root_region ()->get_code_region (this); - return code->get_or_create (this, code_rid, fndecl, TREE_TYPE (fndecl)); + return code->get_or_create (this, code_rid, fndecl, TREE_TYPE (fndecl), + ctxt); } /* Return an svalue_id for a region_svalue for LABEL, creating the label_region if necessary. */ svalue_id -region_model::get_svalue_for_label (tree ptr_type, tree label) +region_model::get_svalue_for_label (tree ptr_type, tree label, + region_model_context *ctxt) { gcc_assert (TREE_CODE (label) == LABEL_DECL); - region_id label_rid = get_region_for_label (label); + region_id label_rid = get_region_for_label (label, ctxt); return get_or_create_ptr_svalue (ptr_type, label_rid); } @@ -4981,16 +4993,18 @@ region_model::get_svalue_for_label (tree ptr_type, tree label) creating it if necessary. */ region_id -region_model::get_region_for_label (tree label) +region_model::get_region_for_label (tree label, + region_model_context *ctxt) { gcc_assert (TREE_CODE (label) == LABEL_DECL); tree fndecl = DECL_CONTEXT (label); gcc_assert (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL); - region_id func_rid = get_region_for_fndecl (fndecl); + region_id func_rid = get_region_for_fndecl (fndecl, ctxt); function_region *func_reg = get_region (func_rid); - return func_reg->get_or_create (this, func_rid, label, TREE_TYPE (label)); + return func_reg->get_or_create (this, func_rid, label, TREE_TYPE (label), + ctxt); } /* Build a cast of SRC_EXPR to DST_TYPE, or return NULL_TREE. @@ -5124,7 +5138,8 @@ region_model::maybe_cast (tree dst_type, svalue_id sid, return the child region's region_id. */ region_id -region_model::get_field_region (region_id struct_or_union_rid, tree field) +region_model::get_field_region (region_id struct_or_union_rid, tree field, + region_model_context *ctxt) { struct_or_union_region *sou_reg = get_region (struct_or_union_rid); @@ -5141,7 +5156,7 @@ region_model::get_field_region (region_id struct_or_union_rid, tree field) /* Union. Get a view of the union as a whole, with the type of the field. */ region_id view_rid - = get_or_create_view (struct_or_union_rid, field_type_with_quals); + = get_or_create_view (struct_or_union_rid, field_type_with_quals, ctxt); return view_rid; } else @@ -5149,7 +5164,7 @@ region_model::get_field_region (region_id struct_or_union_rid, tree field) /* Struct. */ region_id child_rid = sou_reg->get_or_create (this, struct_or_union_rid, field, - field_type_with_quals); + field_type_with_quals, ctxt); return child_rid; } } @@ -6061,7 +6076,8 @@ region_model::get_region (region_id rid) const } /* Make a region of an appropriate subclass for TYPE, - with parent PARENT_RID. */ + with parent PARENT_RID, or return NULL for types we don't yet know + how to handle. */ static region * make_region_for_type (region_id parent_rid, tree type) @@ -6091,18 +6107,24 @@ make_region_for_type (region_id parent_rid, tree type) if (VOID_TYPE_P (type)) return new symbolic_region (parent_rid, type, false); - gcc_unreachable (); + return NULL; } /* Add a region with type TYPE and parent PARENT_RID. */ region_id -region_model::add_region_for_type (region_id parent_rid, tree type) +region_model::add_region_for_type (region_id parent_rid, tree type, + region_model_context *ctxt) { gcc_assert (TYPE_P (type)); - region *new_region = make_region_for_type (parent_rid, type); - return add_region (new_region); + if (region *new_region = make_region_for_type (parent_rid, type)) + return add_region (new_region); + + /* If we can't handle TYPE, return a placeholder region, and stop + exploring this path. */ + return make_region_for_unexpected_tree_code (ctxt, type, + dump_location_t ()); } /* Helper class for region_model::purge_unused_svalues. */ @@ -6581,7 +6603,7 @@ region_model::get_or_create_mem_ref (tree type, if (zerop (cst_sval->get_constant ())) { /* Handle the zero offset case. */ - return get_or_create_view (raw_rid, type); + return get_or_create_view (raw_rid, type, ctxt); } /* If we're already within an array of the correct type, @@ -6622,7 +6644,7 @@ region_model::get_or_create_mem_ref (tree type, region_id element_rid = parent_array->get_element (this, raw_rid, index_sid, ctxt); - return get_or_create_view (element_rid, type); + return get_or_create_view (element_rid, type, ctxt); } } } @@ -6630,7 +6652,7 @@ region_model::get_or_create_mem_ref (tree type, tree array_type = build_array_type (TREE_TYPE (ptr_type), integer_type_node); - region_id array_view_rid = get_or_create_view (raw_rid, array_type); + region_id array_view_rid = get_or_create_view (raw_rid, array_type, ctxt); array_region *array_reg = get_region (array_view_rid); svalue_id index_sid @@ -6639,7 +6661,7 @@ region_model::get_or_create_mem_ref (tree type, region_id element_rid = array_reg->get_element (this, array_view_rid, index_sid, ctxt); - return get_or_create_view (element_rid, type); + return get_or_create_view (element_rid, type, ctxt); } /* Get a region of type TYPE for PTR_SID + OFFSET_SID. @@ -6664,7 +6686,8 @@ region_model::get_or_create_pointer_plus_expr (tree type, Return the id of the view (or RAW_ID if it of the same type). */ region_id -region_model::get_or_create_view (region_id raw_rid, tree type) +region_model::get_or_create_view (region_id raw_rid, tree type, + region_model_context *ctxt) { region *raw_region = get_region (raw_rid); @@ -6679,7 +6702,7 @@ region_model::get_or_create_view (region_id raw_rid, tree type) /* Otherwise, make one (adding it to the region_model and to the viewed region). */ - region_id view_rid = add_region_for_type (raw_rid, type); + region_id view_rid = add_region_for_type (raw_rid, type, ctxt); raw_region->add_view (view_rid, this); // TODO: something to signify that this is a "view" return view_rid; @@ -8102,7 +8125,8 @@ test_state_merging () region_model model0; region_id x_rid = model0.get_lvalue (x, &ctxt); - region_id x_as_ptr = model0.get_or_create_view (x_rid, ptr_type_node); + region_id x_as_ptr = model0.get_or_create_view (x_rid, ptr_type_node, + &ctxt); model0.set_value (x_as_ptr, model0.get_rvalue (addr_of_y, &ctxt), &ctxt); region_model model1 (model0); diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 3b2b43b595f..c185eb18d0b 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -978,7 +978,8 @@ public: region_id get_or_create (region_model *model, region_id this_rid, - tree expr, tree type); + tree expr, tree type, + region_model_context *ctxt); void unbind (tree expr); region_id *get (tree expr); @@ -1374,7 +1375,8 @@ public: region_id get_or_create (region_model *model, region_id this_rid, - key_t key, tree type); + key_t key, tree type, + region_model_context *ctxt); // void unbind (int expr); region_id *get (key_t key); @@ -1719,7 +1721,8 @@ class region_model region_id add_region (region *r); - region_id add_region_for_type (region_id parent_rid, tree type); + region_id add_region_for_type (region_id parent_rid, tree type, + region_model_context *ctxt); svalue *get_svalue (svalue_id sval_id) const; region *get_region (region_id rid) const; @@ -1740,16 +1743,19 @@ class region_model svalue_id get_or_create_ptr_svalue (tree ptr_type, region_id id); svalue_id get_or_create_constant_svalue (tree cst_expr); - svalue_id get_svalue_for_fndecl (tree ptr_type, tree fndecl); - svalue_id get_svalue_for_label (tree ptr_type, tree label); + svalue_id get_svalue_for_fndecl (tree ptr_type, tree fndecl, + region_model_context *ctxt); + svalue_id get_svalue_for_label (tree ptr_type, tree label, + region_model_context *ctxt); - region_id get_region_for_fndecl (tree fndecl); - region_id get_region_for_label (tree label); + region_id get_region_for_fndecl (tree fndecl, region_model_context *ctxt); + region_id get_region_for_label (tree label, region_model_context *ctxt); svalue_id maybe_cast (tree type, svalue_id sid, region_model_context *ctxt); svalue_id maybe_cast_1 (tree type, svalue_id sid); - region_id get_field_region (region_id rid, tree field); + region_id get_field_region (region_id rid, tree field, + region_model_context *ctxt); region_id deref_rvalue (svalue_id ptr_sid, region_model_context *ctxt); region_id deref_rvalue (tree ptr, region_model_context *ctxt); @@ -1826,7 +1832,8 @@ class region_model svalue_id ptr_sid, svalue_id offset_sid, region_model_context *ctxt); - region_id get_or_create_view (region_id raw_rid, tree type); + region_id get_or_create_view (region_id raw_rid, tree type, + region_model_context *ctxt); tree get_fndecl_for_call (const gcall *call, region_model_context *ctxt); diff --git a/gcc/testsuite/g++.dg/analyzer/pr93899.C b/gcc/testsuite/g++.dg/analyzer/pr93899.C new file mode 100644 index 00000000000..12fe0a2c881 --- /dev/null +++ b/gcc/testsuite/g++.dg/analyzer/pr93899.C @@ -0,0 +1,2 @@ +// { dg-do compile { target c++11 } } +#include "../abi/mangle55.C"