From patchwork Tue Jan 9 11:37:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 857399 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-470521-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="LX9h2Sbv"; 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 3zG94R69vQz9sNV for ; Tue, 9 Jan 2018 22:33:09 +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:in-reply-to:references; q=dns; s= default; b=xtWZlMgPMswZgrUrkVR1eBqnCkWr0BuU+VUMPVTIgFrlkz3Z4hZPn doZ/wYk8qYJxygdFx1IH3YSfxH2SfJMPQKcywo02EKdK4MduAK5/gwaOhVk3mb9V Ofx/rpBsw6X1gZbetE1WXQ/HAt92FdUsWMlKnnxTBbX5K5xUfnRqPU= 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:in-reply-to:references; s= default; bh=iwHPz5TUrmbzwau/NzvD1/Jc8ac=; b=LX9h2Sbv+nbn1tv5ll54 ObSO5ZbzrRPJHqgqbyI1idVjwUd8k+KXnlxB1c0nUUqCoGWImwlIhvIGb+IlTgOt gn+HyHBIu9gZgVvpbk966POxofnDz2u9DeAHvjyEQnu/L467Yho094vtKN8E1cJH VPgff6LhDfaAaZM8qrjIvso= Received: (qmail 60754 invoked by alias); 9 Jan 2018 11:33:02 -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 60693 invoked by uid 89); 9 Jan 2018 11:33:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=v21, v2.1, purely X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 09 Jan 2018 11:32:59 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1671E356E1; Tue, 9 Jan 2018 11:32:58 +0000 (UTC) Received: from c64.redhat.com (ovpn-112-31.phx2.redhat.com [10.3.112.31]) by smtp.corp.redhat.com (Postfix) with ESMTP id 631C567011; Tue, 9 Jan 2018 11:32:56 +0000 (UTC) From: David Malcolm To: Jakub Jelinek Cc: Nathan Sidwell , Jason Merrill , Richard Biener , gcc-patches List , David Malcolm Subject: [PATCH v2.4 of 02/14] Support for adding and stripping location_t wrapper nodes Date: Tue, 9 Jan 2018 06:37:02 -0500 Message-Id: <1515497822-14693-1-git-send-email-dmalcolm@redhat.com> In-Reply-To: <20180108180851.GV1833@tucnak> References: <20180108180851.GV1833@tucnak> X-IsSubscribed: yes On Mon, 2018-01-08 at 19:08 +0100, Jakub Jelinek wrote: > On Mon, Jan 08, 2018 at 01:02:37PM -0500, David Malcolm wrote: > > Thanks Nathan and Jakub: a quick smoketest using TREE_LANG_FLAG_0 > > worked, and fixes this issue. > > > > However, should I be using a TREE_LANG_FLAG for something that's in > > tree.h/c, rather than just in the "cp" subdir? (the wrapper nodes > > are > > only added to C++ in this patch kit, but given that e.g. STRIP_NOPS > > needs to remove them, the lang-independent code needs to handle > > them, > > and ultimately we may want wrapper nodes in other FEs). > > If location_wrapper_p etc. are in generic code rather than only in > the FE, > sure, you'd need to use some generic flag rather than FE specific. > I bet e.g. private_flag and protected_flag aren't used yet for > VIEW_CONVERT_EXPR/NON_LVALUE_EXPR, but they are used on some other > expressions, e.g. CALL_EXPR, which suggests that it could be used for > that. > > Jakub Thanks. "public_flag" seemed to be available for those codes, so I used that, via a new EXPR_LOCATION_WRAPPER_P macro Here's an updated version of patch 2 of the kit to do so [1]. Successfully bootstrapped®rtested on x86_64-pc-linux-gnu, as part of the kit. Also, manually tested with "make s-selftest-c++" (since we don't run the selftests for cc1plus by default). OK for trunk in conjunction with the rest of the kit? (I'm about to post an updated version of the [03/14] patch, which is the only other part of the kit still needing review). Dave [1] (it also merges in the part of patch [08/14] for making wrappers for STRING_CST use VIEW_CONVERT_EXPR, which Jason has already approved; needs to be here to avoid git conflicts; all of this will be one squashed patch if/when committed). Blurb follows: Changed in v2.4: * use a flag rather than types for indicating location_wrapper_p (to cope with decls changing type from under us) * add the STRING_CST part of the [08/14] lvalue_kind patch Changed in v2.3: * move most of location_wrapper_p's comment inside the function (approved by Jason here: https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02618.html ) Changed in v2.2: * added tree_strip_any_location_wrapper * removed checking for !CONSTANT_CLASS_P on VIEW_CONVERT_EXPR Changed in v2.1: * updated comments for location_wrapper_p and maybe_wrap_with_location * added selftests This patch provides a mechanism in tree.c for adding a wrapper node for expressing a location_t, for those nodes for which !CAN_HAVE_LOCATION_P. It's called in later patches in the kit via a new method of cp_expr. In this version of the patch, I use NON_LVALUE_EXPR for wrapping constants, and VIEW_CONVERT_EXPR for other nodes. I also turned off wrapper nodes for EXCEPTIONAL_CLASS_P, for the sake of keeping the patch kit more minimal. The patch also adds a STRIP_ANY_LOCATION_WRAPPER macro for stripping such nodes, used later on in the patch kit. gcc/cp/ChangeLog: PR c++/43486 * cp-tree.h (cp_expr::maybe_add_location_wrapper): New method. gcc/ChangeLog: PR c++/43486 * tree-core.h: Document EXPR_LOCATION_WRAPPER_P's usage of "public_flag". * tree.c (maybe_wrap_with_location): New function. (selftest::test_location_wrappers): New function. (selftest::tree_c_tests): Call it. * tree.h (STRIP_ANY_LOCATION_WRAPPER): New macro. (maybe_wrap_with_location): New decl. (EXPR_LOCATION_WRAPPER_P): New macro. (location_wrapper_p): New inline function. (tree_strip_any_location_wrapper): New inline function. --- gcc/cp/cp-tree.h | 6 ++++ gcc/tree-core.h | 3 ++ gcc/tree.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/tree.h | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d408370..d4b45a4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -93,6 +93,12 @@ public: set_location (make_location (m_loc, start, finish)); } + cp_expr& maybe_add_location_wrapper () + { + m_value = maybe_wrap_with_location (m_value, m_loc); + return *this; + } + private: tree m_value; location_t m_loc; diff --git a/gcc/tree-core.h b/gcc/tree-core.h index b08d215..b127bc7 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1116,6 +1116,9 @@ struct GTY(()) tree_base { SSA_NAME_IS_VIRTUAL_OPERAND in SSA_NAME + EXPR_LOCATION_WRAPPER_P in + NON_LVALUE_EXPR, VIEW_CONVERT_EXPR + private_flag: TREE_PRIVATE in diff --git a/gcc/tree.c b/gcc/tree.c index aa647de..8b1c4b2 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14066,6 +14066,40 @@ set_source_range (tree expr, source_range src_range) return adhoc; } +/* Return EXPR, potentially wrapped with a node expression LOC, + if !CAN_HAVE_LOCATION_P (expr). + + NON_LVALUE_EXPR is used for wrapping constants, apart from STRING_CST. + VIEW_CONVERT_EXPR is used for wrapping non-constants and STRING_CST. + + Wrapper nodes can be identified using location_wrapper_p. */ + +tree +maybe_wrap_with_location (tree expr, location_t loc) +{ + if (expr == NULL) + return NULL; + if (loc == UNKNOWN_LOCATION) + return expr; + if (CAN_HAVE_LOCATION_P (expr)) + return expr; + /* We should only be adding wrappers for constants and for decls, + or for some exceptional tree nodes (e.g. BASELINK in the C++ FE). */ + gcc_assert (CONSTANT_CLASS_P (expr) + || DECL_P (expr) + || EXCEPTIONAL_CLASS_P (expr)); + + if (EXCEPTIONAL_CLASS_P (expr)) + return expr; + + tree_code code = (CONSTANT_CLASS_P (expr) && TREE_CODE (expr) != STRING_CST + ? NON_LVALUE_EXPR : VIEW_CONVERT_EXPR); + tree wrapper = build1_loc (loc, code, TREE_TYPE (expr), expr); + /* Mark this node as being a wrapper. */ + EXPR_LOCATION_WRAPPER_P (wrapper) = 1; + return wrapper; +} + /* Return the name of combined function FN, for debugging purposes. */ const char * @@ -14436,6 +14470,54 @@ test_vector_cst_patterns () check_vector_cst_fill (elements, build_vector (vector_type, elements), 4); } +/* Verify location wrappers. */ + +static void +test_location_wrappers () +{ + location_t loc = BUILTINS_LOCATION; + + /* Wrapping a constant. */ + tree int_cst = build_int_cst (integer_type_node, 42); + ASSERT_FALSE (CAN_HAVE_LOCATION_P (int_cst)); + ASSERT_FALSE (location_wrapper_p (int_cst)); + + tree wrapped_int_cst = maybe_wrap_with_location (int_cst, loc); + ASSERT_TRUE (location_wrapper_p (wrapped_int_cst)); + ASSERT_EQ (loc, EXPR_LOCATION (wrapped_int_cst)); + ASSERT_EQ (int_cst, tree_strip_any_location_wrapper (wrapped_int_cst)); + + /* Wrapping a STRING_CST. */ + tree string_cst = build_string (4, "foo"); + ASSERT_FALSE (CAN_HAVE_LOCATION_P (string_cst)); + ASSERT_FALSE (location_wrapper_p (string_cst)); + + tree wrapped_string_cst = maybe_wrap_with_location (string_cst, loc); + ASSERT_TRUE (location_wrapper_p (wrapped_string_cst)); + ASSERT_EQ (VIEW_CONVERT_EXPR, TREE_CODE (wrapped_string_cst)); + ASSERT_EQ (loc, EXPR_LOCATION (wrapped_string_cst)); + ASSERT_EQ (string_cst, tree_strip_any_location_wrapper (wrapped_string_cst)); + + + /* Wrapping a variable. */ + tree int_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, + get_identifier ("some_int_var"), + integer_type_node); + ASSERT_FALSE (CAN_HAVE_LOCATION_P (int_var)); + ASSERT_FALSE (location_wrapper_p (int_var)); + + tree wrapped_int_var = maybe_wrap_with_location (int_var, loc); + ASSERT_TRUE (location_wrapper_p (wrapped_int_var)); + ASSERT_EQ (loc, EXPR_LOCATION (wrapped_int_var)); + ASSERT_EQ (int_var, tree_strip_any_location_wrapper (wrapped_int_var)); + + /* Verify that "reinterpret_cast(some_int_var)" is not a location + wrapper. */ + tree r_cast = build1 (NON_LVALUE_EXPR, integer_type_node, int_var); + ASSERT_FALSE (location_wrapper_p (r_cast)); + ASSERT_EQ (r_cast, tree_strip_any_location_wrapper (r_cast)); +} + /* Run all of the selftests within this file. */ void @@ -14445,6 +14527,7 @@ tree_c_tests () test_identifiers (); test_labels (); test_vector_cst_patterns (); + test_location_wrappers (); } } // namespace selftest diff --git a/gcc/tree.h b/gcc/tree.h index aedd48d..f347b13 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -483,6 +483,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define STRIP_USELESS_TYPE_CONVERSION(EXP) \ (EXP) = tree_ssa_strip_useless_type_conversions (EXP) +/* Remove any VIEW_CONVERT_EXPR or NON_LVALUE_EXPR that's purely + in use to provide a location_t. */ + +#define STRIP_ANY_LOCATION_WRAPPER(EXP) \ + (EXP) = tree_strip_any_location_wrapper (CONST_CAST_TREE (EXP)) + /* Nonzero if TYPE represents a vector type. */ #define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE) @@ -1180,6 +1186,8 @@ get_expr_source_range (tree expr) extern void protected_set_expr_location (tree, location_t); +extern tree maybe_wrap_with_location (tree, location_t); + /* In a TARGET_EXPR node. */ #define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0) #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1) @@ -3677,6 +3685,45 @@ id_equal (const char *str, const_tree id) return !strcmp (str, IDENTIFIER_POINTER (id)); } +/* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a + wrapper added to express a location_t on behalf of the node's child + (e.g. by maybe_wrap_with_location). */ + +#define EXPR_LOCATION_WRAPPER_P(NODE) \ + (TREE_CHECK2(NODE, NON_LVALUE_EXPR, VIEW_CONVERT_EXPR)->base.public_flag) + +/* Test if EXP is merely a wrapper node, added to express a location_t + on behalf of the node's child (e.g. by maybe_wrap_with_location). */ + +inline bool +location_wrapper_p (const_tree exp) +{ + /* A wrapper node has code NON_LVALUE_EXPR or VIEW_CONVERT_EXPR, and + the flag EXPR_LOCATION_WRAPPER_P is set. + It normally has the same type as its operand, but it can have a + different one if the type of the operand has changed (e.g. when + merging duplicate decls). + + NON_LVALUE_EXPR is used for wrapping constants, apart from STRING_CST. + VIEW_CONVERT_EXPR is used for wrapping non-constants and STRING_CST. */ + if ((TREE_CODE (exp) == NON_LVALUE_EXPR + || TREE_CODE (exp) == VIEW_CONVERT_EXPR) + && EXPR_LOCATION_WRAPPER_P (exp)) + return true; + return false; +} + +/* Implementation of STRIP_ANY_LOCATION_WRAPPER. */ + +inline tree +tree_strip_any_location_wrapper (tree exp) +{ + if (location_wrapper_p (exp)) + return TREE_OPERAND (exp, 0); + else + return exp; +} + #define error_mark_node global_trees[TI_ERROR_MARK] #define intQI_type_node global_trees[TI_INTQI_TYPE]