aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-typeck.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c/c-typeck.c')
-rw-r--r--gcc/c/c-typeck.c227
1 files changed, 121 insertions, 106 deletions
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 11825a9218e..7d2df6b1d12 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -101,14 +101,15 @@ static void push_string (const char *);
static void push_member_name (tree);
static int spelling_length (void);
static char *print_spelling (char *);
-static void warning_init (int, const char *);
+static void warning_init (location_t, int, const char *);
static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
static void output_init_element (location_t, tree, tree, bool, tree, tree, int,
bool, struct obstack *);
static void output_pending_init_elements (int, struct obstack *);
static int set_designator (int, struct obstack *);
static void push_range_stack (tree, struct obstack *);
-static void add_pending_init (tree, tree, tree, bool, struct obstack *);
+static void add_pending_init (location_t, tree, tree, tree, bool,
+ struct obstack *);
static void set_nonincremental_init (struct obstack *);
static void set_nonincremental_init_from_string (tree, struct obstack *);
static tree find_init_member (tree, struct obstack *);
@@ -1754,22 +1755,20 @@ type_lists_compatible_p (const_tree args1, const_tree args2,
}
}
-/* Compute the size to increment a pointer by. */
+/* Compute the size to increment a pointer by. When a function type or void
+ type or incomplete type is passed, size_one_node is returned.
+ This function does not emit any diagnostics; the caller is responsible
+ for that. */
static tree
c_size_in_bytes (const_tree type)
{
enum tree_code code = TREE_CODE (type);
- if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
+ if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK
+ || !COMPLETE_TYPE_P (type))
return size_one_node;
- if (!COMPLETE_OR_VOID_TYPE_P (type))
- {
- error ("arithmetic on pointer to an incomplete type");
- return size_one_node;
- }
-
/* Convert in case a char is more than one unit. */
return size_binop_loc (input_location, CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
size_int (TYPE_PRECISION (char_type_node)
@@ -2108,7 +2107,8 @@ default_conversion (tree exp)
if (code == VOID_TYPE)
{
- error ("void value not ignored as it ought to be");
+ error_at (EXPR_LOC_OR_LOC (exp, input_location),
+ "void value not ignored as it ought to be");
return error_mark_node;
}
@@ -3529,7 +3529,6 @@ pointer_diff (location_t loc, tree op0, tree op1)
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (TREE_TYPE (orig_op1))))
error_at (loc, "arithmetic on pointer to an incomplete type");
- /* This generates an error if op0 is pointer to incomplete type. */
op1 = c_size_in_bytes (target_type);
if (pointer_to_zero_sized_aggr_p (TREE_TYPE (orig_op1)))
@@ -4003,16 +4002,18 @@ build_unary_op (location_t location,
if (typecode == POINTER_TYPE)
{
- /* If pointer target is an undefined struct,
+ /* If pointer target is an incomplete type,
we just cannot know how to do the arithmetic. */
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (argtype)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
error_at (location,
- "increment of pointer to unknown structure");
+ "increment of pointer to an incomplete type %qT",
+ TREE_TYPE (argtype));
else
error_at (location,
- "decrement of pointer to unknown structure");
+ "decrement of pointer to an incomplete type %qT",
+ TREE_TYPE (argtype));
}
else if (TREE_CODE (TREE_TYPE (argtype)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (argtype)) == VOID_TYPE)
@@ -5539,6 +5540,72 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs)
return ret;
}
+/* Issue an error message for a bad initializer component.
+ GMSGID identifies the message.
+ The component name is taken from the spelling stack. */
+
+static void
+error_init (const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ error (gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ error ("(near initialization for %qs)", ofwhat);
+}
+
+/* Issue a pedantic warning for a bad initializer component. OPT is
+ the option OPT_* (from options.h) controlling this warning or 0 if
+ it is unconditionally given. GMSGID identifies the message. The
+ component name is taken from the spelling stack. */
+
+static void
+pedwarn_init (location_t location, int opt, const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ pedwarn (location, opt, gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
+}
+
+/* Issue a warning for a bad initializer component.
+
+ OPT is the OPT_W* value corresponding to the warning option that
+ controls this warning. GMSGID identifies the message. The
+ component name is taken from the spelling stack. */
+
+static void
+warning_init (location_t loc, int opt, const char *gmsgid)
+{
+ char *ofwhat;
+
+ /* The gmsgid may be a format string with %< and %>. */
+ warning_at (loc, opt, gmsgid);
+ ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
+ if (*ofwhat)
+ warning_at (loc, opt, "(near initialization for %qs)", ofwhat);
+}
+
+/* If TYPE is an array type and EXPR is a parenthesized string
+ constant, warn if pedantic that EXPR is being used to initialize an
+ object of type TYPE. */
+
+void
+maybe_warn_string_init (tree type, struct c_expr expr)
+{
+ if (pedantic
+ && TREE_CODE (type) == ARRAY_TYPE
+ && TREE_CODE (expr.value) == STRING_CST
+ && expr.original_code != STRING_CST)
+ pedwarn_init (input_location, OPT_Wpedantic,
+ "array initialized from parenthesized string constant");
+}
+
/* Convert value RHS to type TYPE as preparation for an assignment to
an lvalue of type TYPE. If ORIGTYPE is not NULL_TREE, it is the
original type of RHS; this differs from TREE_TYPE (RHS) for enum
@@ -5850,7 +5917,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE "
"makes %q#v qualified function "
"pointer from unqualified"),
@@ -5866,7 +5933,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
}
else if (TYPE_QUALS_NO_ADDR_SPACE (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttl))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE discards "
"%qv qualifier from pointer target type"),
G_("assignment discards %qv qualifier "
@@ -6047,7 +6114,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
if (TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttr)
& ~TYPE_QUALS_NO_ADDR_SPACE_NO_ATOMIC (ttl))
{
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE discards "
"%qv qualifier from pointer target type"),
G_("assignment discards %qv qualifier "
@@ -6084,7 +6151,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS_NO_ADDR_SPACE (ttl)
& ~TYPE_QUALS_NO_ADDR_SPACE (ttr))
- WARN_FOR_QUALIFIERS (location, 0,
+ WARN_FOR_QUALIFIERS (location, OPT_Wdiscarded_qualifiers,
G_("passing argument %d of %qE makes "
"%q#v qualified function pointer "
"from unqualified"),
@@ -6404,72 +6471,6 @@ print_spelling (char *buffer)
return buffer;
}
-/* Issue an error message for a bad initializer component.
- GMSGID identifies the message.
- The component name is taken from the spelling stack. */
-
-void
-error_init (const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- error (gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- error ("(near initialization for %qs)", ofwhat);
-}
-
-/* Issue a pedantic warning for a bad initializer component. OPT is
- the option OPT_* (from options.h) controlling this warning or 0 if
- it is unconditionally given. GMSGID identifies the message. The
- component name is taken from the spelling stack. */
-
-void
-pedwarn_init (location_t location, int opt, const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- pedwarn (location, opt, gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- pedwarn (location, opt, "(near initialization for %qs)", ofwhat);
-}
-
-/* Issue a warning for a bad initializer component.
-
- OPT is the OPT_W* value corresponding to the warning option that
- controls this warning. GMSGID identifies the message. The
- component name is taken from the spelling stack. */
-
-static void
-warning_init (int opt, const char *gmsgid)
-{
- char *ofwhat;
-
- /* The gmsgid may be a format string with %< and %>. */
- warning (opt, gmsgid);
- ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
- if (*ofwhat)
- warning (opt, "(near initialization for %qs)", ofwhat);
-}
-
-/* If TYPE is an array type and EXPR is a parenthesized string
- constant, warn if pedantic that EXPR is being used to initialize an
- object of type TYPE. */
-
-void
-maybe_warn_string_init (tree type, struct c_expr expr)
-{
- if (pedantic
- && TREE_CODE (type) == ARRAY_TYPE
- && TREE_CODE (expr.value) == STRING_CST
- && expr.original_code != STRING_CST)
- pedwarn_init (input_location, OPT_Wpedantic,
- "array initialized from parenthesized string constant");
-}
-
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
@@ -7267,6 +7268,9 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
push_member_name (constructor_fields);
constructor_depth++;
}
+ /* If upper initializer is designated, then mark this as
+ designated too to prevent bogus warnings. */
+ constructor_designated = p->designated;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -7298,7 +7302,8 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned)
{
missing_braces_mentioned = 1;
- warning_init (OPT_Wmissing_braces, "missing braces around initializer");
+ warning_init (input_location, OPT_Wmissing_braces,
+ "missing braces around initializer");
}
if (TREE_CODE (constructor_type) == RECORD_TYPE
@@ -7359,7 +7364,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
else
{
if (constructor_type != error_mark_node)
- warning_init (0, "braces around scalar initializer");
+ warning_init (input_location, 0, "braces around scalar initializer");
constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type;
}
@@ -7774,8 +7779,8 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack)
existing initializer. */
static void
-add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
- struct obstack * braced_init_obstack)
+add_pending_init (location_t loc, tree purpose, tree value, tree origtype,
+ bool implicit, struct obstack *braced_init_obstack)
{
struct init_node *p, **q, *r;
@@ -7796,9 +7801,12 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
+ warning_init (loc, 0,
+ "initialized field with side-effects "
+ "overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
p->value = value;
p->origtype = origtype;
@@ -7823,9 +7831,12 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (p->value))
- warning_init (0, "initialized field with side-effects overwritten");
+ warning_init (loc, 0,
+ "initialized field with side-effects "
+ "overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
p->value = value;
p->origtype = origtype;
@@ -8014,10 +8025,8 @@ set_nonincremental_init (struct obstack * braced_init_obstack)
return;
FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
- {
- add_pending_init (index, value, NULL_TREE, true,
- braced_init_obstack);
- }
+ add_pending_init (input_location, index, value, NULL_TREE, true,
+ braced_init_obstack);
constructor_elements = NULL;
if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
@@ -8112,7 +8121,7 @@ set_nonincremental_init_from_string (tree str,
value = wide_int_to_tree (type,
wide_int::from_array (val, 2,
HOST_BITS_PER_WIDE_INT * 2));
- add_pending_init (purpose, value, NULL_TREE, true,
+ add_pending_init (input_location, purpose, value, NULL_TREE, true,
braced_init_obstack);
}
@@ -8278,7 +8287,7 @@ output_init_element (location_t loc, tree value, tree origtype,
if (checktype != error_mark_node
&& (TYPE_MAIN_VARIANT (checktype)
!= TYPE_MAIN_VARIANT (DECL_BIT_FIELD_TYPE (field))))
- warning_init (OPT_Wc___compat,
+ warning_init (loc, OPT_Wc___compat,
"enum conversion in initialization is invalid in C++");
}
@@ -8314,7 +8323,7 @@ output_init_element (location_t loc, tree value, tree origtype,
&& tree_int_cst_lt (field, constructor_unfilled_index))
set_nonincremental_init (braced_init_obstack);
- add_pending_init (field, value, origtype, implicit,
+ add_pending_init (loc, field, value, origtype, implicit,
braced_init_obstack);
return;
}
@@ -8341,7 +8350,7 @@ output_init_element (location_t loc, tree value, tree origtype,
}
}
- add_pending_init (field, value, origtype, implicit,
+ add_pending_init (loc, field, value, origtype, implicit,
braced_init_obstack);
return;
}
@@ -8351,10 +8360,11 @@ output_init_element (location_t loc, tree value, tree origtype,
if (!implicit)
{
if (TREE_SIDE_EFFECTS (constructor_elements->last ().value))
- warning_init (0,
+ warning_init (loc, 0,
"initialized field with side-effects overwritten");
else if (warn_override_init)
- warning_init (OPT_Woverride_init, "initialized field overwritten");
+ warning_init (loc, OPT_Woverride_init,
+ "initialized field overwritten");
}
/* We can have just one union field set. */
@@ -9263,9 +9273,14 @@ c_finish_return (location_t loc, tree retval, tree origtype)
&& !DECL_EXTERNAL (inner)
&& !TREE_STATIC (inner)
&& DECL_CONTEXT (inner) == current_function_decl)
- warning_at (loc,
- OPT_Wreturn_local_addr, "function returns address "
- "of local variable");
+ {
+ if (TREE_CODE (inner) == LABEL_DECL)
+ warning_at (loc, OPT_Wreturn_local_addr,
+ "function returns address of label");
+ else
+ warning_at (loc, OPT_Wreturn_local_addr,
+ "function returns address of local variable");
+ }
break;
default: