\f
/* Given an expression PTR for a pointer, return an expression
for the value pointed to.
- ERRORSTRING is the name of the operator to appear in error messages. */
+ ERRORSTRING is the name of the operator to appear in error messages.
+
+ LOC is the location to use for the generated tree. */
tree
-build_indirect_ref (tree ptr, const char *errorstring)
+build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
{
tree pointer = default_conversion (ptr);
tree type = TREE_TYPE (pointer);
+ tree ref;
if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (pointer) == ADDR_EXPR
&& (TREE_TYPE (TREE_OPERAND (pointer, 0))
== TREE_TYPE (type)))
- return TREE_OPERAND (pointer, 0);
+ {
+ ref = TREE_OPERAND (pointer, 0);
+ protected_set_expr_location (ref, loc);
+ return ref;
+ }
else
{
tree t = TREE_TYPE (type);
- tree ref;
ref = build1 (INDIRECT_REF, t, pointer);
TREE_SIDE_EFFECTS (ref)
= TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
+ protected_set_expr_location (ref, loc);
return ref;
}
}
If A is a variable or a member, we generate a primitive ARRAY_REF.
This avoids forcing the array out of registers, and can work on
arrays that are not lvalues (for example, members of structures returned
- by functions). */
+ by functions).
+
+ LOC is the location to use for the returned expression. */
tree
-build_array_ref (tree array, tree index)
+build_array_ref (tree array, tree index, location_t loc)
{
+ tree ret;
bool swapped = false;
if (TREE_TYPE (array) == error_mark_node
|| TREE_TYPE (index) == error_mark_node)
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
- error ("subscripted value is neither array nor pointer");
+ error_at (loc, "subscripted value is neither array nor pointer");
return error_mark_node;
}
temp = array;
if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
{
- error ("array subscript is not an integer");
+ error_at (loc, "array subscript is not an integer");
return error_mark_node;
}
if (TREE_CODE (TREE_TYPE (TREE_TYPE (array))) == FUNCTION_TYPE)
{
- error ("subscripted value is pointer to function");
+ error_at (loc, "subscripted value is pointer to function");
return error_mark_node;
}
while (TREE_CODE (foo) == COMPONENT_REF)
foo = TREE_OPERAND (foo, 0);
if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids subscripting %<register%> array");
else if (!flag_isoc99 && !lvalue_p (foo))
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C90 forbids subscripting non-lvalue array");
}
in an inline function.
Hope it doesn't break something else. */
| TREE_THIS_VOLATILE (array));
- return require_complete_type (fold (rval));
+ ret = require_complete_type (fold (rval));
+ protected_set_expr_location (ret, loc);
+ return ret;
}
else
{
gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
- "array indexing");
+ "array indexing", loc);
}
}
\f
/* This is the entry point used by the parser to build unary operators
in the input. CODE, a tree_code, specifies the unary operator, and
ARG is the operand. For unary plus, the C parser currently uses
- CONVERT_EXPR for code. */
+ CONVERT_EXPR for code.
+
+ LOC is the location to use for the tree generated.
+*/
struct c_expr
-parser_build_unary_op (enum tree_code code, struct c_expr arg)
+parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
{
struct c_expr result;
result.original_code = ERROR_MARK;
result.value = build_unary_op (code, arg.value, 0);
-
+ protected_set_expr_location (result.value, loc);
+
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
overflow_warning (result.value);
/* This macro is used to emit diagnostics to ensure that all format
strings are complete sentences, visible to gettext and checked at
compile time. */
-#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \
- do { \
- switch (errtype) \
- { \
- case ic_argpass: \
- pedwarn (LOCATION, OPT, AR, parmnum, rname); \
- break; \
- case ic_argpass_nonproto: \
- warning (OPT, AR, parmnum, rname); \
- break; \
- case ic_assign: \
- pedwarn (LOCATION, OPT, AS); \
- break; \
- case ic_init: \
- pedwarn (LOCATION, OPT, IN); \
- break; \
- case ic_return: \
- pedwarn (LOCATION, OPT, RE); \
- break; \
- default: \
- gcc_unreachable (); \
- } \
+#define WARN_FOR_ASSIGNMENT(LOCATION, OPT, AR, AS, IN, RE) \
+ do { \
+ switch (errtype) \
+ { \
+ case ic_argpass: \
+ if (pedwarn (LOCATION, OPT, AR, parmnum, rname)) \
+ inform (fundecl ? DECL_SOURCE_LOCATION (fundecl) : LOCATION, \
+ "expected %qT but argument is of type %qT", \
+ type, rhstype); \
+ break; \
+ case ic_argpass_nonproto: \
+ warning (OPT, AR, parmnum, rname); \
+ break; \
+ case ic_assign: \
+ pedwarn (LOCATION, OPT, AS); \
+ break; \
+ case ic_init: \
+ pedwarn (LOCATION, OPT, IN); \
+ break; \
+ case ic_return: \
+ pedwarn (LOCATION, OPT, RE); \
+ break; \
+ default: \
+ gcc_unreachable (); \
+ } \
} while (0)
STRIP_TYPE_NOPS (rhs);