From patchwork Mon Dec 16 23:06:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 1210889 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-516071-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=oracle.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="V4qDGhe2"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oracle.com header.i=@oracle.com header.b="XhdWqGNM"; 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 47cH2p2gphz9sR4 for ; Tue, 17 Dec 2019 10:06:40 +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:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=ve+rCMpXi93pCVBKOHoA17T/N+ElzKPHEPX0XKy+9uB+Afvpns snUr9hNIKdu4/jJxKLD64UoWa1UzQpk+jqMEmSpaxtRLYA3Ww+SBYftyL4BqDZY/ y4iNWixCHrQn/jTHRQzJnxUVroekup9P/1Z1i9uAVP/rYIy7ShhjIhgMU= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=O/t19pcUPjGPZFGy13eapzbAyxI=; b=V4qDGhe2c2oFJDOz9VKZ 87EP/LbyKXbD+s3PT75D/7DrrVkmx7nCfXoqzJz/0ofHttT6K5t2mpXGCOUZLPUa 1XsUbVTWOkcayRn3dL35gctA4gMeYP8rFqusaV10AgJz75IKnLwnnMO+mKhRaGOH +IDNz5SVOFsuT3i5LOXj4O4= Received: (qmail 100317 invoked by alias); 16 Dec 2019 23:06:32 -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 100309 invoked by uid 89); 16 Dec 2019 23:06:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-9.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=Under, 279371, cpp1z X-HELO: userp2120.oracle.com Received: from userp2120.oracle.com (HELO userp2120.oracle.com) (156.151.31.85) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 16 Dec 2019 23:06:26 +0000 Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xBGN46u2107113; Mon, 16 Dec 2019 23:06:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=to : cc : from : subject : message-id : date : mime-version : content-type; s=corp-2019-08-05; bh=DDgBc91kO4nygYXMHK5jHnPO331Xtw4FfDvZmPD7JbQ=; b=XhdWqGNM66E2du9RjdSbZzr86SUwHIBHF8qjaEORyO7TClRAP3BtNaVrdSnY3AD/19BO nObEpXqiSdyhrs9vg6CmHUcRD+K3vIbV1J5rCRblDffg+qX37KuBzgG8oqAgwF9zKW2Q dKgdp+wnEDAMdKzMSaqSICQPMJvhG4vIRdtfiyg8IVJ+lYRAgLUV1VcKPAYyKXY/L7eJ Hb+PWlDOxNWrAlSR2CwVlu4viJN3wLXOIxIbp3FX9v2aLiLuHYSVvMtYbS3bt2MOxpin TRUVOPLf8R8kwvVukqsVI36atNGiyrpIVM1ES2Xb5D6IZqv2OlRSJh1ADBdMMad6LK07 DQ== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2120.oracle.com with ESMTP id 2wvrcr2p6t-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 16 Dec 2019 23:06:24 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.27/8.16.0.27) with SMTP id xBGN4EA0172886; Mon, 16 Dec 2019 23:06:24 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userp3020.oracle.com with ESMTP id 2ww9vq3k2p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 16 Dec 2019 23:06:23 +0000 Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0121.oracle.com (8.14.4/8.13.8) with ESMTP id xBGN6L2b017052; Mon, 16 Dec 2019 23:06:22 GMT Received: from [192.168.1.4] (/79.56.109.108) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Mon, 16 Dec 2019 15:06:19 -0800 To: "gcc-patches@gcc.gnu.org" Cc: Jason Merrill From: Paolo Carlini Subject: [C++ Patch] Improve throw, sizeof, and alignof locations & more Message-ID: <496be035-3db4-a944-0e09-f207180a2fd4@oracle.com> Date: Tue, 17 Dec 2019 00:06:17 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.1 MIME-Version: 1.0 X-IsSubscribed: yes Hi, another batch of work. Primarily, more of the idea of moving up the construction of the compound location thus passing it to the cxx_sizeof_or_alignof* and build_throw functions to obtain better locations for all the diagnostics issued by the latter. During the work a few mildly interesting nits (eg, for sizeof and alignof we want to set whenever possible the location inside the cxx_* functions and that allows to avoid set_location in cp_parser_unary_expression, but minimally we have to pass it to the cp_expr constructor, otherwise plugin testcases badly fail; noticed that in cxx_sizeof_expr and cxx_alignof_expr having a single cp_expr_loc_or_input_loc on top actually implies better locations (4 testcases) because below, before the diagnostic calls, we have STRIP_ANY_LOCATION_WRAPPER uses; in fact I changed those cp_expr_loc_or_input_loc to cp_expr_loc_or_loc because for expressions we still want to try fetching the locations but we do have a meaningful fallback in the location argument of the function; in build_throw, an error should be an inform, because in such cases we already issued an error (tested in ctor1.C)) but nothing major. The below includes a few other minor changes, like two additional uses of DECL_SOURCE_LOCATION, cp_expr_loc_or_input_loc, removal of an unused function. Tested x86_64-linux. Thanks, Paolo. ////////////////////////////// /gcc/cp 2019-12-16 Paolo Carlini * typeck.c (cxx_sizeof_or_alignof_type): Add location_t parameter and use it throughout. (cxx_sizeof_expr): Likewise. (cxx_alignof_expr): Likewise. (cxx_sizeof_or_alignof_expr): Likewise. (cxx_alignas_expr): Update call. * decl.c (fold_sizeof_expr): Likewise. * pt.c (tsubst_copy): Likewise. (tsubst_copy_and_build): Likewise. * except.c (build_throw): Add location_t parameter and use it. (expand_end_catch_block): Update call. * parser.c (cp_parser_unary_expression): Update cxx_sizeof_or_alignof_type and cxx_sizeof_or_alignof_expr calls, pass the compound location. (cp_parser_throw_expression): Likewise pass the combined location to build_throw. * cp-tree.h: Update declarations. * semantics.c (finish_handler_parms): Use DECL_SOURCE_LOCATION. * decl2.c (check_classfn): Likewise. * except.c (is_admissible_throw_operand_or_catch_parameter): Exploit cp_expr_loc_or_input_loc in one place. * except.c (create_try_catch_expr): Remove, unused. /libcc1 2019-12-16 Paolo Carlini * libcp1plugin.cc (plugin_build_unary_expr): Update build_throw and cxx_sizeof_or_alignof_expr calls. (plugin_build_unary_type_expr): Likewise for cxx_sizeof_or_alignof_type. /gcc/testsuite 2019-12-16 Paolo Carlini * g++.dg/diagnostic/alignof2.C: New. * g++.dg/diagnostic/alignof3.C: Likewise. * g++.dg/diagnostic/incomplete-type-1.C: Likewise. * g++.dg/warn/Wcatch-value-3b.C: Likewise. * g++.dg/cpp0x/alignof3.C: Check location(s) too. * g++.dg/cpp1z/decomp-bitfield1.C: Likewise. * g++.dg/cpp1z/has-unique-obj-representations2.C: Likewise. * g++.dg/expr/sizeof3.C: Likewise. * g++.dg/ext/flexary6.C: Likewise. * g++.dg/ext/vla4.C: Likewise. * g++.dg/template/sizeof11.C: Likewise. * g++.dg/warn/Wcatch-value-1.C: Likewise. * g++.dg/warn/Wcatch-value-2.C: Likewise. * g++.dg/warn/Wcatch-value-3.C: Likewise. * g++.old-deja/g++.brendan/sizeof1.C: Likewise. * g++.old-deja/g++.brendan/sizeof3.C: Likewise. * g++.old-deja/g++.brendan/sizeof4.C: Likewise. * g++.old-deja/g++.eh/ctor1.C: Likewise. * g++.old-deja/g++.jason/ambig1.C: Likewise. * g++.old-deja/g++.other/sizeof4.C: Likewise. Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 279371) +++ gcc/cp/cp-tree.h (working copy) @@ -6657,7 +6657,7 @@ extern void init_exception_processing (void); extern tree expand_start_catch_block (tree); extern void expand_end_catch_block (void); extern tree build_exc_ptr (void); -extern tree build_throw (tree); +extern tree build_throw (location_t, tree); extern int nothrow_libfn_p (const_tree); extern void check_handlers (tree); extern tree finish_noexcept_expr (tree, tsubst_flags_t); @@ -6674,7 +6674,6 @@ extern tree begin_eh_spec_block (void); extern void finish_eh_spec_block (tree, tree); extern tree build_eh_type_type (tree); extern tree cp_protect_cleanup_actions (void); -extern tree create_try_catch_expr (tree, tree); extern tree template_parms_to_args (tree); extern tree template_parms_level_to_args (tree); extern tree generic_targs_for (tree); @@ -7487,8 +7486,10 @@ extern bool compparms (const_tree, const_tree); extern int comp_cv_qualification (const_tree, const_tree); extern int comp_cv_qualification (int, int); extern int comp_cv_qual_signature (tree, tree); -extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool); -extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool, bool); +extern tree cxx_sizeof_or_alignof_expr (location_t, tree, + enum tree_code, bool); +extern tree cxx_sizeof_or_alignof_type (location_t, tree, + enum tree_code, bool, bool); extern tree cxx_alignas_expr (tree); extern tree cxx_sizeof_nowarn (tree); extern tree is_bitfield_expr_with_lowered_type (const_tree); @@ -7603,7 +7604,7 @@ extern tree cp_build_binary_op (c extern tree build_x_vec_perm_expr (location_t, tree, tree, tree, tsubst_flags_t); -#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, false, true) +#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (input_location, T, SIZEOF_EXPR, false, true) extern tree build_simple_component_ref (tree, tree); extern tree build_ptrmemfunc_access_expr (tree, tree); extern tree build_address (tree); Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 279371) +++ gcc/cp/decl.c (working copy) @@ -10225,13 +10225,16 @@ fold_sizeof_expr (tree t) { tree r; if (SIZEOF_EXPR_TYPE_P (t)) - r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)), + r = cxx_sizeof_or_alignof_type (EXPR_LOCATION (t), + TREE_TYPE (TREE_OPERAND (t, 0)), SIZEOF_EXPR, false, false); else if (TYPE_P (TREE_OPERAND (t, 0))) - r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR, + r = cxx_sizeof_or_alignof_type (EXPR_LOCATION (t), + TREE_OPERAND (t, 0), SIZEOF_EXPR, false, false); else - r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR, + r = cxx_sizeof_or_alignof_expr (EXPR_LOCATION (t), + TREE_OPERAND (t, 0), SIZEOF_EXPR, false); if (r == error_mark_node) r = size_one_node; Index: gcc/cp/decl2.c =================================================================== --- gcc/cp/decl2.c (revision 279371) +++ gcc/cp/decl2.c (working copy) @@ -698,7 +698,8 @@ check_classfn (tree ctype, tree function, tree tem if (!matched) { if (!COMPLETE_TYPE_P (ctype)) - cxx_incomplete_type_error (function, ctype); + cxx_incomplete_type_error (DECL_SOURCE_LOCATION (function), + function, ctype); else { if (DECL_CONV_FN_P (function)) Index: gcc/cp/except.c =================================================================== --- gcc/cp/except.c (revision 279371) +++ gcc/cp/except.c (working copy) @@ -507,7 +507,7 @@ expand_end_catch_block (void) && (DECL_CONSTRUCTOR_P (current_function_decl) || DECL_DESTRUCTOR_P (current_function_decl))) { - tree rethrow = build_throw (NULL_TREE); + tree rethrow = build_throw (input_location, NULL_TREE); TREE_NO_WARNING (rethrow) = true; finish_expr_stmt (rethrow); } @@ -627,7 +627,7 @@ wrap_cleanups_r (tree *tp, int *walk_subtrees, voi /* Build a throw expression. */ tree -build_throw (tree exp) +build_throw (location_t loc, tree exp) { if (exp == error_mark_node) return exp; @@ -637,12 +637,13 @@ tree if (cfun) current_function_returns_abnormally = 1; exp = build_min (THROW_EXPR, void_type_node, exp); - SET_EXPR_LOCATION (exp, input_location); + SET_EXPR_LOCATION (exp, loc); return exp; } if (exp && null_node_p (exp)) - warning (0, "throwing NULL, which has integral, not pointer type"); + warning_at (loc, 0, + "throwing NULL, which has integral, not pointer type"); if (exp != NULL_TREE) { @@ -758,6 +759,7 @@ tree { int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING; bool converted = false; + location_t exp_loc = cp_expr_loc_or_loc (exp, loc); /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes treated as an rvalue for the purposes of overload resolution @@ -790,7 +792,7 @@ tree if (exp == error_mark_node) { - error (" in thrown expression"); + inform (exp_loc, " in thrown expression"); return error_mark_node; } } @@ -867,8 +869,7 @@ tree exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error); } - exp = build1 (THROW_EXPR, void_type_node, exp); - SET_EXPR_LOCATION (exp, input_location); + exp = build1_loc (loc, THROW_EXPR, void_type_node, exp); return exp; } @@ -948,8 +949,9 @@ is_admissible_throw_operand_or_catch_parameter (tr else if (variably_modified_type_p (type, NULL_TREE)) { if (is_throw) - error ("cannot throw expression of type %qT because it involves " - "types of variable size", type); + error_at (cp_expr_loc_or_input_loc (expr), + "cannot throw expression of type %qT because it involves " + "types of variable size", type); else error ("cannot catch type %qT because it involves types of " "variable size", type); @@ -1321,22 +1323,4 @@ build_noexcept_spec (tree expr, tsubst_flags_t com } } -/* Returns a TRY_CATCH_EXPR that will put TRY_LIST and CATCH_LIST in the - TRY and CATCH locations. CATCH_LIST must be a STATEMENT_LIST */ - -tree -create_try_catch_expr (tree try_expr, tree catch_list) -{ - location_t loc = EXPR_LOCATION (try_expr); - - append_to_statement_list (do_begin_catch (), &catch_list); - append_to_statement_list (build_throw (NULL_TREE), &catch_list); - tree catch_tf_expr = build_stmt (loc, TRY_FINALLY_EXPR, catch_list, - do_end_catch (NULL_TREE)); - catch_list = build2 (CATCH_EXPR, void_type_node, NULL_TREE, - catch_tf_expr); - tree try_catch_expr = build_stmt (loc, TRY_CATCH_EXPR, try_expr, catch_list); - return try_catch_expr; -} - #include "gt-cp-except.h" Index: gcc/cp/parser.c =================================================================== --- gcc/cp/parser.c (revision 279371) +++ gcc/cp/parser.c (working copy) @@ -8169,9 +8169,17 @@ cp_parser_unary_expression (cp_parser *parser, cp_ /* Parse the operand. */ operand = cp_parser_sizeof_operand (parser, keyword); + /* Construct a location e.g. : + alignof (expr) + ^~~~~~~~~~~~~~ + with start == caret at the start of the "alignof"/"sizeof" + token, with the endpoint at the final closing paren. */ + location_t compound_loc + = make_location (start_loc, start_loc, parser->lexer); + if (TYPE_P (operand)) - ret = cxx_sizeof_or_alignof_type (operand, op, std_alignof, - true); + ret = cxx_sizeof_or_alignof_type (compound_loc, operand, op, + std_alignof, true); else { /* ISO C++ defines alignof only with types, not with @@ -8182,7 +8190,8 @@ cp_parser_unary_expression (cp_parser *parser, cp_ "ISO C++ does not allow % " "with a non-type"); - ret = cxx_sizeof_or_alignof_expr (operand, op, true); + ret = cxx_sizeof_or_alignof_expr (compound_loc, + operand, op, true); } /* For SIZEOF_EXPR, just issue diagnostics, but keep SIZEOF_EXPR with the original operand. */ @@ -8201,19 +8210,11 @@ cp_parser_unary_expression (cp_parser *parser, cp_ ret = build_min (SIZEOF_EXPR, size_type_node, operand); TREE_SIDE_EFFECTS (ret) = 0; TREE_READONLY (ret) = 1; + SET_EXPR_LOCATION (ret, compound_loc); } } - /* Construct a location e.g. : - alignof (expr) - ^~~~~~~~~~~~~~ - with start == caret at the start of the "alignof"/"sizeof" - token, with the endpoint at the final closing paren. */ - location_t compound_loc - = make_location (start_loc, start_loc, parser->lexer); - - cp_expr ret_expr (ret); - ret_expr.set_location (compound_loc); + cp_expr ret_expr (ret, compound_loc); ret_expr = ret_expr.maybe_add_location_wrapper (); return ret_expr; } @@ -26045,8 +26046,7 @@ cp_parser_throw_expression (cp_parser* parser) the end at the end of the final token we consumed. */ location_t combined_loc = make_location (start_loc, start_loc, parser->lexer); - expression = build_throw (expression); - protected_set_expr_location (expression, combined_loc); + expression = build_throw (combined_loc, expression); return expression; } Index: gcc/cp/pt.c =================================================================== --- gcc/cp/pt.c (revision 279371) +++ gcc/cp/pt.c (working copy) @@ -16395,11 +16395,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t com expanded = make_argument_pack (expanded); if (TYPE_P (expanded)) - return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR, + return cxx_sizeof_or_alignof_type (input_location, + expanded, SIZEOF_EXPR, false, complain & tf_error); else - return cxx_sizeof_or_alignof_expr (expanded, SIZEOF_EXPR, + return cxx_sizeof_or_alignof_expr (input_location, + expanded, SIZEOF_EXPR, complain & tf_error); } else @@ -19189,10 +19191,12 @@ tsubst_copy_and_build (tree t, --c_inhibit_evaluation_warnings; } if (TYPE_P (op1)) - r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), std_alignof, + r = cxx_sizeof_or_alignof_type (input_location, + op1, TREE_CODE (t), std_alignof, complain & tf_error); else - r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t), + r = cxx_sizeof_or_alignof_expr (input_location, + op1, TREE_CODE (t), complain & tf_error); if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node) { @@ -19954,7 +19958,7 @@ tsubst_copy_and_build (tree t, case THROW_EXPR: RETURN (build_throw - (RECUR (TREE_OPERAND (t, 0)))); + (input_location, RECUR (TREE_OPERAND (t, 0)))); case CONSTRUCTOR: { Index: gcc/cp/semantics.c =================================================================== --- gcc/cp/semantics.c (revision 279371) +++ gcc/cp/semantics.c (working copy) @@ -1429,15 +1429,19 @@ finish_handler_parms (tree decl, tree handler) if (CLASS_TYPE_P (orig_type)) { if (TYPE_POLYMORPHIC_P (orig_type)) - warning (OPT_Wcatch_value_, - "catching polymorphic type %q#T by value", orig_type); + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wcatch_value_, + "catching polymorphic type %q#T by value", + orig_type); else if (warn_catch_value > 1) - warning (OPT_Wcatch_value_, - "catching type %q#T by value", orig_type); + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wcatch_value_, + "catching type %q#T by value", orig_type); } else if (warn_catch_value > 2) - warning (OPT_Wcatch_value_, - "catching non-reference type %q#T", orig_type); + warning_at (DECL_SOURCE_LOCATION (decl), + OPT_Wcatch_value_, + "catching non-reference type %q#T", orig_type); } } HANDLER_TYPE (handler) = type; Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 279371) +++ gcc/cp/typeck.c (working copy) @@ -1663,8 +1663,8 @@ compparms (const_tree parms1, const_tree parms2) SIZEOF_EXPR. */ tree -cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool std_alignof, - bool complain) +cxx_sizeof_or_alignof_type (location_t loc, tree type, enum tree_code op, + bool std_alignof, bool complain) { gcc_assert (op == SIZEOF_EXPR || op == ALIGNOF_EXPR); if (type == error_mark_node) @@ -1675,7 +1675,7 @@ tree { if (complain) { - pedwarn (input_location, OPT_Wpointer_arith, + pedwarn (loc, OPT_Wpointer_arith, "invalid application of %qs to a member function", OVL_OP_INFO (false, op)->name); return size_one_node; @@ -1702,10 +1702,11 @@ tree TREE_READONLY (value) = 1; if (op == ALIGNOF_EXPR && std_alignof) ALIGNOF_EXPR_STD_P (value) = true; + SET_EXPR_LOCATION (value, loc); return value; } - return c_sizeof_or_alignof_type (input_location, complete_type (type), + return c_sizeof_or_alignof_type (loc, complete_type (type), op == SIZEOF_EXPR, std_alignof, complain); } @@ -1724,13 +1725,14 @@ cxx_sizeof_nowarn (tree type) else if (!COMPLETE_TYPE_P (type)) return size_zero_node; else - return cxx_sizeof_or_alignof_type (type, SIZEOF_EXPR, false, false); + return cxx_sizeof_or_alignof_type (input_location, type, + SIZEOF_EXPR, false, false); } /* Process a sizeof expression where the operand is an expression. */ static tree -cxx_sizeof_expr (tree e, tsubst_flags_t complain) +cxx_sizeof_expr (location_t loc, tree e, tsubst_flags_t complain) { if (e == error_mark_node) return error_mark_node; @@ -1740,10 +1742,12 @@ static tree e = build_min (SIZEOF_EXPR, size_type_node, e); TREE_SIDE_EFFECTS (e) = 0; TREE_READONLY (e) = 1; + SET_EXPR_LOCATION (e, loc); return e; } + location_t e_loc = cp_expr_loc_or_loc (e, loc); STRIP_ANY_LOCATION_WRAPPER (e); /* To get the size of a static data member declared as an array of @@ -1758,8 +1762,9 @@ static tree && (complain & tf_warning)) { auto_diagnostic_group d; - if (warning (OPT_Wsizeof_array_argument, "% on array function " - "parameter %qE will return size of %qT", e, TREE_TYPE (e))) + if (warning_at (e_loc, OPT_Wsizeof_array_argument, + "% on array function parameter %qE " + "will return size of %qT", e, TREE_TYPE (e))) inform (DECL_SOURCE_LOCATION (e), "declared here"); } @@ -1768,7 +1773,7 @@ static tree if (bitfield_p (e)) { if (complain & tf_error) - error_at (cp_expr_loc_or_input_loc (e), + error_at (e_loc, "invalid application of % to a bit-field"); else return error_mark_node; @@ -1777,9 +1782,8 @@ static tree else if (is_overloaded_fn (e)) { if (complain & tf_error) - permerror (cp_expr_loc_or_input_loc (e), - "ISO C++ forbids applying % to an expression " - "of function type"); + permerror (e_loc, "ISO C++ forbids applying % to " + "an expression of function type"); else return error_mark_node; e = char_type_node; @@ -1787,7 +1791,7 @@ static tree else if (type_unknown_p (e)) { if (complain & tf_error) - cxx_incomplete_type_error (e, TREE_TYPE (e)); + cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e)); else return error_mark_node; e = char_type_node; @@ -1795,7 +1799,8 @@ static tree else e = TREE_TYPE (e); - return cxx_sizeof_or_alignof_type (e, SIZEOF_EXPR, false, complain & tf_error); + return cxx_sizeof_or_alignof_type (loc, e, SIZEOF_EXPR, false, + complain & tf_error); } /* Implement the __alignof keyword: Return the minimum required @@ -1804,7 +1809,7 @@ static tree "aligned" __attribute__ specification). */ static tree -cxx_alignof_expr (tree e, tsubst_flags_t complain) +cxx_alignof_expr (location_t loc, tree e, tsubst_flags_t complain) { tree t; @@ -1816,15 +1821,17 @@ static tree e = build_min (ALIGNOF_EXPR, size_type_node, e); TREE_SIDE_EFFECTS (e) = 0; TREE_READONLY (e) = 1; + SET_EXPR_LOCATION (e, loc); return e; } + location_t e_loc = cp_expr_loc_or_loc (e, loc); STRIP_ANY_LOCATION_WRAPPER (e); e = mark_type_use (e); - if (!verify_type_context (input_location, TCTX_ALIGNOF, TREE_TYPE (e), + if (!verify_type_context (loc, TCTX_ALIGNOF, TREE_TYPE (e), !(complain & tf_error))) { if (!(complain & tf_error)) @@ -1836,7 +1843,7 @@ static tree else if (bitfield_p (e)) { if (complain & tf_error) - error_at (cp_expr_loc_or_input_loc (e), + error_at (e_loc, "invalid application of %<__alignof%> to a bit-field"); else return error_mark_node; @@ -1848,9 +1855,8 @@ static tree else if (is_overloaded_fn (e)) { if (complain & tf_error) - permerror (cp_expr_loc_or_input_loc (e), - "ISO C++ forbids applying %<__alignof%> to an expression " - "of function type"); + permerror (e_loc, "ISO C++ forbids applying %<__alignof%> to " + "an expression of function type"); else return error_mark_node; if (TREE_CODE (e) == FUNCTION_DECL) @@ -1861,16 +1867,17 @@ static tree else if (type_unknown_p (e)) { if (complain & tf_error) - cxx_incomplete_type_error (e, TREE_TYPE (e)); + cxx_incomplete_type_error (e_loc, e, TREE_TYPE (e)); else return error_mark_node; t = size_one_node; } else - return cxx_sizeof_or_alignof_type (TREE_TYPE (e), ALIGNOF_EXPR, false, + return cxx_sizeof_or_alignof_type (loc, TREE_TYPE (e), + ALIGNOF_EXPR, false, complain & tf_error); - return fold_convert (size_type_node, t); + return fold_convert_loc (loc, size_type_node, t); } /* Process a sizeof or alignof expression E with code OP where the operand @@ -1877,12 +1884,13 @@ static tree is an expression. */ tree -cxx_sizeof_or_alignof_expr (tree e, enum tree_code op, bool complain) +cxx_sizeof_or_alignof_expr (location_t loc, tree e, enum tree_code op, + bool complain) { if (op == SIZEOF_EXPR) - return cxx_sizeof_expr (e, complain? tf_warning_or_error : tf_none); + return cxx_sizeof_expr (loc, e, complain? tf_warning_or_error : tf_none); else - return cxx_alignof_expr (e, complain? tf_warning_or_error : tf_none); + return cxx_alignof_expr (loc, e, complain? tf_warning_or_error : tf_none); } /* Build a representation of an expression 'alignas(E).' Return the @@ -1906,7 +1914,8 @@ cxx_alignas_expr (tree e) alignas(type-id ), it shall have the same effect as alignas(alignof(type-id )). */ - return cxx_sizeof_or_alignof_type (e, ALIGNOF_EXPR, true, false); + return cxx_sizeof_or_alignof_type (input_location, + e, ALIGNOF_EXPR, true, false); /* If we reach this point, it means the alignas expression if of the form "alignas(assignment-expression)", so we should follow Index: gcc/testsuite/g++.dg/cpp0x/alignof3.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/alignof3.C (revision 279371) +++ gcc/testsuite/g++.dg/cpp0x/alignof3.C (working copy) @@ -2,5 +2,5 @@ // { dg-options "-pedantic" } int main(void) { - alignof(void (void)); // { dg-warning "function type" } + alignof(void (void)); // { dg-warning "3:ISO C\\+\\+ does not permit .alignof. applied to a function type" } } Index: gcc/testsuite/g++.dg/cpp1z/decomp-bitfield1.C =================================================================== --- gcc/testsuite/g++.dg/cpp1z/decomp-bitfield1.C (revision 279371) +++ gcc/testsuite/g++.dg/cpp1z/decomp-bitfield1.C (working copy) @@ -15,5 +15,5 @@ void f() long &r = x; // { dg-error "bit" } &x; // { dg-error "bit" } - sizeof(x); // { dg-error "bit" } + sizeof(x); // { dg-error "10:invalid application of .sizeof. to a bit-field" } } Index: gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C =================================================================== --- gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C (revision 279371) +++ gcc/testsuite/g++.dg/cpp1z/has-unique-obj-representations2.C (working copy) @@ -1,6 +1,6 @@ struct S; -struct T { S t; }; // { dg-error "incomplete type" } -struct U { int u[sizeof (S)]; }; // { dg-error "incomplete type" } +struct T { S t; }; // { dg-error "14:field .t. has incomplete type" } +struct U { int u[sizeof (S)]; }; // { dg-error "18:invalid application of .sizeof. to incomplete type" } union V { char c; char d[]; }; // { dg-error "24:flexible array member in union" } bool a = __has_unique_object_representations (S); // { dg-error "incomplete type" } bool b = __has_unique_object_representations (T); Index: gcc/testsuite/g++.dg/diagnostic/alignof2.C =================================================================== --- gcc/testsuite/g++.dg/diagnostic/alignof2.C (nonexistent) +++ gcc/testsuite/g++.dg/diagnostic/alignof2.C (working copy) @@ -0,0 +1,2 @@ +void f(); +int i = __alignof(f); // { dg-error "19:ISO C\\+\\+ forbids applying .__alignof." } Index: gcc/testsuite/g++.dg/diagnostic/alignof3.C =================================================================== --- gcc/testsuite/g++.dg/diagnostic/alignof3.C (nonexistent) +++ gcc/testsuite/g++.dg/diagnostic/alignof3.C (working copy) @@ -0,0 +1,5 @@ +struct A { long i: 2; }; +void f() +{ + __alignof(A::i); // { dg-error "16:invalid application of .__alignof. to a bit-field" } +} Index: gcc/testsuite/g++.dg/diagnostic/incomplete-type-1.C =================================================================== --- gcc/testsuite/g++.dg/diagnostic/incomplete-type-1.C (nonexistent) +++ gcc/testsuite/g++.dg/diagnostic/incomplete-type-1.C (working copy) @@ -0,0 +1,2 @@ +template struct A; // { dg-message "27:declaration" } +template A::A(); // { dg-error "22:invalid use of incomplete type" } Index: gcc/testsuite/g++.dg/expr/sizeof3.C =================================================================== --- gcc/testsuite/g++.dg/expr/sizeof3.C (revision 279371) +++ gcc/testsuite/g++.dg/expr/sizeof3.C (working copy) @@ -1,4 +1,4 @@ // PR c++/15337 class CCC; -int main() { sizeof(CCC); return 0; } // { dg-error ".*CCC.*" } +int main() { sizeof(CCC); return 0; } // { dg-error "14:invalid application of .sizeof. to incomplete type .CCC." } Index: gcc/testsuite/g++.dg/ext/flexary6.C =================================================================== --- gcc/testsuite/g++.dg/ext/flexary6.C (revision 279371) +++ gcc/testsuite/g++.dg/ext/flexary6.C (working copy) @@ -9,7 +9,7 @@ struct A { int n; int a[]; enum { - e = sizeof a // { dg-error "invalid application of .sizeof. to incomplete type" } + e = sizeof a // { dg-error "9:invalid application of .sizeof. to incomplete type" } }; }; @@ -18,6 +18,6 @@ struct B { typedef int A[]; A a; enum { - e = sizeof a // { dg-error "invalid application of .sizeof. to incomplete type" } + e = sizeof a // { dg-error "9:invalid application of .sizeof. to incomplete type" } }; }; Index: gcc/testsuite/g++.dg/ext/vla4.C =================================================================== --- gcc/testsuite/g++.dg/ext/vla4.C (revision 279371) +++ gcc/testsuite/g++.dg/ext/vla4.C (working copy) @@ -6,7 +6,7 @@ void f(int i) { try { int a[i]; - throw &a; // { dg-error "int \\(\\*\\)\\\[i\\\]" } + throw &a; // { dg-error "11:cannot throw expression of type .int \\(\\*\\)\\\[i\\\]." } } catch (int (*)[i]) { // { dg-error "variable size" } } } Index: gcc/testsuite/g++.dg/template/sizeof11.C =================================================================== --- gcc/testsuite/g++.dg/template/sizeof11.C (revision 279371) +++ gcc/testsuite/g++.dg/template/sizeof11.C (working copy) @@ -9,6 +9,6 @@ template < int> void g() template < class T > struct B; template < int> void f() { - sizeof (B); // { dg-error "incomplete" } + sizeof (B); // { dg-error "3:invalid application of .sizeof. to incomplete type" } } Index: gcc/testsuite/g++.dg/warn/Wcatch-value-1.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wcatch-value-1.C (revision 279371) +++ gcc/testsuite/g++.dg/warn/Wcatch-value-1.C (working copy) @@ -10,8 +10,8 @@ void foo() try {} catch (D) {} catch (C) {} - catch (B) {} // { dg-warning "catching polymorphic type" } - catch (A) {} // { dg-warning "catching polymorphic type" } + catch (B) {} // { dg-warning "10:catching polymorphic type" } + catch (A) {} // { dg-warning "10:catching polymorphic type" } catch (A*) {} catch (int) {} @@ -27,7 +27,7 @@ void foo() template void foo1() { try {} - catch (T) {} // { dg-warning "catching polymorphic type" } + catch (T) {} // { dg-warning "10:catching polymorphic type" } } template void foo2() Index: gcc/testsuite/g++.dg/warn/Wcatch-value-2.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wcatch-value-2.C (revision 279371) +++ gcc/testsuite/g++.dg/warn/Wcatch-value-2.C (working copy) @@ -8,10 +8,10 @@ struct D : C {}; void foo() { try {} - catch (D) {} // { dg-warning "catching type" } - catch (C) {} // { dg-warning "catching type" } - catch (B) {} // { dg-warning "catching polymorphic type" } - catch (A) {} // { dg-warning "catching polymorphic type" } + catch (D) {} // { dg-warning "10:catching type" } + catch (C) {} // { dg-warning "10:catching type" } + catch (B) {} // { dg-warning "10:catching polymorphic type" } + catch (A) {} // { dg-warning "10:catching polymorphic type" } catch (A*) {} catch (int) {} @@ -27,7 +27,7 @@ void foo() template void foo1() { try {} - catch (T) {} // { dg-warning "catching" } + catch (T) {} // { dg-warning "10:catching" } } template void foo2() Index: gcc/testsuite/g++.dg/warn/Wcatch-value-3.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wcatch-value-3.C (revision 279371) +++ gcc/testsuite/g++.dg/warn/Wcatch-value-3.C (working copy) @@ -8,12 +8,12 @@ struct D : C {}; void foo() { try {} - catch (D) {} // { dg-warning "catching type" } - catch (C) {} // { dg-warning "catching type" } - catch (B) {} // { dg-warning "catching polymorphic type" } - catch (A) {} // { dg-warning "catching polymorphic type" } + catch (D) {} // { dg-warning "10:catching type" } + catch (C) {} // { dg-warning "10:catching type" } + catch (B) {} // { dg-warning "10:catching polymorphic type" } + catch (A) {} // { dg-warning "10:catching polymorphic type" } catch (A*) {} // { dg-warning "catching non-reference type" } - catch (int) {} // { dg-warning "catching non-reference type" } + catch (int) {} // { dg-warning "10:catching non-reference type" } try {} catch (D&) {} @@ -27,7 +27,7 @@ void foo() template void foo1() { try {} - catch (T) {} // { dg-warning "catching" } + catch (T) {} // { dg-warning "10:catching" } } template void foo2() Index: gcc/testsuite/g++.dg/warn/Wcatch-value-3b.C =================================================================== --- gcc/testsuite/g++.dg/warn/Wcatch-value-3b.C (nonexistent) +++ gcc/testsuite/g++.dg/warn/Wcatch-value-3b.C (working copy) @@ -0,0 +1,64 @@ +// { dg-options "-Wcatch-value=3" } + +struct A { virtual ~A() {} }; +struct B : A {}; +struct C {}; +struct D : C {}; + +void foo() +{ + try {} + catch (D d) {} // { dg-warning "12:catching type" } + catch (C c) {} // { dg-warning "12:catching type" } + catch (B b) {} // { dg-warning "12:catching polymorphic type" } + catch (A a) {} // { dg-warning "12:catching polymorphic type" } + catch (A* a) {} // { dg-warning "13:catching non-reference type" } + catch (int i) {} // { dg-warning "14:catching non-reference type" } + + try {} + catch (D& d) {} + catch (C& c) {} + catch (B& b) {} + catch (A& a) {} + catch (A* a) {} // { dg-warning "13:catching non-reference type" } + catch (int& i) {} +} + +template void foo1() +{ + try {} + catch (T t) {} // { dg-warning "12:catching" } +} + +template void foo2() +{ + try {} + catch (T* t) {} // { dg-warning "13:catching non-reference type" } + + try {} + catch (T&) {} + + try {} + catch (const T&) {} +} + +void bar() +{ + foo1(); + foo1(); + foo1(); + foo1(); + foo1(); + + foo1(); // { dg-message "required" } + foo1(); // { dg-message "required" } + foo1(); // { dg-message "required" } + foo1(); // { dg-message "required" } + foo1(); // { dg-message "required" } + + foo2(); // { dg-message "required" } + foo2(); // { dg-message "required" } + foo2(); // { dg-message "required" } + foo2(); // { dg-message "required" } + foo2(); // { dg-message "required" } +} Index: gcc/testsuite/g++.old-deja/g++.brendan/sizeof1.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.brendan/sizeof1.C (revision 279371) +++ gcc/testsuite/g++.old-deja/g++.brendan/sizeof1.C (working copy) @@ -9,7 +9,7 @@ int main() { // sizeof may not be applied to a function - int i = sizeof( f);// { dg-error "" } .* + int i = sizeof( f);// { dg-error "19:ISO C\\+\\+ forbids applying .sizeof." } .* return 0; } Index: gcc/testsuite/g++.old-deja/g++.brendan/sizeof3.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.brendan/sizeof3.C (revision 279371) +++ gcc/testsuite/g++.old-deja/g++.brendan/sizeof3.C (working copy) @@ -9,7 +9,7 @@ int main() { // sizeof may not be applied to an undefined class - int k = sizeof (bar);// { dg-error "" } .* + int k = sizeof (bar);// { dg-error "11:invalid application of .sizeof. to incomplete type" } .* return 0; } Index: gcc/testsuite/g++.old-deja/g++.brendan/sizeof4.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.brendan/sizeof4.C (revision 279371) +++ gcc/testsuite/g++.old-deja/g++.brendan/sizeof4.C (working copy) @@ -7,7 +7,7 @@ int main() { // sizeof may not be applied to the type void - int l = sizeof (void);// { dg-error "" } .* + int l = sizeof (void);// { dg-error "11:invalid application of .sizeof. to a void type" } .* return 0; } Index: gcc/testsuite/g++.old-deja/g++.eh/ctor1.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.eh/ctor1.C (revision 279371) +++ gcc/testsuite/g++.old-deja/g++.eh/ctor1.C (working copy) @@ -11,7 +11,7 @@ main () try { throw A(); // { dg-error "rvalue" "" { target c++14_down } } can't copy - // { dg-error "thrown expression" "expr" { target c++14_down } .-1 } + // { dg-message "13:thrown expression" "expr" { target c++14_down } .-1 } } catch (...) { } } Index: gcc/testsuite/g++.old-deja/g++.jason/ambig1.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.jason/ambig1.C (revision 279371) +++ gcc/testsuite/g++.old-deja/g++.jason/ambig1.C (working copy) @@ -3,5 +3,5 @@ // Testcase for ambiguity between functional cast and abstract declarator. // This ambiguity accounts for 6 of the r/r conflicts. -int i = sizeof (int ()); // { dg-error "" } sizeof applied to fn type +int i = sizeof (int ()); // { dg-error "9:invalid application of .sizeof. to a function type" } sizeof applied to fn type int j = sizeof (int () + 1); Index: gcc/testsuite/g++.old-deja/g++.other/sizeof4.C =================================================================== --- gcc/testsuite/g++.old-deja/g++.other/sizeof4.C (revision 279442) +++ gcc/testsuite/g++.old-deja/g++.other/sizeof4.C (working copy) @@ -17,21 +17,21 @@ void fn () {} int main (int argc, char **argv) { - sizeof (s); // { dg-error "" } incomplete - sizeof (0, s); // { dg-error "" } incomplete - sizeof (argc ? s : s); // { dg-error "" } incomplete + sizeof (s); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (0, s); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (argc ? s : s); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete - sizeof (arys); // { dg-error "" } incomplete - sizeof (0, arys); // { dg-error "" } incomplete - sizeof (argc ? arys : arys); // { dg-error "" } incomplete + sizeof (arys); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (0, arys); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (argc ? arys : arys); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete - sizeof (aryt); // { dg-error "" } incomplete - sizeof (0, aryt); // { dg-error "" } incomplete - sizeof (argc ? aryt : aryt); // { dg-error "" } incomplete + sizeof (aryt); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (0, aryt); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete + sizeof (argc ? aryt : aryt); // { dg-error "3:invalid application of .sizeof. to incomplete type" } incomplete - sizeof (fn); // { dg-error "" } cannot take size of function - sizeof (0, fn); // { dg-error "" } cannot take size of function - sizeof (argc ? fn : fn); // { dg-error "" } cannot take size of function + sizeof (fn); // { dg-error "11:ISO C\\+\\+ forbids applying .sizeof." } cannot take size of function + sizeof (0, fn); // { dg-error "3:invalid application of .sizeof. to a function type" } cannot take size of function + sizeof (argc ? fn : fn); // { dg-error "3:invalid application of .sizeof. to a function type" } cannot take size of function sizeof (&fn); // ok sizeof (0, &fn); // ok Index: libcc1/libcp1plugin.cc =================================================================== --- libcc1/libcp1plugin.cc (revision 279371) +++ libcc1/libcp1plugin.cc (working copy) @@ -2797,7 +2797,7 @@ plugin_build_unary_expr (cc1_plugin::connection *s break; case THROW_EXPR: - result = build_throw (op0); + result = build_throw (input_location, op0); break; case TYPEID_EXPR: @@ -2806,7 +2806,8 @@ plugin_build_unary_expr (cc1_plugin::connection *s case SIZEOF_EXPR: case ALIGNOF_EXPR: - result = cxx_sizeof_or_alignof_expr (op0, opcode, true); + result = cxx_sizeof_or_alignof_expr (input_location, + op0, opcode, true); break; case DELETE_EXPR: @@ -3048,7 +3049,8 @@ plugin_build_unary_type_expr (cc1_plugin::connecti default: /* Use the C++11 alignof semantics. */ - result = cxx_sizeof_or_alignof_type (type, opcode, true, true); + result = cxx_sizeof_or_alignof_type (input_location, type, + opcode, true, true); } if (template_dependent_p)