From: Marek Polacek <polacek@redhat.com>
To: Jason Merrill <jason@redhat.com>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
Date: Tue, 03 May 2016 11:27:00 -0000 [thread overview]
Message-ID: <20160503112707.GH5348@redhat.com> (raw)
In-Reply-To: <57278FA6.90308@redhat.com>
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 <polacek@redhat.com>
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<location_t> 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<location_t> 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);
}
\f
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
next prev parent reply other threads:[~2016-05-03 11:27 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-28 15:59 Marek Polacek
2016-04-29 20:04 ` Jason Merrill
2016-05-02 16:41 ` Marek Polacek
2016-05-02 17:34 ` Jason Merrill
2016-05-03 11:27 ` Marek Polacek [this message]
2016-05-04 0:05 ` Jason Merrill
2016-05-04 13:00 ` Marek Polacek
2016-05-04 15:53 ` Jason Merrill
2016-05-05 14:22 ` Marek Polacek
2016-05-12 10:37 ` Marek Polacek
2016-05-12 15:09 ` Jason Merrill
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160503112707.GH5348@redhat.com \
--to=polacek@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=jason@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).