* [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
@ 2016-04-28 15:59 Marek Polacek
2016-04-29 20:04 ` Jason Merrill
0 siblings, 1 reply; 11+ messages in thread
From: Marek Polacek @ 2016-04-28 15:59 UTC (permalink / raw)
To: GCC Patches
The goal of this patch is to improve the location info for the "incomplete
type" error. Turned out this is isn't as trivial as it should be:
1) c_incomplete_type_error is a target hook, so I had to add the location
parameter to the other hooks, too,
2) I had to add the location parameter to size_in_bytes, too. I renamed
it to size_in_bytes_loc and defined a macro so I don't have to change
all the callsites,
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,
4) what with using EXPR_LOC_OR_LOC (exp, input_location), we sometimes
still produce imprecise location :(.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2016-04-28 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): Adjust declaration.
* typeck2.c (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): Define macro.
(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 c086dee..decbe8b 100644
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -4270,7 +4270,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 16e4250..d714ec2 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 4633182..d3a6c4c 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 58c2139..32fd504 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;
@@ -12548,7 +12550,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
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;
@@ -13359,7 +13361,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
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 4c548c9..2656edd 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -6726,7 +6726,8 @@ extern tree finish_binary_fold_expr (tree, tree, int);
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);
+extern void cxx_incomplete_type_error (location_t, const_tree,
+ const_tree);
#define cxx_incomplete_type_error(V,T) \
(cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
extern void cxx_incomplete_type_inform (const_tree);
diff --git gcc/cp/typeck2.c gcc/cp/typeck2.c
index e59ad51..b4d466d 100644
--- gcc/cp/typeck2.c
+++ gcc/cp/typeck2.c
@@ -574,7 +574,7 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
required by ../tree.c. */
#undef cxx_incomplete_type_error
void
-cxx_incomplete_type_error (const_tree value, const_tree type)
+cxx_incomplete_type_error (location_t, const_tree value, const_tree type)
{
cxx_incomplete_type_diagnostic (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 8692182..45c6498 100644
--- gcc/tree.c
+++ gcc/tree.c
@@ -2944,7 +2944,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;
@@ -2956,7 +2956,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 259a2bf..3bf47bf 100644
--- gcc/tree.h
+++ gcc/tree.h
@@ -4224,7 +4224,9 @@ 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);
+#define size_in_bytes(T)\
+ size_in_bytes_loc (input_location, T)
+extern tree size_in_bytes_loc (location_t, const_tree);
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-04-28 15:59 [PATCH] Better location info for "incomplete type" error msg (PR c/70756) Marek Polacek
@ 2016-04-29 20:04 ` Jason Merrill
2016-05-02 16:41 ` Marek Polacek
0 siblings, 1 reply; 11+ messages in thread
From: Jason Merrill @ 2016-04-29 20:04 UTC (permalink / raw)
To: Marek Polacek, GCC Patches
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?
It seems sad to discard the location information; could we pass it into
cxx_incomplete_type_diagnostic?
Jason
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-04-29 20:04 ` Jason Merrill
@ 2016-05-02 16:41 ` Marek Polacek
2016-05-02 17:34 ` Jason Merrill
0 siblings, 1 reply; 11+ messages in thread
From: Marek Polacek @ 2016-05-02 16:41 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
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 :/.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2016-05-02 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 4633182..d3a6c4c 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 58c2139..32fd504 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;
@@ -12548,7 +12550,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
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;
@@ -13359,7 +13361,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
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 8a06609..0a3f060 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -6727,11 +6727,23 @@ 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 (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 f7366f6..e1e4d63 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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-02 16:41 ` Marek Polacek
@ 2016-05-02 17:34 ` Jason Merrill
2016-05-03 11:27 ` Marek Polacek
0 siblings, 1 reply; 11+ messages in thread
From: Jason Merrill @ 2016-05-02 17:34 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
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?
Jason
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-02 17:34 ` Jason Merrill
@ 2016-05-03 11:27 ` Marek Polacek
2016-05-04 0:05 ` Jason Merrill
0 siblings, 1 reply; 11+ messages in thread
From: Marek Polacek @ 2016-05-03 11:27 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-03 11:27 ` Marek Polacek
@ 2016-05-04 0:05 ` Jason Merrill
2016-05-04 13:00 ` Marek Polacek
0 siblings, 1 reply; 11+ messages in thread
From: Jason Merrill @ 2016-05-04 0:05 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
On 05/03/2016 07:27 AM, Marek Polacek wrote:
> 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:
Looks good.
But I don't see a C++ testcase; can the test go into c-c++-common?
Jason
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-04 0:05 ` Jason Merrill
@ 2016-05-04 13:00 ` Marek Polacek
2016-05-04 15:53 ` Jason Merrill
0 siblings, 1 reply; 11+ messages in thread
From: Marek Polacek @ 2016-05-04 13:00 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
On Tue, May 03, 2016 at 08:05:47PM -0400, Jason Merrill wrote:
> Looks good.
>
> But I don't see a C++ testcase; can the test go into c-c++-common?
Sadly, no. As of now, the patch doesn't improve things for C++ (?). Seems
we'd need to pass better locations down to pointer_int_sum / size_in_bytes.
It cascades :(.
Marek
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-04 13:00 ` Marek Polacek
@ 2016-05-04 15:53 ` Jason Merrill
2016-05-05 14:22 ` Marek Polacek
0 siblings, 1 reply; 11+ messages in thread
From: Jason Merrill @ 2016-05-04 15:53 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
On Wed, May 4, 2016 at 9:00 AM, Marek Polacek <polacek@redhat.com> wrote:
> On Tue, May 03, 2016 at 08:05:47PM -0400, Jason Merrill wrote:
>> Looks good.
>>
>> But I don't see a C++ testcase; can the test go into c-c++-common?
>
> Sadly, no. As of now, the patch doesn't improve things for C++ (?). Seems
> we'd need to pass better locations down to pointer_int_sum / size_in_bytes.
> It cascades :(.
Sure. But can you fix that, too, while you're thinking about it?
Passing the location to cp_pointer_int_sum and pointer_diff seems
pretty simple.
Jason
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
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
0 siblings, 2 replies; 11+ messages in thread
From: Marek Polacek @ 2016-05-05 14:22 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
On Wed, May 04, 2016 at 11:52:39AM -0400, Jason Merrill wrote:
> On Wed, May 4, 2016 at 9:00 AM, Marek Polacek <polacek@redhat.com> wrote:
> > On Tue, May 03, 2016 at 08:05:47PM -0400, Jason Merrill wrote:
> >> Looks good.
> >>
> >> But I don't see a C++ testcase; can the test go into c-c++-common?
> >
> > Sadly, no. As of now, the patch doesn't improve things for C++ (?). Seems
> > we'd need to pass better locations down to pointer_int_sum / size_in_bytes.
> > It cascades :(.
>
> Sure. But can you fix that, too, while you're thinking about it?
> Passing the location to cp_pointer_int_sum and pointer_diff seems
> pretty simple.
That's true, that was pretty simple, actually. And while at it, I also
added a location parameter to cp_build_modify_expr. With that, we generate
better diagnostics even for C++, so I could move the test to c-c++-common.
And I also added another test, this time with -Wpointer-arith diagnostics,
which this patch improves as well.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2016-05-05 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.
* call.c (build_new_op_1): Pass LOC to cp_build_modify_expr.
* cp-tree.h (cp_build_modify_expr): Update declaration.
(cxx_incomplete_type_error, cxx_incomplete_type_diagnostic): New inline
overloads.
* cp-ubsan.c (cp_ubsan_dfs_initialize_vtbl_ptrs): Pass INPUT_LOCATION to
cp_build_modify_expr.
* decl2.c (set_guard): Likewise.
(handle_tls_init): Likewise.
* init.c (perform_member_init): Likewise.
(expand_virtual_init): Likewise.
(build_new_1): Likewise.
(build_vec_delete_1): Likewise.
(get_temp_regvar): Likewise.
(build_vec_init): Likewise.
* method.c (do_build_copy_assign): Likewise.
(assignable_expr): Likewise.
* semantics.c (finish_omp_for): Likewise.
* typeck.c (cp_build_binary_op): Pass LOCATION to pointer_diff and
cp_pointer_int_sum.
(cp_pointer_int_sum): Add location parameter. Pass it down to
pointer_int_sum.
(pointer_diff): Add location parameter. Use it.
(build_modify_expr): Pass location down to cp_build_modify_expr.
(cp_build_modify_expr): Add location parameter. Use it.
(build_x_modify_expr): Pass location down to cp_build_modify_expr.
* 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.
* c-c++-common/pr70756-2.c: New test.
* c-c++-common/pr70756.c: New test.
diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
index 63a18c8..150bdb2 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 861aa12..b037f46 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);
@@ -3088,7 +3090,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. */
@@ -3239,7 +3241,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)
{
@@ -4047,7 +4049,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)
@@ -5268,7 +5270,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;
}
@@ -5538,7 +5540,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)
@@ -6133,7 +6135,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;
@@ -12550,7 +12552,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;
@@ -13361,7 +13363,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/call.c gcc/cp/call.c
index e9ebdbc..a49bbb5 100644
--- gcc/cp/call.c
+++ gcc/cp/call.c
@@ -5757,7 +5757,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
switch (code)
{
case MODIFY_EXPR:
- return cp_build_modify_expr (arg1, code2, arg2, complain);
+ return cp_build_modify_expr (loc, arg1, code2, arg2, complain);
case INDIRECT_REF:
return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h
index 6665355..556c256 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -6666,7 +6666,8 @@ extern tree cp_build_c_cast (tree, tree, tsubst_flags_t);
extern cp_expr build_x_modify_expr (location_t, tree,
enum tree_code, tree,
tsubst_flags_t);
-extern tree cp_build_modify_expr (tree, enum tree_code, tree,
+extern tree cp_build_modify_expr (location_t, tree,
+ enum tree_code, tree,
tsubst_flags_t);
extern tree convert_for_initialization (tree, tree, tree, int,
impl_conv_rhs, tree, int,
@@ -6726,11 +6727,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/cp-ubsan.c gcc/cp/cp-ubsan.c
index be24a5c..9c8f6e6 100644
--- gcc/cp/cp-ubsan.c
+++ gcc/cp/cp-ubsan.c
@@ -299,8 +299,8 @@ cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
/* Assign NULL to the vptr. */
tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
- tree stmt = cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
- tf_warning_or_error);
+ tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
+ vtbl, tf_warning_or_error);
if (vptr_via_virtual_p (binfo))
/* If this vptr comes from a virtual base of the complete object, only
clear it if we're in charge of virtual bases. */
diff --git gcc/cp/decl2.c gcc/cp/decl2.c
index 0ea326d..22f9ede 100644
--- gcc/cp/decl2.c
+++ gcc/cp/decl2.c
@@ -3161,7 +3161,7 @@ set_guard (tree guard)
guard_init = integer_one_node;
if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
guard_init = fold_convert (TREE_TYPE (guard), guard_init);
- return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
+ return cp_build_modify_expr (input_location, guard, NOP_EXPR, guard_init,
tf_warning_or_error);
}
@@ -4346,7 +4346,8 @@ handle_tls_init (void)
tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
tf_warning_or_error);
finish_if_stmt_cond (cond, if_stmt);
- finish_expr_stmt (cp_build_modify_expr (guard, NOP_EXPR, boolean_true_node,
+ finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR,
+ boolean_true_node,
tf_warning_or_error));
for (; vars; vars = TREE_CHAIN (vars))
{
diff --git gcc/cp/init.c gcc/cp/init.c
index 681ca12..8e7541f 100644
--- gcc/cp/init.c
+++ gcc/cp/init.c
@@ -798,7 +798,8 @@ perform_member_init (tree member, tree init)
tf_warning_or_error);
if (init)
- finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+ finish_expr_stmt (cp_build_modify_expr (input_location, decl,
+ INIT_EXPR, init,
tf_warning_or_error));
}
@@ -1254,8 +1255,8 @@ expand_virtual_init (tree binfo, tree decl)
/* Assign the vtable to the vptr. */
vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
- finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
- tf_warning_or_error));
+ finish_expr_stmt (cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
+ vtbl, tf_warning_or_error));
}
/* If an exception is thrown in a constructor, those base classes already
@@ -3208,8 +3209,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
ie = build_x_compound_expr_from_vec (*init, "new initializer",
complain);
- init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
- complain);
+ init_expr = cp_build_modify_expr (input_location, init_expr,
+ INIT_EXPR, ie, complain);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
}
@@ -3596,7 +3597,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
tbase = create_temporary_var (ptype);
tbase_init
- = cp_build_modify_expr (tbase, NOP_EXPR,
+ = cp_build_modify_expr (input_location, tbase, NOP_EXPR,
fold_build_pointer_plus_loc (input_location,
fold_convert (ptype,
base),
@@ -3613,7 +3614,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
fold_convert (ptype, base)));
tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
tmp = fold_build_pointer_plus (tbase, tmp);
- tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
+ tmp = cp_build_modify_expr (input_location, tbase, NOP_EXPR, tmp, complain);
if (tmp == error_mark_node)
return error_mark_node;
body = build_compound_expr (input_location, body, tmp);
@@ -3735,8 +3736,8 @@ get_temp_regvar (tree type, tree init)
decl = create_temporary_var (type);
add_decl_expr (decl);
- finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
- tf_warning_or_error));
+ finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR,
+ init, tf_warning_or_error));
return decl;
}
@@ -4000,8 +4001,8 @@ build_vec_init (tree base, tree maxindex, tree init,
else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
one_init = build_aggr_init (baseref, elt, 0, complain);
else
- one_init = cp_build_modify_expr (baseref, NOP_EXPR,
- elt, complain);
+ one_init = cp_build_modify_expr (input_location, baseref,
+ NOP_EXPR, elt, complain);
if (one_init == error_mark_node)
errors = true;
if (try_const)
@@ -4128,12 +4129,12 @@ build_vec_init (tree base, tree maxindex, tree init,
from = NULL_TREE;
if (from_array == 2)
- elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
- complain);
+ elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
+ from, complain);
else if (type_build_ctor_call (type))
elt_init = build_aggr_init (to, from, 0, complain);
else if (from)
- elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
+ elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR, from,
complain);
else
gcc_unreachable ();
diff --git gcc/cp/method.c gcc/cp/method.c
index 0e501d9..310e7eb 100644
--- gcc/cp/method.c
+++ gcc/cp/method.c
@@ -741,7 +741,7 @@ do_build_copy_assign (tree fndecl)
init = move (init);
if (DECL_NAME (field))
- init = cp_build_modify_expr (comp, NOP_EXPR, init,
+ init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
tf_warning_or_error);
else
init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
@@ -1023,7 +1023,7 @@ assignable_expr (tree to, tree from)
++cp_unevaluated_operand;
to = build_stub_object (to);
from = build_stub_object (from);
- tree r = cp_build_modify_expr (to, NOP_EXPR, from, tf_none);
+ tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
--cp_unevaluated_operand;
return r;
}
diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index fed7e88..817ef99 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -8073,7 +8073,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
{
if (orig_incr)
TREE_VEC_ELT (orig_incr, i) = incr;
- incr = cp_build_modify_expr (TREE_OPERAND (incr, 0),
+ incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
TREE_CODE (TREE_OPERAND (incr, 1)),
TREE_OPERAND (incr, 2),
tf_warning_or_error);
@@ -8107,7 +8107,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
if (!processing_template_decl)
{
init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
- init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
+ init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
+ tf_warning_or_error);
}
else
init = build2 (MODIFY_EXPR, void_type_node, decl, init);
diff --git gcc/cp/typeck.c gcc/cp/typeck.c
index 95c777d..0d8a980 100644
--- gcc/cp/typeck.c
+++ gcc/cp/typeck.c
@@ -43,13 +43,14 @@ static tree pfn_from_ptrmemfunc (tree);
static tree delta_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
tsubst_flags_t, int);
-static tree cp_pointer_int_sum (enum tree_code, tree, tree, tsubst_flags_t);
+static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
+ tsubst_flags_t);
static tree rationalize_conditional_expr (enum tree_code, tree,
tsubst_flags_t);
static int comp_ptr_ttypes_real (tree, tree, int);
static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, bool);
-static tree pointer_diff (tree, tree, tree, tsubst_flags_t);
+static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t);
static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
static bool casts_away_constness (tree, tree, tsubst_flags_t);
@@ -4236,8 +4237,8 @@ cp_build_binary_op (location_t location,
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
TREE_TYPE (type1)))
- return pointer_diff (op0, op1, common_pointer_type (type0, type1),
- complain);
+ return pointer_diff (location, op0, op1,
+ common_pointer_type (type0, type1), complain);
/* In all other cases except pointer - int, the usual arithmetic
rules apply. */
else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
@@ -4260,8 +4261,8 @@ cp_build_binary_op (location_t location,
result_type = TREE_TYPE (ptr_operand);
break;
}
- return cp_pointer_int_sum (code,
- ptr_operand,
+ return cp_pointer_int_sum (location, code,
+ ptr_operand,
int_operand,
complain);
}
@@ -5226,8 +5227,8 @@ build_x_vec_perm_expr (location_t loc,
of pointer PTROP and integer INTOP. */
static tree
-cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
- tsubst_flags_t complain)
+cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
+ tree intop, tsubst_flags_t complain)
{
tree res_type = TREE_TYPE (ptrop);
@@ -5238,7 +5239,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
pointer_int_sum() anyway. */
complete_type (TREE_TYPE (res_type));
- return pointer_int_sum (input_location, resultcode, ptrop,
+ return pointer_int_sum (loc, resultcode, ptrop,
intop, complain & tf_warning_or_error);
}
@@ -5246,7 +5247,8 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
The resulting tree has type int. */
static tree
-pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
+pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
+ tsubst_flags_t complain)
{
tree result;
tree restype = ptrdiff_type_node;
@@ -5258,7 +5260,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (VOID_TYPE_P (target_type))
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer of "
+ permerror (loc, "ISO C++ forbids using pointer of "
"type %<void *%> in subtraction");
else
return error_mark_node;
@@ -5266,7 +5268,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (TREE_CODE (target_type) == FUNCTION_TYPE)
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer to "
+ permerror (loc, "ISO C++ forbids using pointer to "
"a function in subtraction");
else
return error_mark_node;
@@ -5274,7 +5276,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (TREE_CODE (target_type) == METHOD_TYPE)
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer to "
+ permerror (loc, "ISO C++ forbids using pointer to "
"a method in subtraction");
else
return error_mark_node;
@@ -5283,7 +5285,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
/* First do the subtraction as integers;
then drop through to build the divide operator. */
- op0 = cp_build_binary_op (input_location,
+ op0 = cp_build_binary_op (loc,
MINUS_EXPR,
cp_convert (restype, op0, complain),
cp_convert (restype, op1, complain),
@@ -5293,8 +5295,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
{
if (complain & tf_error)
- error ("invalid use of a pointer to an incomplete type in "
- "pointer arithmetic");
+ error_at (loc, "invalid use of a pointer to an incomplete type in "
+ "pointer arithmetic");
else
return error_mark_node;
}
@@ -5302,19 +5304,19 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
{
if (complain & tf_error)
- error ("arithmetic on pointer to an empty aggregate");
+ error_at (loc, "arithmetic on pointer to an empty aggregate");
else
return error_mark_node;
}
op1 = (TYPE_PTROB_P (ptrtype)
- ? size_in_bytes (target_type)
+ ? size_in_bytes_loc (loc, target_type)
: integer_one_node);
/* Do the division. */
- result = build2 (EXACT_DIV_EXPR, restype, op0,
- cp_convert (restype, op1, complain));
+ result = build2_loc (loc, EXACT_DIV_EXPR, restype, op0,
+ cp_convert (restype, op1, complain));
return result;
}
\f
@@ -7470,13 +7472,14 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
\f
/* For use from the C common bits. */
tree
-build_modify_expr (location_t /*location*/,
+build_modify_expr (location_t location,
tree lhs, tree /*lhs_origtype*/,
enum tree_code modifycode,
location_t /*rhs_location*/, tree rhs,
tree /*rhs_origtype*/)
{
- return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
+ return cp_build_modify_expr (location, lhs, modifycode, rhs,
+ tf_warning_or_error);
}
/* Build an assignment expression of lvalue LHS from value RHS.
@@ -7487,8 +7490,8 @@ build_modify_expr (location_t /*location*/,
C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */
tree
-cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
- tsubst_flags_t complain)
+cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
+ tree rhs, tsubst_flags_t complain)
{
tree result;
tree newrhs = rhs;
@@ -7510,7 +7513,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
TREE_OPERAND (lhs, 1));
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0),
modifycode, rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
@@ -7518,7 +7521,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
/* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR:
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
modifycode, rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
@@ -7530,8 +7533,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
TREE_OPERAND (lhs, 1));
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
- complain);
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0), modifycode,
+ rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
@@ -7580,9 +7583,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
cond = build_conditional_expr
(input_location, TREE_OPERAND (lhs, 0),
- cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
modifycode, rhs, complain),
- cp_build_modify_expr (TREE_OPERAND (lhs, 2),
+ cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
modifycode, rhs, complain),
complain);
@@ -7680,9 +7683,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = cp_stabilize_reference (lhs);
rhs = rvalue (rhs);
rhs = stabilize_expr (rhs, &init);
- newrhs = cp_build_binary_op (input_location,
- modifycode, lhs, rhs,
- complain);
+ newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
if (newrhs == error_mark_node)
{
if (complain & tf_error)
@@ -7893,7 +7894,7 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
return rval;
}
}
- return cp_build_modify_expr (lhs, modifycode, rhs, complain);
+ return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
}
/* Helper function for get_delta_difference which assumes FROM is a base
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/c-c++-common/pr70756-2.c gcc/testsuite/c-c++-common/pr70756-2.c
index e69de29..b7df3b7 100644
--- gcc/testsuite/c-c++-common/pr70756-2.c
+++ gcc/testsuite/c-c++-common/pr70756-2.c
@@ -0,0 +1,12 @@
+/* PR c/70756 */
+/* { dg-do compile } */
+/* { dg-options "-Wpointer-arith" } */
+
+extern void bar (void);
+
+void
+fn (void *p)
+{
+ void *a = p + 1; /* { dg-warning "15:pointer of type" } */
+ void (*a2)(void) = &bar + 1; /* { dg-warning "27:pointer to a function" } */
+}
diff --git gcc/testsuite/c-c++-common/pr70756.c gcc/testsuite/c-c++-common/pr70756.c
index e69de29..3725922 100644
--- gcc/testsuite/c-c++-common/pr70756.c
+++ gcc/testsuite/c-c++-common/pr70756.c
@@ -0,0 +1,23 @@
+/* PR c/70756 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+enum E e; /* { dg-error "storage size|use of enum" } */
+int (*A)[];
+
+void
+fn0 (void)
+{
+ struct
+ {
+ int x;
+ int y[];
+ } s;
+ 1234 && &s.y + 1; /* { dg-error "16:invalid use of" } */
+}
+
+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 c565337..b63f64c 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
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-05 14:22 ` Marek Polacek
@ 2016-05-12 10:37 ` Marek Polacek
2016-05-12 15:09 ` Jason Merrill
1 sibling, 0 replies; 11+ messages in thread
From: Marek Polacek @ 2016-05-12 10:37 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches
Ping.
On Thu, May 05, 2016 at 04:22:15PM +0200, Marek Polacek wrote:
> On Wed, May 04, 2016 at 11:52:39AM -0400, Jason Merrill wrote:
> > On Wed, May 4, 2016 at 9:00 AM, Marek Polacek <polacek@redhat.com> wrote:
> > > On Tue, May 03, 2016 at 08:05:47PM -0400, Jason Merrill wrote:
> > >> Looks good.
> > >>
> > >> But I don't see a C++ testcase; can the test go into c-c++-common?
> > >
> > > Sadly, no. As of now, the patch doesn't improve things for C++ (?). Seems
> > > we'd need to pass better locations down to pointer_int_sum / size_in_bytes.
> > > It cascades :(.
> >
> > Sure. But can you fix that, too, while you're thinking about it?
> > Passing the location to cp_pointer_int_sum and pointer_diff seems
> > pretty simple.
>
> That's true, that was pretty simple, actually. And while at it, I also
> added a location parameter to cp_build_modify_expr. With that, we generate
> better diagnostics even for C++, so I could move the test to c-c++-common.
> And I also added another test, this time with -Wpointer-arith diagnostics,
> which this patch improves as well.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2016-05-05 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.
>
> * call.c (build_new_op_1): Pass LOC to cp_build_modify_expr.
> * cp-tree.h (cp_build_modify_expr): Update declaration.
> (cxx_incomplete_type_error, cxx_incomplete_type_diagnostic): New inline
> overloads.
> * cp-ubsan.c (cp_ubsan_dfs_initialize_vtbl_ptrs): Pass INPUT_LOCATION to
> cp_build_modify_expr.
> * decl2.c (set_guard): Likewise.
> (handle_tls_init): Likewise.
> * init.c (perform_member_init): Likewise.
> (expand_virtual_init): Likewise.
> (build_new_1): Likewise.
> (build_vec_delete_1): Likewise.
> (get_temp_regvar): Likewise.
> (build_vec_init): Likewise.
> * method.c (do_build_copy_assign): Likewise.
> (assignable_expr): Likewise.
> * semantics.c (finish_omp_for): Likewise.
> * typeck.c (cp_build_binary_op): Pass LOCATION to pointer_diff and
> cp_pointer_int_sum.
> (cp_pointer_int_sum): Add location parameter. Pass it down to
> pointer_int_sum.
> (pointer_diff): Add location parameter. Use it.
> (build_modify_expr): Pass location down to cp_build_modify_expr.
> (cp_build_modify_expr): Add location parameter. Use it.
> (build_x_modify_expr): Pass location down to cp_build_modify_expr.
> * 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.
>
> * c-c++-common/pr70756-2.c: New test.
> * c-c++-common/pr70756.c: New test.
>
> diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c
> index 63a18c8..150bdb2 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 861aa12..b037f46 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);
> @@ -3088,7 +3090,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. */
> @@ -3239,7 +3241,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)
> {
> @@ -4047,7 +4049,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)
> @@ -5268,7 +5270,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;
> }
> @@ -5538,7 +5540,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)
> @@ -6133,7 +6135,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;
>
> @@ -12550,7 +12552,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;
> @@ -13361,7 +13363,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/call.c gcc/cp/call.c
> index e9ebdbc..a49bbb5 100644
> --- gcc/cp/call.c
> +++ gcc/cp/call.c
> @@ -5757,7 +5757,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
> switch (code)
> {
> case MODIFY_EXPR:
> - return cp_build_modify_expr (arg1, code2, arg2, complain);
> + return cp_build_modify_expr (loc, arg1, code2, arg2, complain);
>
> case INDIRECT_REF:
> return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
> diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h
> index 6665355..556c256 100644
> --- gcc/cp/cp-tree.h
> +++ gcc/cp/cp-tree.h
> @@ -6666,7 +6666,8 @@ extern tree cp_build_c_cast (tree, tree, tsubst_flags_t);
> extern cp_expr build_x_modify_expr (location_t, tree,
> enum tree_code, tree,
> tsubst_flags_t);
> -extern tree cp_build_modify_expr (tree, enum tree_code, tree,
> +extern tree cp_build_modify_expr (location_t, tree,
> + enum tree_code, tree,
> tsubst_flags_t);
> extern tree convert_for_initialization (tree, tree, tree, int,
> impl_conv_rhs, tree, int,
> @@ -6726,11 +6727,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/cp-ubsan.c gcc/cp/cp-ubsan.c
> index be24a5c..9c8f6e6 100644
> --- gcc/cp/cp-ubsan.c
> +++ gcc/cp/cp-ubsan.c
> @@ -299,8 +299,8 @@ cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
>
> /* Assign NULL to the vptr. */
> tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
> - tree stmt = cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
> - tf_warning_or_error);
> + tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
> + vtbl, tf_warning_or_error);
> if (vptr_via_virtual_p (binfo))
> /* If this vptr comes from a virtual base of the complete object, only
> clear it if we're in charge of virtual bases. */
> diff --git gcc/cp/decl2.c gcc/cp/decl2.c
> index 0ea326d..22f9ede 100644
> --- gcc/cp/decl2.c
> +++ gcc/cp/decl2.c
> @@ -3161,7 +3161,7 @@ set_guard (tree guard)
> guard_init = integer_one_node;
> if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
> guard_init = fold_convert (TREE_TYPE (guard), guard_init);
> - return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
> + return cp_build_modify_expr (input_location, guard, NOP_EXPR, guard_init,
> tf_warning_or_error);
> }
>
> @@ -4346,7 +4346,8 @@ handle_tls_init (void)
> tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
> tf_warning_or_error);
> finish_if_stmt_cond (cond, if_stmt);
> - finish_expr_stmt (cp_build_modify_expr (guard, NOP_EXPR, boolean_true_node,
> + finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR,
> + boolean_true_node,
> tf_warning_or_error));
> for (; vars; vars = TREE_CHAIN (vars))
> {
> diff --git gcc/cp/init.c gcc/cp/init.c
> index 681ca12..8e7541f 100644
> --- gcc/cp/init.c
> +++ gcc/cp/init.c
> @@ -798,7 +798,8 @@ perform_member_init (tree member, tree init)
> tf_warning_or_error);
>
> if (init)
> - finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
> + finish_expr_stmt (cp_build_modify_expr (input_location, decl,
> + INIT_EXPR, init,
> tf_warning_or_error));
> }
>
> @@ -1254,8 +1255,8 @@ expand_virtual_init (tree binfo, tree decl)
>
> /* Assign the vtable to the vptr. */
> vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
> - finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
> - tf_warning_or_error));
> + finish_expr_stmt (cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
> + vtbl, tf_warning_or_error));
> }
>
> /* If an exception is thrown in a constructor, those base classes already
> @@ -3208,8 +3209,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
>
> ie = build_x_compound_expr_from_vec (*init, "new initializer",
> complain);
> - init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
> - complain);
> + init_expr = cp_build_modify_expr (input_location, init_expr,
> + INIT_EXPR, ie, complain);
> }
> stable = stabilize_init (init_expr, &init_preeval_expr);
> }
> @@ -3596,7 +3597,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
>
> tbase = create_temporary_var (ptype);
> tbase_init
> - = cp_build_modify_expr (tbase, NOP_EXPR,
> + = cp_build_modify_expr (input_location, tbase, NOP_EXPR,
> fold_build_pointer_plus_loc (input_location,
> fold_convert (ptype,
> base),
> @@ -3613,7 +3614,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
> fold_convert (ptype, base)));
> tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
> tmp = fold_build_pointer_plus (tbase, tmp);
> - tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
> + tmp = cp_build_modify_expr (input_location, tbase, NOP_EXPR, tmp, complain);
> if (tmp == error_mark_node)
> return error_mark_node;
> body = build_compound_expr (input_location, body, tmp);
> @@ -3735,8 +3736,8 @@ get_temp_regvar (tree type, tree init)
> decl = create_temporary_var (type);
> add_decl_expr (decl);
>
> - finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
> - tf_warning_or_error));
> + finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR,
> + init, tf_warning_or_error));
>
> return decl;
> }
> @@ -4000,8 +4001,8 @@ build_vec_init (tree base, tree maxindex, tree init,
> else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
> one_init = build_aggr_init (baseref, elt, 0, complain);
> else
> - one_init = cp_build_modify_expr (baseref, NOP_EXPR,
> - elt, complain);
> + one_init = cp_build_modify_expr (input_location, baseref,
> + NOP_EXPR, elt, complain);
> if (one_init == error_mark_node)
> errors = true;
> if (try_const)
> @@ -4128,12 +4129,12 @@ build_vec_init (tree base, tree maxindex, tree init,
> from = NULL_TREE;
>
> if (from_array == 2)
> - elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
> - complain);
> + elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
> + from, complain);
> else if (type_build_ctor_call (type))
> elt_init = build_aggr_init (to, from, 0, complain);
> else if (from)
> - elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
> + elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR, from,
> complain);
> else
> gcc_unreachable ();
> diff --git gcc/cp/method.c gcc/cp/method.c
> index 0e501d9..310e7eb 100644
> --- gcc/cp/method.c
> +++ gcc/cp/method.c
> @@ -741,7 +741,7 @@ do_build_copy_assign (tree fndecl)
> init = move (init);
>
> if (DECL_NAME (field))
> - init = cp_build_modify_expr (comp, NOP_EXPR, init,
> + init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
> tf_warning_or_error);
> else
> init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
> @@ -1023,7 +1023,7 @@ assignable_expr (tree to, tree from)
> ++cp_unevaluated_operand;
> to = build_stub_object (to);
> from = build_stub_object (from);
> - tree r = cp_build_modify_expr (to, NOP_EXPR, from, tf_none);
> + tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
> --cp_unevaluated_operand;
> return r;
> }
> diff --git gcc/cp/semantics.c gcc/cp/semantics.c
> index fed7e88..817ef99 100644
> --- gcc/cp/semantics.c
> +++ gcc/cp/semantics.c
> @@ -8073,7 +8073,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
> {
> if (orig_incr)
> TREE_VEC_ELT (orig_incr, i) = incr;
> - incr = cp_build_modify_expr (TREE_OPERAND (incr, 0),
> + incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
> TREE_CODE (TREE_OPERAND (incr, 1)),
> TREE_OPERAND (incr, 2),
> tf_warning_or_error);
> @@ -8107,7 +8107,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
> if (!processing_template_decl)
> {
> init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
> - init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
> + init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
> + tf_warning_or_error);
> }
> else
> init = build2 (MODIFY_EXPR, void_type_node, decl, init);
> diff --git gcc/cp/typeck.c gcc/cp/typeck.c
> index 95c777d..0d8a980 100644
> --- gcc/cp/typeck.c
> +++ gcc/cp/typeck.c
> @@ -43,13 +43,14 @@ static tree pfn_from_ptrmemfunc (tree);
> static tree delta_from_ptrmemfunc (tree);
> static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
> tsubst_flags_t, int);
> -static tree cp_pointer_int_sum (enum tree_code, tree, tree, tsubst_flags_t);
> +static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
> + tsubst_flags_t);
> static tree rationalize_conditional_expr (enum tree_code, tree,
> tsubst_flags_t);
> static int comp_ptr_ttypes_real (tree, tree, int);
> static bool comp_except_types (tree, tree, bool);
> static bool comp_array_types (const_tree, const_tree, bool);
> -static tree pointer_diff (tree, tree, tree, tsubst_flags_t);
> +static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t);
> static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
> static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
> static bool casts_away_constness (tree, tree, tsubst_flags_t);
> @@ -4236,8 +4237,8 @@ cp_build_binary_op (location_t location,
> if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
> && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
> TREE_TYPE (type1)))
> - return pointer_diff (op0, op1, common_pointer_type (type0, type1),
> - complain);
> + return pointer_diff (location, op0, op1,
> + common_pointer_type (type0, type1), complain);
> /* In all other cases except pointer - int, the usual arithmetic
> rules apply. */
> else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
> @@ -4260,8 +4261,8 @@ cp_build_binary_op (location_t location,
> result_type = TREE_TYPE (ptr_operand);
> break;
> }
> - return cp_pointer_int_sum (code,
> - ptr_operand,
> + return cp_pointer_int_sum (location, code,
> + ptr_operand,
> int_operand,
> complain);
> }
> @@ -5226,8 +5227,8 @@ build_x_vec_perm_expr (location_t loc,
> of pointer PTROP and integer INTOP. */
>
> static tree
> -cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
> - tsubst_flags_t complain)
> +cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
> + tree intop, tsubst_flags_t complain)
> {
> tree res_type = TREE_TYPE (ptrop);
>
> @@ -5238,7 +5239,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
> pointer_int_sum() anyway. */
> complete_type (TREE_TYPE (res_type));
>
> - return pointer_int_sum (input_location, resultcode, ptrop,
> + return pointer_int_sum (loc, resultcode, ptrop,
> intop, complain & tf_warning_or_error);
> }
>
> @@ -5246,7 +5247,8 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
> The resulting tree has type int. */
>
> static tree
> -pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> +pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
> + tsubst_flags_t complain)
> {
> tree result;
> tree restype = ptrdiff_type_node;
> @@ -5258,7 +5260,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> if (VOID_TYPE_P (target_type))
> {
> if (complain & tf_error)
> - permerror (input_location, "ISO C++ forbids using pointer of "
> + permerror (loc, "ISO C++ forbids using pointer of "
> "type %<void *%> in subtraction");
> else
> return error_mark_node;
> @@ -5266,7 +5268,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> if (TREE_CODE (target_type) == FUNCTION_TYPE)
> {
> if (complain & tf_error)
> - permerror (input_location, "ISO C++ forbids using pointer to "
> + permerror (loc, "ISO C++ forbids using pointer to "
> "a function in subtraction");
> else
> return error_mark_node;
> @@ -5274,7 +5276,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> if (TREE_CODE (target_type) == METHOD_TYPE)
> {
> if (complain & tf_error)
> - permerror (input_location, "ISO C++ forbids using pointer to "
> + permerror (loc, "ISO C++ forbids using pointer to "
> "a method in subtraction");
> else
> return error_mark_node;
> @@ -5283,7 +5285,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> /* First do the subtraction as integers;
> then drop through to build the divide operator. */
>
> - op0 = cp_build_binary_op (input_location,
> + op0 = cp_build_binary_op (loc,
> MINUS_EXPR,
> cp_convert (restype, op0, complain),
> cp_convert (restype, op1, complain),
> @@ -5293,8 +5295,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
> {
> if (complain & tf_error)
> - error ("invalid use of a pointer to an incomplete type in "
> - "pointer arithmetic");
> + error_at (loc, "invalid use of a pointer to an incomplete type in "
> + "pointer arithmetic");
> else
> return error_mark_node;
> }
> @@ -5302,19 +5304,19 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
> if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
> {
> if (complain & tf_error)
> - error ("arithmetic on pointer to an empty aggregate");
> + error_at (loc, "arithmetic on pointer to an empty aggregate");
> else
> return error_mark_node;
> }
>
> op1 = (TYPE_PTROB_P (ptrtype)
> - ? size_in_bytes (target_type)
> + ? size_in_bytes_loc (loc, target_type)
> : integer_one_node);
>
> /* Do the division. */
>
> - result = build2 (EXACT_DIV_EXPR, restype, op0,
> - cp_convert (restype, op1, complain));
> + result = build2_loc (loc, EXACT_DIV_EXPR, restype, op0,
> + cp_convert (restype, op1, complain));
> return result;
> }
> \f
> @@ -7470,13 +7472,14 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
> \f
> /* For use from the C common bits. */
> tree
> -build_modify_expr (location_t /*location*/,
> +build_modify_expr (location_t location,
> tree lhs, tree /*lhs_origtype*/,
> enum tree_code modifycode,
> location_t /*rhs_location*/, tree rhs,
> tree /*rhs_origtype*/)
> {
> - return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
> + return cp_build_modify_expr (location, lhs, modifycode, rhs,
> + tf_warning_or_error);
> }
>
> /* Build an assignment expression of lvalue LHS from value RHS.
> @@ -7487,8 +7490,8 @@ build_modify_expr (location_t /*location*/,
> C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */
>
> tree
> -cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
> - tsubst_flags_t complain)
> +cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
> + tree rhs, tsubst_flags_t complain)
> {
> tree result;
> tree newrhs = rhs;
> @@ -7510,7 +7513,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
> lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
> cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
> TREE_OPERAND (lhs, 1));
> - newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
> + newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0),
> modifycode, rhs, complain);
> if (newrhs == error_mark_node)
> return error_mark_node;
> @@ -7518,7 +7521,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
>
> /* Handle (a, b) used as an "lvalue". */
> case COMPOUND_EXPR:
> - newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
> + newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
> modifycode, rhs, complain);
> if (newrhs == error_mark_node)
> return error_mark_node;
> @@ -7530,8 +7533,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
> lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
> cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
> TREE_OPERAND (lhs, 1));
> - newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
> - complain);
> + newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0), modifycode,
> + rhs, complain);
> if (newrhs == error_mark_node)
> return error_mark_node;
> return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
> @@ -7580,9 +7583,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
>
> cond = build_conditional_expr
> (input_location, TREE_OPERAND (lhs, 0),
> - cp_build_modify_expr (TREE_OPERAND (lhs, 1),
> + cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
> modifycode, rhs, complain),
> - cp_build_modify_expr (TREE_OPERAND (lhs, 2),
> + cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
> modifycode, rhs, complain),
> complain);
>
> @@ -7680,9 +7683,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
> lhs = cp_stabilize_reference (lhs);
> rhs = rvalue (rhs);
> rhs = stabilize_expr (rhs, &init);
> - newrhs = cp_build_binary_op (input_location,
> - modifycode, lhs, rhs,
> - complain);
> + newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
> if (newrhs == error_mark_node)
> {
> if (complain & tf_error)
> @@ -7893,7 +7894,7 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
> return rval;
> }
> }
> - return cp_build_modify_expr (lhs, modifycode, rhs, complain);
> + return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
> }
>
> /* Helper function for get_delta_difference which assumes FROM is a base
> 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/c-c++-common/pr70756-2.c gcc/testsuite/c-c++-common/pr70756-2.c
> index e69de29..b7df3b7 100644
> --- gcc/testsuite/c-c++-common/pr70756-2.c
> +++ gcc/testsuite/c-c++-common/pr70756-2.c
> @@ -0,0 +1,12 @@
> +/* PR c/70756 */
> +/* { dg-do compile } */
> +/* { dg-options "-Wpointer-arith" } */
> +
> +extern void bar (void);
> +
> +void
> +fn (void *p)
> +{
> + void *a = p + 1; /* { dg-warning "15:pointer of type" } */
> + void (*a2)(void) = &bar + 1; /* { dg-warning "27:pointer to a function" } */
> +}
> diff --git gcc/testsuite/c-c++-common/pr70756.c gcc/testsuite/c-c++-common/pr70756.c
> index e69de29..3725922 100644
> --- gcc/testsuite/c-c++-common/pr70756.c
> +++ gcc/testsuite/c-c++-common/pr70756.c
> @@ -0,0 +1,23 @@
> +/* PR c/70756 */
> +/* { dg-do compile } */
> +/* { dg-options "" } */
> +
> +enum E e; /* { dg-error "storage size|use of enum" } */
> +int (*A)[];
> +
> +void
> +fn0 (void)
> +{
> + struct
> + {
> + int x;
> + int y[];
> + } s;
> + 1234 && &s.y + 1; /* { dg-error "16:invalid use of" } */
> +}
> +
> +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 c565337..b63f64c 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
Marek
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] Better location info for "incomplete type" error msg (PR c/70756)
2016-05-05 14:22 ` Marek Polacek
2016-05-12 10:37 ` Marek Polacek
@ 2016-05-12 15:09 ` Jason Merrill
1 sibling, 0 replies; 11+ messages in thread
From: Jason Merrill @ 2016-05-12 15:09 UTC (permalink / raw)
To: Marek Polacek; +Cc: GCC Patches
OK, thanks.
Jason
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2016-05-12 15:09 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-28 15:59 [PATCH] Better location info for "incomplete type" error msg (PR c/70756) 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
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
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).