/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
#include "target.h"
#include "tree-iterator.h"
#include "tree-gimple.h"
+#include "tree-flow.h"
+
+/* Possible cases of implicit bad conversions. Used to select
+ diagnostic messages in convert_for_assignment. */
+enum impl_conv {
+ ic_argpass,
+ ic_argpass_nonproto,
+ ic_assign,
+ ic_init,
+ ic_return
+};
/* The level of nesting inside "__alignof__". */
int in_alignof;
static tree lookup_field (tree, tree);
static tree convert_arguments (tree, tree, tree, tree);
static tree pointer_diff (tree, tree);
-static tree convert_for_assignment (tree, tree, const char *, tree, tree,
+static tree convert_for_assignment (tree, tree, enum impl_conv, tree, tree,
int);
-static void warn_for_assignment (const char *, const char *, tree, int);
static tree valid_compound_expr_initializer (tree, tree);
static void push_string (const char *);
static void push_member_name (tree);
static void set_nonincremental_init (void);
static void set_nonincremental_init_from_string (tree);
static tree find_init_member (tree);
-static int lvalue_or_else (tree, const char *);
+static void readonly_error (tree, enum lvalue_use);
+static void record_maybe_used_decl (tree);
\f
/* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) */
case ARRAY_TYPE:
{
tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
-
+ int quals;
+ tree unqual_elt;
+
/* We should not have any type quals on arrays at all. */
gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
if (elt == TREE_TYPE (t2) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
return build_type_attribute_variant (t2, attributes);
- /* Merge the element types, and have a size if either arg has one. */
- t1 = build_array_type (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ /* Merge the element types, and have a size if either arg has
+ one. We may have qualifiers on the element types. To set
+ up TYPE_MAIN_VARIANT correctly, we need to form the
+ composite of the unqualified types and add the qualifiers
+ back at the end. */
+ quals = TYPE_QUALS (strip_array_types (elt));
+ unqual_elt = c_build_qualified_type (elt, TYPE_UNQUALIFIED);
+ t1 = build_array_type (unqual_elt,
+ TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2));
+ t1 = c_build_qualified_type (t1, quals);
return build_type_attribute_variant (t1, attributes);
}
int i;
/* Save space: see if the result is identical to one of the args. */
- if (valtype == TREE_TYPE (t1) && ! TYPE_ARG_TYPES (t2))
+ if (valtype == TREE_TYPE (t1) && !TYPE_ARG_TYPES (t2))
return build_type_attribute_variant (t1, attributes);
- if (valtype == TREE_TYPE (t2) && ! TYPE_ARG_TYPES (t1))
+ if (valtype == TREE_TYPE (t2) && !TYPE_ARG_TYPES (t1))
return build_type_attribute_variant (t2, attributes);
/* Simple way if one arg fails to specify argument types. */
&& TREE_VALUE (p1) != TREE_VALUE (p2))
{
tree memb;
+ tree mv2 = TREE_VALUE (p2);
+ if (mv2 && mv2 != error_mark_node
+ && TREE_CODE (mv2) != ARRAY_TYPE)
+ mv2 = TYPE_MAIN_VARIANT (mv2);
for (memb = TYPE_FIELDS (TREE_VALUE (p1));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
- {
- TREE_VALUE (n) = TREE_VALUE (p2);
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
- goto parm_done;
- }
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv2))
+ {
+ TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
+ TREE_VALUE (p2));
+ if (pedantic)
+ pedwarn ("function types not truly compatible in ISO C");
+ goto parm_done;
+ }
+ }
}
if (TREE_CODE (TREE_VALUE (p2)) == UNION_TYPE
&& TREE_VALUE (p2) != TREE_VALUE (p1))
{
tree memb;
+ tree mv1 = TREE_VALUE (p1);
+ if (mv1 && mv1 != error_mark_node
+ && TREE_CODE (mv1) != ARRAY_TYPE)
+ mv1 = TYPE_MAIN_VARIANT (mv1);
for (memb = TYPE_FIELDS (TREE_VALUE (p2));
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
- {
- TREE_VALUE (n) = TREE_VALUE (p1);
- if (pedantic)
- pedwarn ("function types not truly compatible in ISO C");
- goto parm_done;
- }
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv1))
+ {
+ TREE_VALUE (n) = composite_type (TREE_TYPE (memb),
+ TREE_VALUE (p1));
+ if (pedantic)
+ pedwarn ("function types not truly compatible in ISO C");
+ goto parm_done;
+ }
+ }
}
TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
parm_done: ;
common_pointer_type (tree t1, tree t2)
{
tree attributes;
- tree pointed_to_1;
- tree pointed_to_2;
+ tree pointed_to_1, mv1;
+ tree pointed_to_2, mv2;
tree target;
/* Save time if the two types are the same. */
attributes = targetm.merge_type_attributes (t1, t2);
/* Find the composite type of the target types, and combine the
- qualifiers of the two types' targets. */
- pointed_to_1 = TREE_TYPE (t1);
- pointed_to_2 = TREE_TYPE (t2);
- target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1),
- TYPE_MAIN_VARIANT (pointed_to_2));
+ qualifiers of the two types' targets. Do not lose qualifiers on
+ array element types by taking the TYPE_MAIN_VARIANT. */
+ mv1 = pointed_to_1 = TREE_TYPE (t1);
+ mv2 = pointed_to_2 = TREE_TYPE (t2);
+ if (TREE_CODE (mv1) != ARRAY_TYPE)
+ mv1 = TYPE_MAIN_VARIANT (pointed_to_1);
+ if (TREE_CODE (mv2) != ARRAY_TYPE)
+ mv2 = TYPE_MAIN_VARIANT (pointed_to_2);
+ target = composite_type (mv1, mv2);
t1 = build_pointer_type (c_build_qualified_type
(target,
TYPE_QUALS (pointed_to_1) |
This is the type for the result of most arithmetic operations
if the operands have the given two types. */
-tree
-common_type (tree t1, tree t2)
+static tree
+c_common_type (tree t1, tree t2)
{
enum tree_code code1;
enum tree_code code2;
{
tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
- tree subtype = common_type (subtype1, subtype2);
+ tree subtype = c_common_type (subtype1, subtype2);
if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
return t1;
return t2;
}
\f
+/* Wrapper around c_common_type that is used by c-common.c. ENUMERAL_TYPEs
+ are allowed here and are converted to their compatible integer types. */
+tree
+common_type (tree t1, tree t2)
+{
+ if (TREE_CODE (t1) == ENUMERAL_TYPE)
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
+ if (TREE_CODE (t2) == ENUMERAL_TYPE)
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
+ return c_common_type (t1, t2);
+}
+\f
/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
or various other operations. Return 2 if they are compatible
but a warning may be needed if you use them together. */
definition. Note that we already checked for equality of the type
qualifiers (just above). */
- if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
+ if (TREE_CODE (t1) != ARRAY_TYPE
+ && TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
return 1;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
- if (! (attrval = targetm.comp_type_attributes (t1, t2)))
+ if (!(attrval = targetm.comp_type_attributes (t1, t2)))
return 0;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
protocol qualifiers may be involved. */
if (c_dialect_objc () && (val = objc_comptypes (t1, t2, 0)) >= 0)
break;
+ /* Do not remove mode or aliasing information. */
+ if (TYPE_MODE (t1) != TYPE_MODE (t2)
+ || TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
+ break;
val = (TREE_TYPE (t1) == TREE_TYPE (t2)
? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
break;
if (d1 == 0 || d2 == 0 || d1 == d2)
break;
- d1_zero = ! TYPE_MAX_VALUE (d1);
- d2_zero = ! TYPE_MAX_VALUE (d2);
+ d1_zero = !TYPE_MAX_VALUE (d1);
+ d2_zero = !TYPE_MAX_VALUE (d2);
- d1_variable = (! d1_zero
+ d1_variable = (!d1_zero
&& (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
|| TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
- d2_variable = (! d2_zero
+ d2_variable = (!d2_zero
&& (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
|| TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
if (d1_zero && d2_zero)
break;
if (d1_zero || d2_zero
- || ! tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
- || ! tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
+ || !tree_int_cst_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
+ || !tree_int_cst_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)))
val = 0;
break;
comp_target_types (tree ttl, tree ttr, int reflexive)
{
int val;
+ tree mvl, mvr;
/* Give objc_comptypes a crack at letting these types through. */
if ((val = objc_comptypes (ttl, ttr, reflexive)) >= 0)
return val;
- val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
- TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
+ /* Do not lose qualifiers on element types of array types that are
+ pointer targets by taking their TYPE_MAIN_VARIANT. */
+ mvl = TREE_TYPE (ttl);
+ mvr = TREE_TYPE (ttr);
+ if (TREE_CODE (mvl) != ARRAY_TYPE)
+ mvl = TYPE_MAIN_VARIANT (mvl);
+ if (TREE_CODE (mvr) != ARRAY_TYPE)
+ mvr = TYPE_MAIN_VARIANT (mvr);
+ val = comptypes (mvl, mvr);
if (val == 2 && pedantic)
pedwarn ("types are not quite compatible");
break;
}
tagged_tu_seen_base = tts.next;
- if (! ok)
+ if (!ok)
return 0;
}
return needs_warning ? 2 : 1;
while (1)
{
+ tree a1, mv1, a2, mv2;
if (args1 == 0 && args2 == 0)
return val;
/* If one list is shorter than the other,
they fail to match. */
if (args1 == 0 || args2 == 0)
return 0;
+ mv1 = a1 = TREE_VALUE (args1);
+ mv2 = a2 = TREE_VALUE (args2);
+ if (mv1 && mv1 != error_mark_node && TREE_CODE (mv1) != ARRAY_TYPE)
+ mv1 = TYPE_MAIN_VARIANT (mv1);
+ if (mv2 && mv2 != error_mark_node && TREE_CODE (mv2) != ARRAY_TYPE)
+ mv2 = TYPE_MAIN_VARIANT (mv2);
/* A null pointer instead of a type
means there is supposed to be an argument
but nothing is specified about what type it has.
So match anything that self-promotes. */
- if (TREE_VALUE (args1) == 0)
+ if (a1 == 0)
{
- if (c_type_promotes_to (TREE_VALUE (args2)) != TREE_VALUE (args2))
+ if (c_type_promotes_to (a2) != a2)
return 0;
}
- else if (TREE_VALUE (args2) == 0)
+ else if (a2 == 0)
{
- if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1))
+ if (c_type_promotes_to (a1) != a1)
return 0;
}
/* If one of the lists has an error marker, ignore this arg. */
- else if (TREE_CODE (TREE_VALUE (args1)) == ERROR_MARK
- || TREE_CODE (TREE_VALUE (args2)) == ERROR_MARK)
+ else if (TREE_CODE (a1) == ERROR_MARK
+ || TREE_CODE (a2) == ERROR_MARK)
;
- else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
- TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
+ else if (!(newval = comptypes (mv1, mv2)))
{
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
- if (TREE_CODE (TREE_VALUE (args1)) == UNION_TYPE
- && (TYPE_NAME (TREE_VALUE (args1)) == 0
- || TYPE_TRANSPARENT_UNION (TREE_VALUE (args1)))
- && TREE_CODE (TYPE_SIZE (TREE_VALUE (args1))) == INTEGER_CST
- && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args1)),
- TYPE_SIZE (TREE_VALUE (args2))))
+ if (TREE_CODE (a1) == UNION_TYPE
+ && (TYPE_NAME (a1) == 0
+ || TYPE_TRANSPARENT_UNION (a1))
+ && TREE_CODE (TYPE_SIZE (a1)) == INTEGER_CST
+ && tree_int_cst_equal (TYPE_SIZE (a1),
+ TYPE_SIZE (a2)))
{
tree memb;
- for (memb = TYPE_FIELDS (TREE_VALUE (args1));
+ for (memb = TYPE_FIELDS (a1);
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
- break;
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv2))
+ break;
+ }
if (memb == 0)
return 0;
}
- else if (TREE_CODE (TREE_VALUE (args2)) == UNION_TYPE
- && (TYPE_NAME (TREE_VALUE (args2)) == 0
- || TYPE_TRANSPARENT_UNION (TREE_VALUE (args2)))
- && TREE_CODE (TYPE_SIZE (TREE_VALUE (args2))) == INTEGER_CST
- && tree_int_cst_equal (TYPE_SIZE (TREE_VALUE (args2)),
- TYPE_SIZE (TREE_VALUE (args1))))
+ else if (TREE_CODE (a2) == UNION_TYPE
+ && (TYPE_NAME (a2) == 0
+ || TYPE_TRANSPARENT_UNION (a2))
+ && TREE_CODE (TYPE_SIZE (a2)) == INTEGER_CST
+ && tree_int_cst_equal (TYPE_SIZE (a2),
+ TYPE_SIZE (a1)))
{
tree memb;
- for (memb = TYPE_FIELDS (TREE_VALUE (args2));
+ for (memb = TYPE_FIELDS (a2);
memb; memb = TREE_CHAIN (memb))
- if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
- break;
+ {
+ tree mv3 = TREE_TYPE (memb);
+ if (mv3 && mv3 != error_mark_node
+ && TREE_CODE (mv3) != ARRAY_TYPE)
+ mv3 = TYPE_MAIN_VARIANT (mv3);
+ if (comptypes (mv3, mv1))
+ break;
+ }
if (memb == 0)
return 0;
}
\f
/* Compute the size to increment a pointer by. */
-tree
+static tree
c_size_in_bytes (tree type)
{
enum tree_code code = TREE_CODE (type);
isn't valid for a PARM_DECL. */
current_function_decl != 0
&& TREE_CODE (decl) != PARM_DECL
- && ! TREE_THIS_VOLATILE (decl)
+ && !TREE_THIS_VOLATILE (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != 0
&& TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
find the element. Otherwise, do a linear search. TYPE_LANG_SPECIFIC
will always be set for structures which have many elements. */
- if (TYPE_LANG_SPECIFIC (type))
+ if (TYPE_LANG_SPECIFIC (type) && TYPE_LANG_SPECIFIC (type)->s)
{
int bot, top, half;
tree *field_array = &TYPE_LANG_SPECIFIC (type)->s->elts[0];
if (!field)
{
- error ("%s has no member named %qs",
- code == RECORD_TYPE ? "structure" : "union",
+ error ("%qT has no member named %qs", type,
IDENTIFIER_POINTER (component));
return error_mark_node;
}
else
{
tree t = TREE_TYPE (type);
- tree ref = build1 (INDIRECT_REF, TYPE_MAIN_VARIANT (t), pointer);
+ tree mvt = t;
+ tree ref;
+
+ if (TREE_CODE (mvt) != ARRAY_TYPE)
+ mvt = TYPE_MAIN_VARIANT (mvt);
+ ref = build1 (INDIRECT_REF, mvt, pointer);
if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
{
tree
build_array_ref (tree array, tree index)
{
- if (index == 0)
- {
- error ("subscript missing in array reference");
- return error_mark_node;
- }
-
+ bool swapped = false;
if (TREE_TYPE (array) == error_mark_node
|| TREE_TYPE (index) == error_mark_node)
return error_mark_node;
- if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+ if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
{
- tree rval, type;
-
- /* Subscripting with type char is likely to lose
- on a machine where chars are signed.
- So warn on any machine, but optionally.
- Don't warn for unsigned char since that type is safe.
- Don't warn for signed char because anyone who uses that
- must have done so deliberately. */
- if (warn_char_subscripts
- && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
- warning ("array subscript has type %<char%>");
-
- /* Apply default promotions *after* noticing character types. */
- index = default_conversion (index);
-
- /* Require integer *after* promotion, for sake of enums. */
- if (TREE_CODE (TREE_TYPE (index)) != INTEGER_TYPE)
+ tree temp;
+ if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
- error ("array subscript is not an integer");
+ error ("subscripted value is neither array nor pointer");
return error_mark_node;
}
+ temp = array;
+ array = index;
+ index = temp;
+ swapped = true;
+ }
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (index)))
+ {
+ error ("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");
+ return error_mark_node;
+ }
+
+ /* Subscripting with type char is likely to lose on a machine where
+ chars are signed. So warn on any machine, but optionally. Don't
+ warn for unsigned char since that type is safe. Don't warn for
+ signed char because anyone who uses that must have done so
+ deliberately. ??? Existing practice has also been to warn only
+ when the char index is syntactically the index, not for
+ char[array]. */
+ if (warn_char_subscripts && !swapped
+ && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
+ warning ("array subscript has type %<char%>");
+
+ /* Apply default promotions *after* noticing character types. */
+ index = default_conversion (index);
+
+ gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
+
+ if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
+ {
+ tree rval, type;
/* An array that is indexed by a non-constant
cannot be stored in a register; we must be able to do
to access a non-existent part of the register. */
if (TREE_CODE (index) == INTEGER_CST
&& TYPE_DOMAIN (TREE_TYPE (array))
- && ! int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array))))
+ && !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array))))
{
if (!c_mark_addressable (array))
return error_mark_node;
foo = TREE_OPERAND (foo, 0);
if (TREE_CODE (foo) == VAR_DECL && C_DECL_REGISTER (foo))
pedwarn ("ISO C forbids subscripting %<register%> array");
- else if (! flag_isoc99 && ! lvalue_p (foo))
+ else if (!flag_isoc99 && !lvalue_p (foo))
pedwarn ("ISO C90 forbids subscripting non-lvalue array");
}
- type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
+ type = TREE_TYPE (TREE_TYPE (array));
+ if (TREE_CODE (type) != ARRAY_TYPE)
+ type = TYPE_MAIN_VARIANT (type);
rval = build4 (ARRAY_REF, type, array, index, NULL_TREE, NULL_TREE);
/* Array ref is const/volatile if the array elements are
or if the array is. */
| TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval));
}
+ else
+ {
+ tree ar = default_conversion (array);
- {
- tree ar = default_conversion (array);
- tree ind = default_conversion (index);
-
- /* Do the same warning check as above, but only on the part that's
- syntactically the index and only if it is also semantically
- the index. */
- if (warn_char_subscripts
- && TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE
- && TYPE_MAIN_VARIANT (TREE_TYPE (index)) == char_type_node)
- warning ("subscript has type %<char%>");
-
- /* Put the integer in IND to simplify error checking. */
- if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE)
- {
- tree temp = ar;
- ar = ind;
- ind = temp;
- }
-
- if (ar == error_mark_node)
- return ar;
+ if (ar == error_mark_node)
+ return ar;
- if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE
- || TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) == FUNCTION_TYPE)
- {
- error ("subscripted value is neither array nor pointer");
- return error_mark_node;
- }
- if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE)
- {
- error ("array subscript is not an integer");
- return error_mark_node;
- }
+ gcc_assert (TREE_CODE (TREE_TYPE (ar)) == POINTER_TYPE);
+ gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
- return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, ind, 0),
- "array indexing");
- }
+ return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
+ "array indexing");
+ }
}
\f
/* Build an external reference to identifier ID. FUN indicates
- whether this will be used for a function call. */
+ whether this will be used for a function call. LOC is the source
+ location of the identifier. */
tree
-build_external_ref (tree id, int fun)
+build_external_ref (tree id, int fun, location_t loc)
{
tree ref;
tree decl = lookup_name (id);
- tree objc_ivar = objc_lookup_ivar (id);
+
+ /* In Objective-C, an instance variable (ivar) may be preferred to
+ whatever lookup_name() found. */
+ decl = objc_lookup_ivar (decl, id);
if (decl && decl != error_mark_node)
- {
- /* Properly declared variable or function reference. */
- if (!objc_ivar)
- ref = decl;
- else if (decl != objc_ivar && !DECL_FILE_SCOPE_P (decl))
- {
- warning ("local declaration of %qs hides instance variable",
- IDENTIFIER_POINTER (id));
- ref = decl;
- }
- else
- ref = objc_ivar;
- }
- else if (objc_ivar)
- ref = objc_ivar;
+ ref = decl;
else if (fun)
/* Implicit function declaration. */
ref = implicitly_declare (id);
return error_mark_node;
else
{
- undeclared_variable (id);
+ undeclared_variable (id, loc);
return error_mark_node;
}
a VLA type or the operand of typeof is a variably modified
type. */
-void
+static void
record_maybe_used_decl (tree decl)
{
struct maybe_used_decl *t = XOBNEW (&parser_obstack, struct maybe_used_decl);
??? This doesn't work for Objective-C because objc_comptypes
refuses to compare function prototypes, yet the compiler appears
to build calls that are flagged as invalid by C's comptypes. */
- if (! c_dialect_objc ()
+ if (!c_dialect_objc ()
&& TREE_CODE (function) == NOP_EXPR
&& TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
&& TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
- && ! comptypes (fntype, TREE_TYPE (tem)))
+ && !comptypes (fntype, TREE_TYPE (tem)))
{
tree return_type = TREE_TYPE (fntype);
tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
function prototype, or apply default promotions. */
coerced_params
- = convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
+ = convert_arguments (TYPE_ARG_TYPES (fntype), params, function, fundecl);
+
+ if (coerced_params == error_mark_node)
+ return error_mark_node;
/* Check that the arguments to the function are valid. */
\f
/* Convert the argument expressions in the list VALUES
to the types in the list TYPELIST. The result is a list of converted
- argument expressions.
+ argument expressions, unless there are too few arguments in which
+ case it is error_mark_node.
If TYPELIST is exhausted, or when an element has NULL as its type,
perform the default conversions.
It may be 0, if that info is not available.
It is used only for generating error messages.
- NAME is an IDENTIFIER_NODE or 0. It is used only for error messages.
+ FUNCTION is a tree for the called function. It is used only for
+ error messages, where it is formatted with %qE.
This is also where warnings about wrong number of args are generated.
with the elements of the list in the TREE_VALUE slots of those nodes. */
static tree
-convert_arguments (tree typelist, tree values, tree name, tree fundecl)
+convert_arguments (tree typelist, tree values, tree function, tree fundecl)
{
tree typetail, valtail;
tree result = NULL;
int parmnum;
+ tree selector;
+
+ /* Change pointer to function to the function itself for
+ diagnostics. */
+ if (TREE_CODE (function) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
+ function = TREE_OPERAND (function, 0);
+
+ /* Handle an ObjC selector specially for diagnostics. */
+ selector = objc_message_selector ();
/* Scan the given expressions and types, producing individual
converted arguments and pushing them on RESULT in reverse order. */
{
tree type = typetail ? TREE_VALUE (typetail) : 0;
tree val = TREE_VALUE (valtail);
+ tree rname = function;
+ int argnum = parmnum + 1;
if (type == void_type_node)
{
- if (name)
- error ("too many arguments to function %qs",
- IDENTIFIER_POINTER (name));
- else
- error ("too many arguments to function");
+ error ("too many arguments to function %qE", function);
break;
}
+ if (selector && argnum > 2)
+ {
+ rname = selector;
+ argnum -= 2;
+ }
+
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
/* Do not use STRIP_NOPS here! We do not want an enumerator with value 0
to convert automatically to a pointer. */
/* Formal parm type is specified by a function prototype. */
tree parmval;
- if (!COMPLETE_TYPE_P (type))
+ if (type == error_mark_node || !COMPLETE_TYPE_P (type))
{
error ("type of formal parameter %d is incomplete", parmnum + 1);
parmval = val;
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
- warn_for_assignment ("%s as integer rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as integer "
+ "rather than floating due to prototype",
+ argnum, rname);
if (INTEGRAL_TYPE_P (type)
&& TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
- warn_for_assignment ("%s as integer rather than complex due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as integer "
+ "rather than complex due to prototype",
+ argnum, rname);
else if (TREE_CODE (type) == COMPLEX_TYPE
&& TREE_CODE (TREE_TYPE (val)) == REAL_TYPE)
- warn_for_assignment ("%s as complex rather than floating due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as complex "
+ "rather than floating due to prototype",
+ argnum, rname);
else if (TREE_CODE (type) == REAL_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (val)))
- warn_for_assignment ("%s as floating rather than integer due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as floating "
+ "rather than integer due to prototype",
+ argnum, rname);
else if (TREE_CODE (type) == COMPLEX_TYPE
&& INTEGRAL_TYPE_P (TREE_TYPE (val)))
- warn_for_assignment ("%s as complex rather than integer due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as complex "
+ "rather than integer due to prototype",
+ argnum, rname);
else if (TREE_CODE (type) == REAL_TYPE
&& TREE_CODE (TREE_TYPE (val)) == COMPLEX_TYPE)
- warn_for_assignment ("%s as floating rather than complex due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as floating "
+ "rather than complex due to prototype",
+ argnum, rname);
/* ??? At some point, messages should be written about
conversions between complex types, but that's too messy
to do now. */
/* Warn if any argument is passed as `float',
since without a prototype it would be `double'. */
if (formal_prec == TYPE_PRECISION (float_type_node))
- warn_for_assignment ("%s as %<float%> rather than "
- "%<double%> due to prototype",
- (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as %<float%> "
+ "rather than %<double%> due to prototype",
+ argnum, rname);
}
/* Detect integer changing in width or signedness.
These warnings are only activated with
and the actual arg is that enum type. */
;
else if (formal_prec != TYPE_PRECISION (type1))
- warn_for_assignment ("%s with different width due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE with different "
+ "width due to prototype", argnum, rname);
else if (TYPE_UNSIGNED (type) == TYPE_UNSIGNED (type1))
;
/* Don't complain if the formal parameter type
&& TYPE_UNSIGNED (TREE_TYPE (val)))
;
else if (TYPE_UNSIGNED (type))
- warn_for_assignment ("%s as unsigned due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as unsigned "
+ "due to prototype", argnum, rname);
else
- warn_for_assignment ("%s as signed due to prototype", (char *) 0, name, parmnum + 1);
+ warning ("passing argument %d of %qE as signed "
+ "due to prototype", argnum, rname);
}
}
- parmval = convert_for_assignment (type, val,
- (char *) 0, /* arg passing */
- fundecl, name, parmnum + 1);
+ parmval = convert_for_assignment (type, val, ic_argpass,
+ fundecl, function,
+ parmnum + 1);
if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
&& INTEGRAL_TYPE_P (type)
if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
{
- if (name)
- error ("too few arguments to function %qs",
- IDENTIFIER_POINTER (name));
- else
- error ("too few arguments to function");
+ error ("too few arguments to function %qE", function);
+ return error_mark_node;
}
return nreverse (result);
/* Complain about anything else that is not a true lvalue. */
if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
- ? "invalid lvalue in increment"
- : "invalid lvalue in decrement")))
+ ? lv_increment
+ : lv_decrement)))
return error_mark_node;
/* Report a read-only lvalue. */
readonly_error (arg,
((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
- ? "increment" : "decrement"));
+ ? lv_increment : lv_decrement));
if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE)
val = boolean_increment (code, arg);
/* Anything not already handled and not a true memory reference
or a non-lvalue array is an error. */
else if (typecode != FUNCTION_TYPE && !flag
- && !lvalue_or_else (arg, "invalid lvalue in unary %<&%>"))
+ && !lvalue_or_else (arg, lv_addressof))
return error_mark_node;
/* Ordinary case; arg is a COMPONENT_REF or a decl. */
if (!c_mark_addressable (arg))
return error_mark_node;
- if (TREE_CODE (arg) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)))
- {
- error ("attempt to take address of bit-field structure member %qD",
- TREE_OPERAND (arg, 1));
- return error_mark_node;
- }
+ gcc_assert (TREE_CODE (arg) != COMPONENT_REF
+ || !DECL_C_BIT_FIELD (TREE_OPERAND (arg, 1)));
argtype = build_pointer_type (argtype);
return 0;
}
}
-
-/* Return nonzero if REF is an lvalue valid for this language;
- otherwise, print an error message and return zero. */
-
-static int
-lvalue_or_else (tree ref, const char *msgid)
-{
- int win = lvalue_p (ref);
-
- if (! win)
- error ("%s", msgid);
-
- return win;
-}
-
\f
-/* Warn about storing in something that is `const'. */
+/* Give an error for storing in something that is 'const'. */
-void
-readonly_error (tree arg, const char *msgid)
+static void
+readonly_error (tree arg, enum lvalue_use use)
{
+ gcc_assert (use == lv_assign || use == lv_increment || use == lv_decrement);
+ /* Using this macro rather than (for example) arrays of messages
+ ensures that all the format strings are checked at compile
+ time. */
+#define READONLY_MSG(A, I, D) (use == lv_assign \
+ ? (A) \
+ : (use == lv_increment ? (I) : (D)))
if (TREE_CODE (arg) == COMPONENT_REF)
{
if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0))))
- readonly_error (TREE_OPERAND (arg, 0), msgid);
+ readonly_error (TREE_OPERAND (arg, 0), use);
else
- error ("%s of read-only member %qs", _(msgid),
+ error (READONLY_MSG (N_("assignment of read-only member %qs"),
+ N_("increment of read-only member %qs"),
+ N_("decrement of read-only member %qs")),
IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1))));
}
else if (TREE_CODE (arg) == VAR_DECL)
- error ("%s of read-only variable %qs", _(msgid),
+ error (READONLY_MSG (N_("assignment of read-only variable %qs"),
+ N_("increment of read-only variable %qs"),
+ N_("decrement of read-only variable %qs")),
IDENTIFIER_POINTER (DECL_NAME (arg)));
else
- error ("%s of read-only location", _(msgid));
+ error (READONLY_MSG (N_("assignment of read-only location"),
+ N_("increment of read-only location"),
+ N_("decrement of read-only location")));
}
\f
/* Mark EXP saying that we need to be able to take the
case COMPONENT_REF:
if (DECL_C_BIT_FIELD (TREE_OPERAND (x, 1)))
{
- error ("cannot take address of bit-field %qs",
- IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
+ error
+ ("cannot take address of bit-field %qD", TREE_OPERAND (x, 1));
return false;
}
{
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
{
- error ("global register variable %qs used in nested function",
- IDENTIFIER_POINTER (DECL_NAME (x)));
+ error
+ ("global register variable %qD used in nested function", x);
return false;
}
- pedwarn ("register variable %qs used in nested function",
- IDENTIFIER_POINTER (DECL_NAME (x)));
+ pedwarn ("register variable %qD used in nested function", x);
}
else if (C_DECL_REGISTER (x))
{
if (TREE_PUBLIC (x) || TREE_STATIC (x) || DECL_EXTERNAL (x))
- {
- error ("address of global register variable %qs requested",
- IDENTIFIER_POINTER (DECL_NAME (x)));
- return false;
- }
-
- pedwarn ("address of register variable %qs requested",
- IDENTIFIER_POINTER (DECL_NAME (x)));
+ error ("address of global register variable %qD requested", x);
+ else
+ error ("address of register variable %qD requested", x);
+ return false;
}
/* drops in */
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE
|| code2 == COMPLEX_TYPE))
{
- result_type = common_type (type1, type2);
+ result_type = c_common_type (type1, type2);
/* If -Wsign-compare, warn here if type1 and type2 have
different signedness. We'll promote the signed to unsigned
/* Do not warn if the result type is signed, since the
signed type will only be chosen if it can represent
all the values of the unsigned type. */
- if (! TYPE_UNSIGNED (result_type))
+ if (!TYPE_UNSIGNED (result_type))
/* OK */;
/* Do not warn if the signed quantity is an unsuffixed
integer literal (or some static constant expression
}
else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE)
{
- if (! integer_zerop (op2))
+ if (!integer_zerop (op2))
pedwarn ("pointer/integer type mismatch in conditional expression");
else
{
/* Convert arrays and functions to pointers. */
expr2 = default_function_array_conversion (expr2);
- /* Don't let (0, 0) be null pointer constant. */
- if (integer_zerop (expr2))
- expr2 = non_lvalue (expr2);
-
- if (! TREE_SIDE_EFFECTS (expr1))
+ if (!TREE_SIDE_EFFECTS (expr1))
{
/* The left-hand operand of a comma expression is like an expression
statement: with -Wextra or -Wunused, we should warn if it doesn't have
any side-effects, unless it was explicitly cast to (void). */
if (warn_unused_value
- && ! (TREE_CODE (expr1) == CONVERT_EXPR
+ && !(TREE_CODE (expr1) == CONVERT_EXPR
&& VOID_TYPE_P (TREE_TYPE (expr1))))
warning ("left-hand operand of comma expression has no effect");
}
pedwarn ("ISO C forbids conversion of object pointer to function pointer type");
ovalue = value;
- /* Replace a nonvolatile const static variable with its value. */
- if (optimize && TREE_CODE (value) == VAR_DECL)
- value = decl_constant_value (value);
value = convert (type, value);
/* Ignore any integer overflow caused by the cast. */
}
}
- /* Don't let (void *) (FOO *) 0 be a null pointer constant. */
- if (TREE_CODE (value) == INTEGER_CST
- && TREE_CODE (expr) == INTEGER_CST
- && TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE)
- value = non_lvalue (value);
-
/* Don't let a cast be an lvalue. */
if (value == expr)
value = non_lvalue (value);
newrhs = build_binary_op (modifycode, lhs, rhs, 1);
}
- if (!lvalue_or_else (lhs, "invalid lvalue in assignment"))
+ if (!lvalue_or_else (lhs, lv_assign))
return error_mark_node;
- /* Warn about storing in something that is `const'. */
+ /* Give an error for storing in something that is 'const'. */
if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
|| ((TREE_CODE (lhstype) == RECORD_TYPE
|| TREE_CODE (lhstype) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (lhstype)))
- readonly_error (lhs, "assignment");
+ readonly_error (lhs, lv_assign);
/* If storing into a structure or union member,
it has probably been given type `int'.
/* Convert new value to destination type. */
- newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"),
+ newrhs = convert_for_assignment (lhstype, newrhs, ic_assign,
NULL_TREE, NULL_TREE, 0);
if (TREE_CODE (newrhs) == ERROR_MARK)
return error_mark_node;
- /* Scan operands */
+ /* Scan operands. */
result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs);
TREE_SIDE_EFFECTS (result) = 1;
if (olhstype == TREE_TYPE (result))
return result;
- return convert_for_assignment (olhstype, result, _("assignment"),
+ return convert_for_assignment (olhstype, result, ic_assign,
NULL_TREE, NULL_TREE, 0);
}
\f
The real work of conversion is done by `convert'.
The purpose of this function is to generate error messages
for assignments that are not allowed in C.
- ERRTYPE is a string to use in error messages:
- "assignment", "return", etc. If it is null, this is parameter passing
- for a function call (and different error messages are output).
+ ERRTYPE says whether it is argument passing, assignment,
+ initialization or return.
- FUNNAME is the name of the function being called,
- as an IDENTIFIER_NODE, or null.
+ FUNCTION is a tree for the function being called.
PARMNUM is the number of the argument, for printing in error messages. */
static tree
-convert_for_assignment (tree type, tree rhs, const char *errtype,
- tree fundecl, tree funname, int parmnum)
+convert_for_assignment (tree type, tree rhs, enum impl_conv errtype,
+ tree fundecl, tree function, int parmnum)
{
enum tree_code codel = TREE_CODE (type);
tree rhstype;
enum tree_code coder;
+ tree rname = NULL_TREE;
+
+ if (errtype == ic_argpass || errtype == ic_argpass_nonproto)
+ {
+ tree selector;
+ /* Change pointer to function to the function itself for
+ diagnostics. */
+ if (TREE_CODE (function) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
+ function = TREE_OPERAND (function, 0);
+
+ /* Handle an ObjC selector specially for diagnostics. */
+ selector = objc_message_selector ();
+ rname = function;
+ if (selector && parmnum > 2)
+ {
+ rname = selector;
+ parmnum -= 2;
+ }
+ }
+
+ /* 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(AR, AS, IN, RE) \
+ do { \
+ switch (errtype) \
+ { \
+ case ic_argpass: \
+ pedwarn (AR, parmnum, rname); \
+ break; \
+ case ic_argpass_nonproto: \
+ warning (AR, parmnum, rname); \
+ break; \
+ case ic_assign: \
+ pedwarn (AS); \
+ break; \
+ case ic_init: \
+ pedwarn (IN); \
+ break; \
+ case ic_return: \
+ pedwarn (RE); \
+ break; \
+ default: \
+ gcc_unreachable (); \
+ } \
+ } while (0)
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
/* Do not use STRIP_NOPS here. We do not want an enumerator
if (coder == VOID_TYPE)
{
+ /* Except for passing an argument to an unprototyped function,
+ this is a constraint violation. When passing an argument to
+ an unprototyped function, it is compile-time undefined;
+ making it a constraint in that case was rejected in
+ DR#252. */
error ("void value not ignored as it ought to be");
return error_mark_node;
}
/* Conversion to a transparent union from its member types.
This applies only to function arguments. */
- else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type) && ! errtype)
+ else if (codel == UNION_TYPE && TYPE_TRANSPARENT_UNION (type)
+ && (errtype == ic_argpass || errtype == ic_argpass_nonproto))
{
tree memb_types;
tree marginal_memb_type = 0;
break;
/* Keep looking for a better type, but remember this one. */
- if (! marginal_memb_type)
+ if (!marginal_memb_type)
marginal_memb_type = memb_type;
}
}
if (memb_types || marginal_memb_type)
{
- if (! memb_types)
+ if (!memb_types)
{
/* We have only a marginally acceptable member type;
it needs a warning. */
function where an ordinary one is wanted, but not
vice-versa. */
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
- warn_for_assignment ("%s makes qualified function pointer from unqualified",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE "
+ "makes qualified function "
+ "pointer from unqualified"),
+ N_("assignment makes qualified "
+ "function pointer from "
+ "unqualified"),
+ N_("initialization makes qualified "
+ "function pointer from "
+ "unqualified"),
+ N_("return makes qualified function "
+ "pointer from unqualified"));
}
else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
- warn_for_assignment ("%s discards qualifiers from pointer target type",
- errtype, funname,
- parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards "
+ "qualifiers from pointer target type"),
+ N_("assignment discards qualifiers "
+ "from pointer target type"),
+ N_("initialization discards qualifiers "
+ "from pointer target type"),
+ N_("return discards qualifiers from "
+ "pointer target type"));
}
- if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl))
+ if (pedantic && !DECL_IN_SYSTEM_HEADER (fundecl))
pedwarn ("ISO C prohibits argument conversion to union type");
return build1 (NOP_EXPR, type, rhs);
{
tree ttl = TREE_TYPE (type);
tree ttr = TREE_TYPE (rhstype);
+ tree mvl = ttl;
+ tree mvr = ttr;
bool is_opaque_pointer;
int target_cmp = 0; /* Cache comp_target_types () result. */
+ if (TREE_CODE (mvl) != ARRAY_TYPE)
+ mvl = TYPE_MAIN_VARIANT (mvl);
+ if (TREE_CODE (mvr) != ARRAY_TYPE)
+ mvr = TYPE_MAIN_VARIANT (mvr);
/* Opaque pointers are treated like void pointers. */
is_opaque_pointer = (targetm.vector_opaque_p (type)
|| targetm.vector_opaque_p (rhstype))
if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
|| (target_cmp = comp_target_types (type, rhstype, 0))
|| is_opaque_pointer
- || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
- == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
+ || (c_common_unsigned_type (mvl)
+ == c_common_unsigned_type (mvr)))
{
if (pedantic
&& ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
which are not ANSI null ptr constants. */
&& (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR)
&& TREE_CODE (ttl) == FUNCTION_TYPE)))
- warn_for_assignment ("ISO C forbids %s between function "
- "pointer and %<void *%>",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("ISO C forbids passing argument %d of "
+ "%qE between function pointer "
+ "and %<void *%>"),
+ N_("ISO C forbids assignment between "
+ "function pointer and %<void *%>"),
+ N_("ISO C forbids initialization between "
+ "function pointer and %<void *%>"),
+ N_("ISO C forbids return between function "
+ "pointer and %<void *%>"));
/* Const and volatile mean something different for function types,
so the usual warnings are not appropriate. */
else if (TREE_CODE (ttr) != FUNCTION_TYPE
&& TREE_CODE (ttl) != FUNCTION_TYPE)
{
if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl))
- warn_for_assignment ("%s discards qualifiers from pointer target type",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE discards "
+ "qualifiers from pointer target type"),
+ N_("assignment discards qualifiers "
+ "from pointer target type"),
+ N_("initialization discards qualifiers "
+ "from pointer target type"),
+ N_("return discards qualifiers from "
+ "pointer target type"));
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
|| target_cmp)
;
/* If there is a mismatch, do warn. */
- else
- warn_for_assignment ("pointer targets in %s differ in signedness",
- errtype, funname, parmnum);
+ else if (warn_pointer_sign)
+ WARN_FOR_ASSIGNMENT (N_("pointer targets in passing argument "
+ "%d of %qE differ in signedness"),
+ N_("pointer targets in assignment "
+ "differ in signedness"),
+ N_("pointer targets in initialization "
+ "differ in signedness"),
+ N_("pointer targets in return differ "
+ "in signedness"));
}
else if (TREE_CODE (ttl) == FUNCTION_TYPE
&& TREE_CODE (ttr) == FUNCTION_TYPE)
it is okay to use a const or volatile function
where an ordinary one is wanted, but not vice-versa. */
if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr))
- warn_for_assignment ("%s makes qualified function pointer from unqualified",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes "
+ "qualified function pointer "
+ "from unqualified"),
+ N_("assignment makes qualified function "
+ "pointer from unqualified"),
+ N_("initialization makes qualified "
+ "function pointer from unqualified"),
+ N_("return makes qualified function "
+ "pointer from unqualified"));
}
}
else
- warn_for_assignment ("%s from incompatible pointer type",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE from "
+ "incompatible pointer type"),
+ N_("assignment from incompatible pointer type"),
+ N_("initialization from incompatible "
+ "pointer type"),
+ N_("return from incompatible pointer type"));
return convert (type, rhs);
}
else if (codel == POINTER_TYPE && coder == ARRAY_TYPE)
{
+ /* ??? This should not be an error when inlining calls to
+ unprototyped functions. */
error ("invalid use of non-lvalue array");
return error_mark_node;
}
/* An explicit constant 0 can convert to a pointer,
or one that results from arithmetic, even including
a cast to integer type. */
- if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))
+ if (!(TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))
&&
- ! (TREE_CODE (rhs) == NOP_EXPR
- && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
- && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
- && integer_zerop (TREE_OPERAND (rhs, 0))))
- warn_for_assignment ("%s makes pointer from integer without a cast",
- errtype, funname, parmnum);
+ !(TREE_CODE (rhs) == NOP_EXPR
+ && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE
+ && TREE_CODE (TREE_OPERAND (rhs, 0)) == INTEGER_CST
+ && integer_zerop (TREE_OPERAND (rhs, 0))))
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes "
+ "pointer from integer without a cast"),
+ N_("assignment makes pointer from integer "
+ "without a cast"),
+ N_("initialization makes pointer from "
+ "integer without a cast"),
+ N_("return makes pointer from integer "
+ "without a cast"));
return convert (type, rhs);
}
else if (codel == INTEGER_TYPE && coder == POINTER_TYPE)
{
- warn_for_assignment ("%s makes integer from pointer without a cast",
- errtype, funname, parmnum);
+ WARN_FOR_ASSIGNMENT (N_("passing argument %d of %qE makes integer "
+ "from pointer without a cast"),
+ N_("assignment makes integer from pointer "
+ "without a cast"),
+ N_("initialization makes integer from pointer "
+ "without a cast"),
+ N_("return makes integer from pointer "
+ "without a cast"));
return convert (type, rhs);
}
else if (codel == BOOLEAN_TYPE && coder == POINTER_TYPE)
return convert (type, rhs);
- if (!errtype)
+ switch (errtype)
{
- if (funname)
- {
- tree selector = objc_message_selector ();
-
- if (selector && parmnum > 2)
- error ("incompatible type for argument %d of %qs",
- parmnum - 2, IDENTIFIER_POINTER (selector));
- else
- error ("incompatible type for argument %d of %qs",
- parmnum, IDENTIFIER_POINTER (funname));
- }
- else
- error ("incompatible type for argument %d of indirect function call",
- parmnum);
+ case ic_argpass:
+ case ic_argpass_nonproto:
+ /* ??? This should not be an error when inlining calls to
+ unprototyped functions. */
+ error ("incompatible type for argument %d of %qE", parmnum, rname);
+ break;
+ case ic_assign:
+ error ("incompatible types in assignment");
+ break;
+ case ic_init:
+ error ("incompatible types in initialization");
+ break;
+ case ic_return:
+ error ("incompatible types in return");
+ break;
+ default:
+ gcc_unreachable ();
}
- else
- error ("incompatible types in %s", errtype);
return error_mark_node;
}
/* If FN was prototyped, the value has been converted already
in convert_arguments. */
- if (! value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
+ if (!value || TYPE_ARG_TYPES (TREE_TYPE (fn)))
return value;
type = TREE_TYPE (parm);
ret = convert_for_assignment (type, value,
- (char *) 0 /* arg passing */, fn,
- DECL_NAME (fn), argnum);
+ ic_argpass_nonproto, fn,
+ fn, argnum);
if (targetm.calls.promote_prototypes (TREE_TYPE (fn))
&& INTEGRAL_TYPE_P (type)
&& (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)))
ret = default_conversion (ret);
return ret;
}
-
-/* Print a warning using MSGID.
- It gets OPNAME as its one parameter.
- if OPNAME is null and ARGNUM is 0, it is replaced by "passing arg of `FUNCTION'".
- Otherwise if OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
- FUNCTION and ARGNUM are handled specially if we are building an
- Objective-C selector. */
-
-static void
-warn_for_assignment (const char *msgid, const char *opname, tree function,
- int argnum)
-{
- if (opname == 0)
- {
- tree selector = objc_message_selector ();
- char * new_opname;
-
- if (selector && argnum > 2)
- {
- function = selector;
- argnum -= 2;
- }
- if (argnum == 0)
- {
- if (function)
- {
- /* Function name is known; supply it. */
- const char *const argstring = _("passing arg of '%s'");
- new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + strlen (argstring) + 1 + 1);
- sprintf (new_opname, argstring,
- IDENTIFIER_POINTER (function));
- }
- else
- {
- /* Function name unknown (call through ptr). */
- const char *const argnofun = _("passing arg of pointer to function");
- new_opname = (char *) alloca (strlen (argnofun) + 1 + 1);
- sprintf (new_opname, argnofun);
- }
- }
- else if (function)
- {
- /* Function name is known; supply it. */
- const char *const argstring = _("passing arg %d of '%s'");
- new_opname = (char *) alloca (IDENTIFIER_LENGTH (function)
- + strlen (argstring) + 1 + 25 /*%d*/ + 1);
- sprintf (new_opname, argstring, argnum,
- IDENTIFIER_POINTER (function));
- }
- else
- {
- /* Function name unknown (call through ptr); just give arg number. */
- const char *const argnofun = _("passing arg %d of pointer to function");
- new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1);
- sprintf (new_opname, argnofun, argnum);
- }
- opname = new_opname;
- }
- pedwarn (msgid, opname);
-}
\f
/* If VALUE is a compound expr all of whose expressions are constant, then
return its value. Otherwise, return error_mark_node.
/* Store the expression if valid; else report error. */
if (warn_traditional && !in_system_header
- && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && ! TREE_STATIC (decl))
+ && AGGREGATE_TYPE_P (TREE_TYPE (decl)) && !TREE_STATIC (decl))
warning ("traditional C rejects automatic aggregate initialization");
DECL_INITIAL (decl) = value;
/* Build a VECTOR_CST from a *constant* vector constructor. If the
vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
below and handle as a constructor. */
- if (code == VECTOR_TYPE
- && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE
- && vector_types_convertible_p (TREE_TYPE (inside_init), type)
- && TREE_CONSTANT (inside_init))
- {
- if (TREE_CODE (inside_init) == VECTOR_CST
- && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
- TYPE_MAIN_VARIANT (type)))
- return inside_init;
- else
- return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
- }
+ if (code == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (inside_init)) == VECTOR_TYPE
+ && vector_types_convertible_p (TREE_TYPE (inside_init), type)
+ && TREE_CONSTANT (inside_init))
+ {
+ if (TREE_CODE (inside_init) == VECTOR_CST
+ && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+ TYPE_MAIN_VARIANT (type)))
+ return inside_init;
+
+ if (TREE_CODE (inside_init) == CONSTRUCTOR)
+ {
+ tree link;
+
+ /* Iterate through elements and check if all constructor
+ elements are *_CSTs. */
+ for (link = CONSTRUCTOR_ELTS (inside_init);
+ link;
+ link = TREE_CHAIN (link))
+ if (! CONSTANT_CLASS_P (TREE_VALUE (link)))
+ break;
+
+ if (link == NULL)
+ return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
+ }
+ }
/* Any type can be initialized
from an expression of the same type, optionally with braces. */
for arrays and functions. We must not call it in the
case where inside_init is a null pointer constant. */
inside_init
- = convert_for_assignment (type, init, _("initialization"),
+ = convert_for_assignment (type, init, ic_init,
NULL_TREE, NULL_TREE, 0);
/* Check to see if we have already given an error message. */
if (inside_init == error_mark_node)
;
- else if (require_constant && ! TREE_CONSTANT (inside_init))
+ else if (require_constant && !TREE_CONSTANT (inside_init))
{
error_init ("initializer element is not constant");
inside_init = error_mark_node;
/* The SPELLING_DEPTH of this constructor. */
static int constructor_depth;
-/* 0 if implicitly pushing constructor levels is allowed. */
-int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages. */
-
/* DECL node for which an initializer is being read.
0 means we are reading a constructor expression
such as (struct foo) {...}. */
constructor_designated = 0;
constructor_top_level = top_level;
- if (decl != 0)
+ if (decl != 0 && decl != error_mark_node)
{
require_constant_value = TREE_STATIC (decl);
require_constant_elements
TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
}
else
- constructor_index = bitsize_zero_node;
+ {
+ constructor_index = bitsize_zero_node;
+ constructor_max_index = NULL_TREE;
+ }
constructor_unfilled_index = constructor_index;
}
}
else
{
- warning_init ("braces around scalar initializer");
+ if (constructor_type != error_mark_node)
+ warning_init ("braces around scalar initializer");
constructor_fields = constructor_type;
constructor_unfilled_fields = constructor_type;
}
if (constructor_type && constructor_fields
&& TREE_CODE (constructor_type) == ARRAY_TYPE
&& TYPE_DOMAIN (constructor_type)
- && ! TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
+ && !TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)))
{
/* Silently discard empty initializations. The parser will
already have pedwarned for empty brackets. */
{
/* Do not warn for flexible array members or zero-length arrays. */
while (constructor_unfilled_fields
- && (! DECL_SIZE (constructor_unfilled_fields)
+ && (!DECL_SIZE (constructor_unfilled_fields)
|| integer_zerop (DECL_SIZE (constructor_unfilled_fields))))
constructor_unfilled_fields = TREE_CHAIN (constructor_unfilled_fields);
return 0;
}
- if (constructor_no_implicit)
- {
- error_init ("initialization designators may not nest");
- return 1;
- }
-
switch (TREE_CODE (constructor_type))
{
case RECORD_TYPE:
output_init_element (tree value, bool strict_string, tree type, tree field,
int pending)
{
- if (type == error_mark_node)
+ if (type == error_mark_node || value == error_mark_node)
{
constructor_erroneous = 1;
return;
/* Ordinarily return, but not if we want to output all
and there are elements left. */
- if (! (all && next != 0))
+ if (!(all && next != 0))
return;
/* If it's not incremental, just skip over the gap, so that after
value.value = orig_value;
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
- else if (value.value != 0 && !constructor_no_implicit
+ else if (value.value != 0
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
value.value = orig_value;
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
- else if (value.value != 0 && !constructor_no_implicit
+ else if (value.value != 0
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != fieldtype
&& (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE
value.value = orig_value;
/* Otherwise, if we have come to a subaggregate,
and we don't have an element of its type, push into it. */
- else if (value.value != 0 && !constructor_no_implicit
+ else if (value.value != 0
&& value.value != error_mark_node
&& TYPE_MAIN_VARIANT (TREE_TYPE (value.value)) != elttype
&& (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE
/* Handle the sole element allowed in a braced initializer
for a scalar variable. */
- else if (constructor_fields == 0)
+ else if (constructor_type != error_mark_node
+ && constructor_fields == 0)
{
pedwarn_init ("excess elements in scalar initializer");
break;
tree args;
int i;
const char *constraint;
+ const char **oconstraints;
bool allows_mem, allows_reg, is_inout;
- int ninputs;
- int noutputs;
+ int ninputs, noutputs;
ninputs = list_length (inputs);
noutputs = list_length (outputs);
+ oconstraints = (const char **) alloca (noutputs * sizeof (const char *));
+
+ string = resolve_asm_operand_names (string, outputs, inputs);
/* Remove output conversions that change the type but not the mode. */
for (i = 0, tail = outputs; tail; ++i, tail = TREE_CHAIN (tail))
{
tree output = TREE_VALUE (tail);
+
+ /* ??? Really, this should not be here. Users should be using a
+ proper lvalue, dammit. But there's a long history of using casts
+ in the output operands. In cases like longlong.h, this becomes a
+ primitive form of typechecking -- if the cast can be removed, then
+ the output operand had a type of the proper width; otherwise we'll
+ get an error. Gross, but ... */
STRIP_NOPS (output);
- TREE_VALUE (tail) = output;
- lvalue_or_else (output, "invalid lvalue in asm statement");
+
+ if (!lvalue_or_else (output, lv_asm))
+ output = error_mark_node;
constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
+ oconstraints[i] = constraint;
- if (!parse_output_constraint (&constraint, i, ninputs, noutputs,
- &allows_mem, &allows_reg, &is_inout))
- {
- /* By marking this operand as erroneous, we will not try
- to process this operand again in expand_asm_operands. */
- TREE_VALUE (tail) = error_mark_node;
- continue;
- }
+ if (parse_output_constraint (&constraint, i, ninputs, noutputs,
+ &allows_mem, &allows_reg, &is_inout))
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && !c_mark_addressable (output))
+ output = error_mark_node;
+ }
+ else
+ output = error_mark_node;
- /* If the operand is a DECL that is going to end up in
- memory, assume it is addressable. This is a bit more
- conservative than it would ideally be; the exact test is
- buried deep in expand_asm_operands and depends on the
- DECL_RTL for the OPERAND -- which we don't have at this
- point. */
- if (!allows_reg && DECL_P (output))
- c_mark_addressable (output);
+ TREE_VALUE (tail) = output;
}
/* Perform default conversions on array and function inputs.
Don't do this for other types as it would screw up operands
expected to be in memory. */
- for (tail = inputs; tail; tail = TREE_CHAIN (tail))
- TREE_VALUE (tail) = default_function_array_conversion (TREE_VALUE (tail));
+ for (i = 0, tail = inputs; tail; ++i, tail = TREE_CHAIN (tail))
+ {
+ tree input;
+
+ constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (tail)));
+ input = TREE_VALUE (tail);
+
+ input = default_function_array_conversion (input);
+
+ if (parse_input_constraint (&constraint, i, ninputs, noutputs, 0,
+ oconstraints, &allows_mem, &allows_reg))
+ {
+ /* If the operand is going to end up in memory,
+ mark it addressable. */
+ if (!allows_reg && allows_mem)
+ {
+ /* Strip the nops as we allow this case. FIXME, this really
+ should be rejected or made deprecated. */
+ STRIP_NOPS (input);
+ if (!c_mark_addressable (input))
+ input = error_mark_node;
+ }
+ }
+ else
+ input = error_mark_node;
+
+ TREE_VALUE (tail) = input;
+ }
args = build_stmt (ASM_EXPR, string, outputs, inputs, clobbers);
ASM_VOLATILE_P (args) = 1;
ASM_INPUT_P (args) = 1;
}
+
return args;
}
\f
}
else
{
- tree t = convert_for_assignment (valtype, retval, _("return"),
+ tree t = convert_for_assignment (valtype, retval, ic_return,
NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
tree inner;
{
tree op1 = TREE_OPERAND (inner, 1);
- while (! POINTER_TYPE_P (TREE_TYPE (op1))
+ while (!POINTER_TYPE_P (TREE_TYPE (op1))
&& (TREE_CODE (op1) == NOP_EXPR
|| TREE_CODE (op1) == NON_LVALUE_EXPR
|| TREE_CODE (op1) == CONVERT_EXPR))
inner = TREE_OPERAND (inner, 0);
if (DECL_P (inner)
- && ! DECL_EXTERNAL (inner)
- && ! TREE_STATIC (inner)
+ && !DECL_EXTERNAL (inner)
+ && !TREE_STATIC (inner)
&& DECL_CONTEXT (inner) == current_function_decl)
warning ("function returns address of local variable");
break;
code = TREE_CODE (TREE_TYPE (exp));
orig_type = TREE_TYPE (exp);
- if (! INTEGRAL_TYPE_P (orig_type)
+ if (!INTEGRAL_TYPE_P (orig_type)
&& code != ERROR_MARK)
{
error ("switch quantity not an integer");
exp = integer_zero_node;
+ orig_type = error_mark_node;
}
else
{
/* Add this new SWITCH_STMT to the stack. */
cs = XNEW (struct c_switch);
- cs->switch_stmt = build_stmt ((enum tree_code) SWITCH_STMT, exp, NULL_TREE,
- orig_type);
+ cs->switch_stmt = build_stmt (SWITCH_STMT, exp, NULL_TREE, orig_type);
cs->orig_type = orig_type;
cs->cases = splay_tree_new (case_compare, NULL, NULL);
cs->next = c_switch_stack;
if (c_switch_stack)
{
label = c_add_case_label (c_switch_stack->cases,
- SWITCH_COND (c_switch_stack->switch_stmt),
+ SWITCH_STMT_COND (c_switch_stack->switch_stmt),
c_switch_stack->orig_type,
low_value, high_value);
if (label == error_mark_node)
{
struct c_switch *cs = c_switch_stack;
- SWITCH_BODY (cs->switch_stmt) = body;
+ SWITCH_STMT_BODY (cs->switch_stmt) = body;
/* Emit warnings as needed. */
c_do_switch_warnings (cs->cases, cs->switch_stmt);
{
tree entry = NULL, exit = NULL, t;
- /* Detect do { ... } while (0) and don't generate loop construct. */
- if (cond && !cond_is_first && integer_zerop (cond))
- cond = NULL;
- if (cond_is_first || cond)
+ /* If the condition is zero don't generate a loop construct. */
+ if (cond && integer_zerop (cond))
+ {
+ if (cond_is_first)
+ {
+ t = build_and_jump (&blab);
+ SET_EXPR_LOCATION (t, start_locus);
+ add_stmt (t);
+ }
+ }
+ else
{
tree top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
then we just build a jump back to the top. */
exit = build_and_jump (&LABEL_EXPR_LABEL (top));
- if (cond)
+ if (cond && !integer_nonzerop (cond))
{
/* Canonicalize the loop condition to the end. This means
generating a branch to the loop condition. Reuse the
tree
c_finish_bc_stmt (tree *label_p, bool is_break)
{
+ bool skip;
tree label = *label_p;
+ /* In switch statements break is sometimes stylistically used after
+ a return statement. This can lead to spurious warnings about
+ control reaching the end of a non-void function when it is
+ inlined. Note that we are calling block_may_fallthru with
+ language specific tree nodes; this works because
+ block_may_fallthru returns true when given something it does not
+ understand. */
+ skip = !block_may_fallthru (cur_stmt_list);
+
if (!label)
- *label_p = label = create_artificial_label ();
+ {
+ if (!skip)
+ *label_p = label = create_artificial_label ();
+ }
else if (TREE_CODE (label) != LABEL_DECL)
{
if (is_break)
return NULL_TREE;
}
+ if (skip)
+ return NULL_TREE;
+
return add_stmt (build1 (GOTO_EXPR, void_type_node, label));
}
dividing by something we know != -1. */
shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
|| (TREE_CODE (op1) == INTEGER_CST
- && ! integer_all_onesp (op1)));
+ && !integer_all_onesp (op1)));
common = 1;
}
break;
only if unsigned or if dividing by something we know != -1. */
shorten = (TYPE_UNSIGNED (TREE_TYPE (orig_op0))
|| (TREE_CODE (op1) == INTEGER_CST
- && ! integer_all_onesp (op1)));
+ && !integer_all_onesp (op1)));
common = 1;
}
break;
warning ("right shift count is negative");
else
{
- if (! integer_zerop (op1))
+ if (!integer_zerop (op1))
short_shift = 1;
if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
}
break;
- case RROTATE_EXPR:
- case LROTATE_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
- {
- if (TREE_CODE (op1) == INTEGER_CST && skip_evaluation == 0)
- {
- if (tree_int_cst_sgn (op1) < 0)
- warning ("shift count is negative");
- else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0)
- warning ("shift count >= width of type");
- }
-
- /* Use the type of the value to be shifted. */
- result_type = type0;
- /* Convert the shift-count to an integer, regardless of size
- of value being shifted. */
- if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node)
- op1 = convert (integer_type_node, op1);
- /* Avoid converting op1 to result_type later. */
- converted = 1;
- }
- break;
-
case EQ_EXPR:
case NE_EXPR:
if (warn_float_equal && (code0 == REAL_TYPE || code1 == REAL_TYPE))
}
break;
- case MAX_EXPR:
- case MIN_EXPR:
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE)
- && (code1 == INTEGER_TYPE || code1 == REAL_TYPE))
- shorten = 1;
- else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
- {
- if (comp_target_types (type0, type1, 1))
- {
- result_type = common_pointer_type (type0, type1);
- if (pedantic
- && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
- pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
- }
- else
- {
- result_type = ptr_type_node;
- pedwarn ("comparison of distinct pointer types lacks a cast");
- }
- }
- break;
-
case LE_EXPR:
case GE_EXPR:
case LT_EXPR:
}
break;
- case UNORDERED_EXPR:
- case ORDERED_EXPR:
- case UNLT_EXPR:
- case UNLE_EXPR:
- case UNGT_EXPR:
- case UNGE_EXPR:
- case UNEQ_EXPR:
- case LTGT_EXPR:
- build_type = integer_type_node;
- if (code0 != REAL_TYPE || code1 != REAL_TYPE)
- {
- error ("unordered comparison on non-floating point argument");
- return error_mark_node;
- }
- common = 1;
- break;
-
default:
- break;
+ gcc_unreachable ();
}
if (code0 == ERROR_MARK || code1 == ERROR_MARK)
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
if (shorten || common || short_compare)
- result_type = common_type (type0, type1);
+ result_type = c_common_type (type0, type1);
/* For certain operations (which identify themselves by shorten != 0)
if both args were extended from the same smaller type,
&& (unsigned0 || !uns))
result_type
= c_common_signed_or_unsigned_type
- (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ (unsigned0, c_common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1))
if (warn_sign_compare && skip_evaluation == 0)
{
- int op0_signed = ! TYPE_UNSIGNED (TREE_TYPE (orig_op0));
- int op1_signed = ! TYPE_UNSIGNED (TREE_TYPE (orig_op1));
+ int op0_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op0));
+ int op1_signed = !TYPE_UNSIGNED (TREE_TYPE (orig_op1));
int unsignedp0, unsignedp1;
tree primop0 = get_narrower (op0, &unsignedp0);
tree primop1 = get_narrower (op1, &unsignedp1);
Do not warn if the comparison is being done in a signed type,
since the signed type will only be chosen if it can represent
all the values of the unsigned type. */
- if (! TYPE_UNSIGNED (result_type))
+ if (!TYPE_UNSIGNED (result_type))
/* OK */;
/* Do not warn if both operands are the same signedness. */
else if (op0_signed == op1_signed)
else if (TREE_CODE (uop) == INTEGER_CST
&& TREE_CODE (TREE_TYPE (uop)) == ENUMERAL_TYPE
&& int_fits_type_p
- (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+ (TYPE_MAX_VALUE (TREE_TYPE (uop)),
c_common_signed_type (result_type)))
/* OK */;
else
if (bits < TYPE_PRECISION (result_type)
&& bits < HOST_BITS_PER_WIDE_INT && unsignedp)
{
- mask = (~ (HOST_WIDE_INT) 0) << bits;
+ mask = (~(HOST_WIDE_INT) 0) << bits;
if ((mask & constant) != mask)
warning ("comparison of promoted ~unsigned with constant");
}
return error_mark_node;
}
- if (! converted)
+ if (!converted)
{
if (TREE_TYPE (op0) != result_type)
op0 = convert (result_type, op0);