From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 67076 invoked by alias); 3 May 2016 11:27:17 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 67055 invoked by uid 89); 3 May 2016 11:27:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=30pm, sk:protect 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 03 May 2016 11:27:13 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A10B3455AC for ; Tue, 3 May 2016 11:27:11 +0000 (UTC) Received: from redhat.com (ovpn-204-17.brq.redhat.com [10.40.204.17]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u43BR8wD007016 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 3 May 2016 07:27:10 -0400 Date: Tue, 03 May 2016 11:27:00 -0000 From: Marek Polacek To: Jason Merrill Cc: GCC Patches Subject: Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756) Message-ID: <20160503112707.GH5348@redhat.com> References: <20160428155908.GQ28445@redhat.com> <5723BE3D.4070706@redhat.com> <20160502164149.GE5348@redhat.com> <57278FA6.90308@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <57278FA6.90308@redhat.com> User-Agent: Mutt/1.6.0 (2016-04-01) X-SW-Source: 2016-05/txt/msg00182.txt.bz2 On Mon, May 02, 2016 at 01:34:30PM -0400, Jason Merrill wrote: > On 05/02/2016 12:41 PM, Marek Polacek wrote: > > On Fri, Apr 29, 2016 at 04:04:13PM -0400, Jason Merrill wrote: > > > On 04/28/2016 11:59 AM, Marek Polacek wrote: > > > > 3) for the C++ FE I used a macro so that I don't have to change all the > > > > cxx_incomplete_type_error calls now, > > > > > > How about an inline overload, instead? > > > > I realized the macro was already there, but inline overloads should probably > > be preferred these days. So I used them instead. > > > > > It seems sad to discard the location information; could we pass it into > > > cxx_incomplete_type_diagnostic? > > > > I suppose I can, though it required another inline overload. I'm not sure > > if the patch will make the C++ diagnostics about incomplete types better, > > most likely not :/. > > +inline void > > +cxx_incomplete_type_diagnostic (const_tree value, const_tree type, > > + diagnostic_t diag_kind) > > +{ > > + cxx_incomplete_type_diagnostic (input_location, value, type, diag_kind); > > +} > > + > > ... > > > -cxx_incomplete_type_diagnostic (const_tree value, const_tree type, > > - diagnostic_t diag_kind) > > +cxx_incomplete_type_diagnostic (location_t loc, const_tree value, > > > > - location_t loc = EXPR_LOC_OR_LOC (value, input_location); > > Shouldn't we use EXPR_LOC_OR_LOC in the inline? That, I suppose, is a good idea ;). Thus: Bootstrapped/regtested on x86_64-linux, ok for trunk? 2016-05-03 Marek Polacek PR c/70756 * c-common.c (pointer_int_sum): Call size_in_bytes_loc instead of size_in_bytes and pass LOC to it. * c-decl.c (build_compound_literal): Pass LOC down to c_incomplete_type_error. * c-tree.h (require_complete_type): Adjust declaration. (c_incomplete_type_error): Likewise. * c-typeck.c (require_complete_type): Add location parameter, pass it down to c_incomplete_type_error. (c_incomplete_type_error): Add location parameter, pass it down to error_at. (build_component_ref): Pass location down to c_incomplete_type_error. (default_conversion): Pass location down to require_complete_type. (build_array_ref): Likewise. (build_function_call_vec): Likewise. (convert_arguments): Likewise. (build_unary_op): Likewise. (build_c_cast): Likewise. (build_modify_expr): Likewise. (convert_for_assignment): Likewise. (c_finish_omp_clauses): Likewise. * cp-tree.h (cxx_incomplete_type_error, cxx_incomplete_type_diagnostic): New inline overloads. * typeck2.c (cxx_incomplete_type_diagnostic, cxx_incomplete_type_error): Add location parameter. * langhooks-def.h (lhd_incomplete_type_error): Adjust declaration. * langhooks.c (lhd_incomplete_type_error): Add location parameter. * langhooks.h (incomplete_type_error): Likewise. * tree.c (size_in_bytes_loc): Renamed from size_in_bytes. Add location parameter, pass it down to incomplete_type_error. * tree.h (size_in_bytes): New inline overload. (size_in_bytes_loc): Renamed from size_in_bytes. * gcc.dg/pr70756.c: New test. diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c index d45bf1b..747d55d 100644 --- gcc/c-family/c-common.c +++ gcc/c-family/c-common.c @@ -4269,7 +4269,7 @@ pointer_int_sum (location_t loc, enum tree_code resultcode, size_exp = integer_one_node; } else - size_exp = size_in_bytes (TREE_TYPE (result_type)); + size_exp = size_in_bytes_loc (loc, TREE_TYPE (result_type)); /* We are manipulating pointer values, so we don't need to warn about relying on undefined signed overflow. We disable the diff --git gcc/c/c-decl.c gcc/c/c-decl.c index 7094efc..48fa65c 100644 --- gcc/c/c-decl.c +++ gcc/c/c-decl.c @@ -5112,7 +5112,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const) if (type == error_mark_node || !COMPLETE_TYPE_P (type)) { - c_incomplete_type_error (NULL_TREE, type); + c_incomplete_type_error (loc, NULL_TREE, type); return error_mark_node; } diff --git gcc/c/c-tree.h gcc/c/c-tree.h index 07d0f65..1201f42 100644 --- gcc/c/c-tree.h +++ gcc/c/c-tree.h @@ -588,13 +588,13 @@ extern tree c_last_sizeof_arg; extern struct c_switch *c_switch_stack; extern tree c_objc_common_truthvalue_conversion (location_t, tree); -extern tree require_complete_type (tree); +extern tree require_complete_type (location_t, tree); extern int same_translation_unit_p (const_tree, const_tree); extern int comptypes (tree, tree); extern int comptypes_check_different_types (tree, tree, bool *); extern bool c_vla_type_p (const_tree); extern bool c_mark_addressable (tree); -extern void c_incomplete_type_error (const_tree, const_tree); +extern void c_incomplete_type_error (location_t, const_tree, const_tree); extern tree c_type_promotes_to (tree); extern struct c_expr default_function_array_conversion (location_t, struct c_expr); diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 0fa9653..e6e13ca 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -183,11 +183,12 @@ struct tagged_tu_seen_cache { static const struct tagged_tu_seen_cache * tagged_tu_seen_base; static void free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *); -/* Do `exp = require_complete_type (exp);' to make sure exp - does not have an incomplete type. (That includes void types.) */ +/* Do `exp = require_complete_type (loc, exp);' to make sure exp + does not have an incomplete type. (That includes void types.) + LOC is the location of the use. */ tree -require_complete_type (tree value) +require_complete_type (location_t loc, tree value) { tree type = TREE_TYPE (value); @@ -198,23 +199,24 @@ require_complete_type (tree value) if (COMPLETE_TYPE_P (type)) return value; - c_incomplete_type_error (value, type); + c_incomplete_type_error (loc, value, type); return error_mark_node; } /* Print an error message for invalid use of an incomplete type. VALUE is the expression that was used (or 0 if that isn't known) - and TYPE is the type that was invalid. */ + and TYPE is the type that was invalid. LOC is the location for + the error. */ void -c_incomplete_type_error (const_tree value, const_tree type) +c_incomplete_type_error (location_t loc, const_tree value, const_tree type) { /* Avoid duplicate error message. */ if (TREE_CODE (type) == ERROR_MARK) return; if (value != 0 && (VAR_P (value) || TREE_CODE (value) == PARM_DECL)) - error ("%qD has an incomplete type %qT", value, type); + error_at (loc, "%qD has an incomplete type %qT", value, type); else { retry: @@ -228,7 +230,7 @@ c_incomplete_type_error (const_tree value, const_tree type) break; case VOID_TYPE: - error ("invalid use of void expression"); + error_at (loc, "invalid use of void expression"); return; case ARRAY_TYPE: @@ -236,13 +238,13 @@ c_incomplete_type_error (const_tree value, const_tree type) { if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL) { - error ("invalid use of flexible array member"); + error_at (loc, "invalid use of flexible array member"); return; } type = TREE_TYPE (type); goto retry; } - error ("invalid use of array with unspecified bounds"); + error_at (loc, "invalid use of array with unspecified bounds"); return; default: @@ -250,10 +252,10 @@ c_incomplete_type_error (const_tree value, const_tree type) } if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error ("invalid use of undefined type %qT", type); + error_at (loc, "invalid use of undefined type %qT", type); else /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error ("invalid use of incomplete typedef %qT", type); + error_at (loc, "invalid use of incomplete typedef %qT", type); } } @@ -2117,7 +2119,7 @@ default_conversion (tree exp) return error_mark_node; } - exp = require_complete_type (exp); + exp = require_complete_type (EXPR_LOC_OR_LOC (exp, input_location), exp); if (exp == error_mark_node) return error_mark_node; @@ -2334,7 +2336,7 @@ build_component_ref (location_t loc, tree datum, tree component) { if (!COMPLETE_TYPE_P (type)) { - c_incomplete_type_error (NULL_TREE, type); + c_incomplete_type_error (loc, NULL_TREE, type); return error_mark_node; } @@ -2642,7 +2644,7 @@ build_array_ref (location_t loc, tree array, tree index) in an inline function. Hope it doesn't break something else. */ | TREE_THIS_VOLATILE (array)); - ret = require_complete_type (rval); + ret = require_complete_type (loc, rval); protected_set_expr_location (ret, loc); if (non_lvalue) ret = non_lvalue_loc (loc, ret); @@ -3087,7 +3089,7 @@ build_function_call_vec (location_t loc, vec arg_loc, "function with qualified void return type called"); return result; } - return require_complete_type (result); + return require_complete_type (loc, result); } /* Like build_function_call_vec, but call also resolve_overloaded_builtin. */ @@ -3238,7 +3240,7 @@ convert_arguments (location_t loc, vec arg_loc, tree typelist, val = c_fully_fold (val, false, NULL); STRIP_TYPE_NOPS (val); - val = require_complete_type (val); + val = require_complete_type (ploc, val); if (type != 0) { @@ -4046,7 +4048,7 @@ build_unary_op (location_t location, arg = remove_c_maybe_const_expr (arg); if (code != ADDR_EXPR) - arg = require_complete_type (arg); + arg = require_complete_type (location, arg); typecode = TREE_CODE (TREE_TYPE (arg)); if (typecode == ERROR_MARK) @@ -5267,7 +5269,7 @@ build_c_cast (location_t loc, tree type, tree expr) if (!VOID_TYPE_P (type)) { - value = require_complete_type (value); + value = require_complete_type (loc, value); if (value == error_mark_node) return error_mark_node; } @@ -5537,7 +5539,7 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype, bool is_atomic_op; /* Types that aren't fully specified cannot be used in assignments. */ - lhs = require_complete_type (lhs); + lhs = require_complete_type (location, lhs); /* Avoid duplicate error messages from operands that had errors. */ if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK) @@ -6132,7 +6134,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type, error_at (location, "void value not ignored as it ought to be"); return error_mark_node; } - rhs = require_complete_type (rhs); + rhs = require_complete_type (location, rhs); if (rhs == error_mark_node) return error_mark_node; @@ -12547,7 +12549,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) t = OMP_CLAUSE_DECL (c); } - t = require_complete_type (t); + t = require_complete_type (OMP_CLAUSE_LOCATION (c), t); if (t == error_mark_node) { remove = true; @@ -13358,7 +13360,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (need_complete) { - t = require_complete_type (t); + t = require_complete_type (OMP_CLAUSE_LOCATION (c), t); if (t == error_mark_node) remove = true; } diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h index 6665355..6d29f8b 100644 --- gcc/cp/cp-tree.h +++ gcc/cp/cp-tree.h @@ -6726,11 +6726,24 @@ extern tree finish_binary_fold_expr (tree, tree, int); /* in typeck2.c */ extern void require_complete_eh_spec_types (tree, tree); -extern void cxx_incomplete_type_diagnostic (const_tree, const_tree, diagnostic_t); -#undef cxx_incomplete_type_error -extern void cxx_incomplete_type_error (const_tree, const_tree); -#define cxx_incomplete_type_error(V,T) \ - (cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR)) +extern void cxx_incomplete_type_diagnostic (location_t, const_tree, + const_tree, diagnostic_t); +inline void +cxx_incomplete_type_diagnostic (const_tree value, const_tree type, + diagnostic_t diag_kind) +{ + cxx_incomplete_type_diagnostic (EXPR_LOC_OR_LOC (value, input_location), + value, type, diag_kind); +} + +extern void cxx_incomplete_type_error (location_t, const_tree, + const_tree); +inline void +cxx_incomplete_type_error (const_tree value, const_tree type) +{ + cxx_incomplete_type_diagnostic (value, type, DK_ERROR); +} + extern void cxx_incomplete_type_inform (const_tree); extern tree error_not_base_type (tree, tree); extern tree binfo_or_else (tree, tree); diff --git gcc/cp/typeck2.c gcc/cp/typeck2.c index e59ad51..1c4e832 100644 --- gcc/cp/typeck2.c +++ gcc/cp/typeck2.c @@ -451,8 +451,8 @@ cxx_incomplete_type_inform (const_tree type) type of diagnostic (see diagnostic.def). */ void -cxx_incomplete_type_diagnostic (const_tree value, const_tree type, - diagnostic_t diag_kind) +cxx_incomplete_type_diagnostic (location_t loc, const_tree value, + const_tree type, diagnostic_t diag_kind) { bool is_decl = false, complained = false; @@ -475,8 +475,6 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, retry: /* We must print an error message. Be clever about what it says. */ - location_t loc = EXPR_LOC_OR_LOC (value, input_location); - switch (TREE_CODE (type)) { case RECORD_TYPE: @@ -570,13 +568,14 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type, } } -/* Backward-compatibility interface to incomplete_type_diagnostic; - required by ../tree.c. */ -#undef cxx_incomplete_type_error +/* Print an error message for invalid use of an incomplete type. + VALUE is the expression that was used (or 0 if that isn't known) + and TYPE is the type that was invalid. */ + void -cxx_incomplete_type_error (const_tree value, const_tree type) +cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type) { - cxx_incomplete_type_diagnostic (value, type, DK_ERROR); + cxx_incomplete_type_diagnostic (loc, value, type, DK_ERROR); } diff --git gcc/langhooks-def.h gcc/langhooks-def.h index a2566ec..034b3b7 100644 --- gcc/langhooks-def.h +++ gcc/langhooks-def.h @@ -52,7 +52,7 @@ extern void lhd_print_error_function (diagnostic_context *, const char *, struct diagnostic_info *); extern void lhd_set_decl_assembler_name (tree); extern bool lhd_warn_unused_global_decl (const_tree); -extern void lhd_incomplete_type_error (const_tree, const_tree); +extern void lhd_incomplete_type_error (location_t, const_tree, const_tree); extern tree lhd_type_promotes_to (tree); extern void lhd_register_builtin_type (tree, const char *); extern bool lhd_decl_ok_for_sibcall (const_tree); diff --git gcc/langhooks.c gcc/langhooks.c index 7c07175..6444631 100644 --- gcc/langhooks.c +++ gcc/langhooks.c @@ -199,7 +199,8 @@ lhd_register_builtin_type (tree ARG_UNUSED (type), /* Invalid use of an incomplete type. */ void -lhd_incomplete_type_error (const_tree ARG_UNUSED (value), const_tree type) +lhd_incomplete_type_error (location_t ARG_UNUSED (loc), + const_tree ARG_UNUSED (value), const_tree type) { gcc_assert (TREE_CODE (type) == ERROR_MARK); return; diff --git gcc/langhooks.h gcc/langhooks.h index bcfd389..0593424 100644 --- gcc/langhooks.h +++ gcc/langhooks.h @@ -100,8 +100,9 @@ struct lang_hooks_for_types /* This routine is called in tree.c to print an error message for invalid use of an incomplete type. VALUE is the expression that was used (or 0 if that isn't known) and TYPE is the type that was - invalid. */ - void (*incomplete_type_error) (const_tree value, const_tree type); + invalid. LOC is the location of the use. */ + void (*incomplete_type_error) (location_t loc, const_tree value, + const_tree type); /* Called from assign_temp to return the maximum size, if there is one, for a type. */ diff --git gcc/testsuite/gcc.dg/pr70756.c gcc/testsuite/gcc.dg/pr70756.c index e69de29..e867832 100644 --- gcc/testsuite/gcc.dg/pr70756.c +++ gcc/testsuite/gcc.dg/pr70756.c @@ -0,0 +1,23 @@ +/* PR c/70756 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +enum E e; /* { dg-error "storage size" } */ +int (*A)[]; + +void +fn0 (void) +{ + struct + { + int x; + int y[]; + } s; + 1234 && &s.y + 1; /* { dg-error "16:invalid use of flexible array member" } */ +} + +void +fn1 (void) +{ + 1234, A += 1; /* { dg-error "11:invalid use of array with unspecified bounds" } */ +} diff --git gcc/tree.c gcc/tree.c index ebec112..ae773de 100644 --- gcc/tree.c +++ gcc/tree.c @@ -2939,7 +2939,7 @@ ctor_to_vec (tree ctor) make_unsigned_type). */ tree -size_in_bytes (const_tree type) +size_in_bytes_loc (location_t loc, const_tree type) { tree t; @@ -2951,7 +2951,7 @@ size_in_bytes (const_tree type) if (t == 0) { - lang_hooks.types.incomplete_type_error (NULL_TREE, type); + lang_hooks.types.incomplete_type_error (loc, NULL_TREE, type); return size_zero_node; } diff --git gcc/tree.h gcc/tree.h index 6e52e3d..37324bf 100644 --- gcc/tree.h +++ gcc/tree.h @@ -4224,7 +4224,13 @@ extern tree type_hash_canon (unsigned int, tree); extern tree convert (tree, tree); extern unsigned int expr_align (const_tree); -extern tree size_in_bytes (const_tree); +extern tree size_in_bytes_loc (location_t, const_tree); +inline tree +size_in_bytes (const_tree t) +{ + return size_in_bytes_loc (input_location, t); +} + extern HOST_WIDE_INT int_size_in_bytes (const_tree); extern HOST_WIDE_INT max_int_size_in_bytes (const_tree); extern tree bit_position (const_tree); Marek