summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/c-typeck.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/c-typeck.c')
-rw-r--r--contrib/gcc/c-typeck.c547
1 files changed, 267 insertions, 280 deletions
diff --git a/contrib/gcc/c-typeck.c b/contrib/gcc/c-typeck.c
index 17e3144..21cc510 100644
--- a/contrib/gcc/c-typeck.c
+++ b/contrib/gcc/c-typeck.c
@@ -51,7 +51,7 @@ static int missing_braces_mentioned;
static int undeclared_variable_notice;
static tree qualify_type PARAMS ((tree, tree));
-static int comp_target_types PARAMS ((tree, tree));
+static int comp_target_types PARAMS ((tree, tree, int));
static int function_types_compatible_p PARAMS ((tree, tree));
static int type_lists_compatible_p PARAMS ((tree, tree));
static tree decl_constant_value_for_broken_optimization PARAMS ((tree));
@@ -73,7 +73,7 @@ static void push_array_bounds PARAMS ((int));
static int spelling_length PARAMS ((void));
static char *print_spelling PARAMS ((char *));
static void warning_init PARAMS ((const char *));
-static tree digest_init PARAMS ((tree, tree, int, int));
+static tree digest_init PARAMS ((tree, tree, int));
static void output_init_element PARAMS ((tree, tree, tree, int));
static void output_pending_init_elements PARAMS ((int));
static int set_designator PARAMS ((int));
@@ -99,7 +99,7 @@ require_complete_type (value)
if (COMPLETE_TYPE_P (type))
return value;
- incomplete_type_error (value, type);
+ c_incomplete_type_error (value, type);
return error_mark_node;
}
@@ -108,7 +108,7 @@ require_complete_type (value)
and TYPE is the type that was invalid. */
void
-incomplete_type_error (value, type)
+c_incomplete_type_error (value, type)
tree value;
tree type;
{
@@ -173,6 +173,28 @@ incomplete_type_error (value, type)
}
}
+/* Given a type, apply default promotions wrt unnamed function
+ arguments and return the new type. */
+
+tree
+c_type_promotes_to (type)
+ tree type;
+{
+ if (TYPE_MAIN_VARIANT (type) == float_type_node)
+ return double_type_node;
+
+ if (c_promoting_integer_type_p (type))
+ {
+ /* Preserve unsignedness if not really getting any wider. */
+ if (TREE_UNSIGNED (type)
+ && (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+ return unsigned_type_node;
+ return integer_type_node;
+ }
+
+ return type;
+}
+
/* Return a variant of TYPE which has all the type qualifiers of LIKE
as well as those of TYPE. */
@@ -216,9 +238,9 @@ common_type (t1, t2)
/* Treat an enum type as the unsigned integer type of the same width. */
if (TREE_CODE (t1) == ENUMERAL_TYPE)
- t1 = type_for_size (TYPE_PRECISION (t1), 1);
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
if (TREE_CODE (t2) == ENUMERAL_TYPE)
- t2 = type_for_size (TYPE_PRECISION (t2), 1);
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
code1 = TREE_CODE (t1);
code2 = TREE_CODE (t2);
@@ -465,9 +487,9 @@ comptypes (type1, type2)
signedness. */
if (TREE_CODE (t1) == ENUMERAL_TYPE)
- t1 = type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
+ t1 = c_common_type_for_size (TYPE_PRECISION (t1), TREE_UNSIGNED (t1));
if (TREE_CODE (t2) == ENUMERAL_TYPE)
- t2 = type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
+ t2 = c_common_type_for_size (TYPE_PRECISION (t2), TREE_UNSIGNED (t2));
if (t1 == t2)
return 1;
@@ -546,7 +568,7 @@ comptypes (type1, type2)
}
case RECORD_TYPE:
- if (maybe_objc_comptypes (t1, t2, 0) == 1)
+ if (flag_objc && objc_comptypes (t1, t2, 0) == 1)
val = 1;
break;
@@ -557,16 +579,21 @@ comptypes (type1, type2)
}
/* Return 1 if TTL and TTR are pointers to types that are equivalent,
- ignoring their qualifiers. */
+ ignoring their qualifiers. REFLEXIVE is only used by ObjC - set it
+ to 1 or 0 depending if the check of the pointer types is meant to
+ be reflexive or not (typically, assignments are not reflexive,
+ while comparisons are reflexive).
+*/
static int
-comp_target_types (ttl, ttr)
+comp_target_types (ttl, ttr, reflexive)
tree ttl, ttr;
+ int reflexive;
{
int val;
- /* Give maybe_objc_comptypes a crack at letting these types through. */
- if ((val = maybe_objc_comptypes (ttl, ttr, 1)) >= 0)
+ /* 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)),
@@ -658,12 +685,12 @@ type_lists_compatible_p (args1, args2)
So match anything that self-promotes. */
if (TREE_VALUE (args1) == 0)
{
- if (simple_type_promotes_to (TREE_VALUE (args2)) != NULL_TREE)
+ if (c_type_promotes_to (TREE_VALUE (args2)) != TREE_VALUE (args2))
return 0;
}
else if (TREE_VALUE (args2) == 0)
{
- if (simple_type_promotes_to (TREE_VALUE (args1)) != NULL_TREE)
+ if (c_type_promotes_to (TREE_VALUE (args1)) != TREE_VALUE (args1))
return 0;
}
else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
@@ -714,71 +741,6 @@ type_lists_compatible_p (args1, args2)
}
}
-/* Compute the value of the `sizeof' operator. */
-
-tree
-c_sizeof (type)
- tree type;
-{
- enum tree_code code = TREE_CODE (type);
- tree size;
-
- if (code == FUNCTION_TYPE)
- {
- if (pedantic || warn_pointer_arith)
- pedwarn ("sizeof applied to a function type");
- size = size_one_node;
- }
- else if (code == VOID_TYPE)
- {
- if (pedantic || warn_pointer_arith)
- pedwarn ("sizeof applied to a void type");
- size = size_one_node;
- }
- else if (code == ERROR_MARK)
- size = size_one_node;
- else if (!COMPLETE_TYPE_P (type))
- {
- error ("sizeof applied to an incomplete type");
- size = size_zero_node;
- }
- else
- /* Convert in case a char is more than one unit. */
- size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
- size_int (TYPE_PRECISION (char_type_node)
- / BITS_PER_UNIT));
-
- /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
- TYPE_IS_SIZETYPE means that certain things (like overflow) will
- never happen. However, this node should really have type
- `size_t', which is just a typedef for an ordinary integer type. */
- return fold (build1 (NOP_EXPR, size_type_node, size));
-}
-
-tree
-c_sizeof_nowarn (type)
- tree type;
-{
- enum tree_code code = TREE_CODE (type);
- tree size;
-
- if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK)
- size = size_one_node;
- else if (!COMPLETE_TYPE_P (type))
- size = size_zero_node;
- else
- /* Convert in case a char is more than one unit. */
- size = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type),
- size_int (TYPE_PRECISION (char_type_node)
- / BITS_PER_UNIT));
-
- /* SIZE will have an integer type with TYPE_IS_SIZETYPE set.
- TYPE_IS_SIZETYPE means that certain things (like overflow) will
- never happen. However, this node should really have type
- `size_t', which is just a typedef for an ordinary integer type. */
- return fold (build1 (NOP_EXPR, size_type_node, size));
-}
-
/* Compute the size to increment a pointer by. */
tree
@@ -932,7 +894,7 @@ default_function_array_conversion (exp)
is not the target type of the type of the ADDR_EXPR itself.
Question is, can this lossage be avoided? */
adr = build1 (ADDR_EXPR, ptrtype, exp);
- if (mark_addressable (exp) == 0)
+ if (!c_mark_addressable (exp))
return error_mark_node;
TREE_CONSTANT (adr) = staticp (exp);
TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */
@@ -994,12 +956,11 @@ default_conversion (exp)
but convert wide enums to something wider. */
if (code == ENUMERAL_TYPE)
{
- type = type_for_size (MAX (TYPE_PRECISION (type),
- TYPE_PRECISION (integer_type_node)),
- ((flag_traditional
- || (TYPE_PRECISION (type)
- >= TYPE_PRECISION (integer_type_node)))
- && TREE_UNSIGNED (type)));
+ type = c_common_type_for_size (MAX (TYPE_PRECISION (type),
+ TYPE_PRECISION (integer_type_node)),
+ ((TYPE_PRECISION (type)
+ >= TYPE_PRECISION (integer_type_node))
+ && TREE_UNSIGNED (type)));
return convert (type, exp);
}
@@ -1010,26 +971,18 @@ default_conversion (exp)
c_promoting_integer_type_p, otherwise leave it alone. */
&& 0 > compare_tree_int (DECL_SIZE (TREE_OPERAND (exp, 1)),
TYPE_PRECISION (integer_type_node)))
- return convert (flag_traditional && TREE_UNSIGNED (type)
- ? unsigned_type_node : integer_type_node,
- exp);
+ return convert (integer_type_node, exp);
if (c_promoting_integer_type_p (type))
{
- /* Traditionally, unsignedness is preserved in default promotions.
- Also preserve unsignedness if not really getting any wider. */
+ /* Preserve unsignedness if not really getting any wider. */
if (TREE_UNSIGNED (type)
- && (flag_traditional
- || TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)))
+ && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node))
return convert (unsigned_type_node, exp);
return convert (integer_type_node, exp);
}
- if (flag_traditional && !flag_allow_single_precision
- && TYPE_MAIN_VARIANT (type) == float_type_node)
- return convert (double_type_node, exp);
-
if (code == VOID_TYPE)
{
error ("void value not ignored as it ought to be");
@@ -1172,7 +1125,7 @@ build_component_ref (datum, component)
{
if (!COMPLETE_TYPE_P (type))
{
- incomplete_type_error (NULL_TREE, type);
+ c_incomplete_type_error (NULL_TREE, type);
return error_mark_node;
}
@@ -1191,7 +1144,7 @@ build_component_ref (datum, component)
end does it - by giving the anonymous entities each a
separate name and type, and then have build_component_ref
recursively call itself. We can't do that here. */
- for (; field; field = TREE_CHAIN (field))
+ do
{
tree subdatum = TREE_VALUE (field);
@@ -1208,7 +1161,10 @@ build_component_ref (datum, component)
warn_deprecated_use (subdatum);
datum = ref;
+
+ field = TREE_CHAIN (field);
}
+ while (field);
return ref;
}
@@ -1326,7 +1282,7 @@ build_array_ref (array, index)
|| (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
{
- if (mark_addressable (array) == 0)
+ if (!c_mark_addressable (array))
return error_mark_node;
}
/* An array that is indexed by a constant value which is not within
@@ -1337,7 +1293,7 @@ build_array_ref (array, index)
&& TYPE_VALUES (TREE_TYPE (array))
&& ! int_fits_type_p (index, TYPE_VALUES (TREE_TYPE (array))))
{
- if (mark_addressable (array) == 0)
+ if (!c_mark_addressable (array))
return error_mark_node;
}
@@ -1349,7 +1305,7 @@ build_array_ref (array, index)
if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo))
pedwarn ("ISO C forbids subscripting `register' array");
else if (! flag_isoc99 && ! lvalue_p (foo))
- pedwarn ("ISO C89 forbids subscripting non-lvalue array");
+ pedwarn ("ISO C90 forbids subscripting non-lvalue array");
}
type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (array)));
@@ -1502,6 +1458,17 @@ build_external_ref (id, fun)
ref = DECL_INITIAL (ref);
TREE_CONSTANT (ref) = 1;
}
+ else if (current_function_decl != 0
+ && DECL_CONTEXT (current_function_decl) != 0
+ && (TREE_CODE (ref) == VAR_DECL
+ || TREE_CODE (ref) == PARM_DECL
+ || TREE_CODE (ref) == FUNCTION_DECL))
+ {
+ tree context = decl_function_context (ref);
+
+ if (context != 0 && context != current_function_decl)
+ DECL_NONLOCAL (ref) = 1;
+ }
return ref;
}
@@ -1564,10 +1531,9 @@ build_function_call (function, params)
coerced_params
= convert_arguments (TYPE_ARG_TYPES (fntype), params, name, fundecl);
- /* Check for errors in format strings. */
+ /* Check that the arguments to the function are valid. */
- if (warn_format)
- check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params);
+ check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
/* Recognize certain built-in functions so we can make tree-codes
other than CALL_EXPR. We do this when it enables fold-const.c
@@ -2011,7 +1977,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* Subtraction of two similar pointers.
We must subtract them as integers, then divide by object size. */
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
- && comp_target_types (type0, type1))
+ && comp_target_types (type0, type1, 1))
return pointer_diff (op0, op1);
/* Handle pointer minus int. Just like pointer plus int. */
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
@@ -2035,9 +2001,9 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
warning ("division by zero");
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE)
+ || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE))
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
@@ -2060,6 +2026,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
case BIT_XOR_EXPR:
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
shorten = -1;
+ else if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ common = 1;
break;
case TRUNC_MOD_EXPR:
@@ -2094,8 +2062,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
but that does not mean the operands should be
converted to ints! */
result_type = integer_type_node;
- op0 = truthvalue_conversion (op0);
- op1 = truthvalue_conversion (op1);
+ op0 = c_common_truthvalue_conversion (op0);
+ op1 = c_common_truthvalue_conversion (op1);
converted = 1;
}
break;
@@ -2121,18 +2089,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
}
- /* Use the type of the value to be shifted.
- This is what most traditional C compilers do. */
+ /* Use the type of the value to be shifted. */
result_type = type0;
- /* Unless traditional, convert the shift-count to an integer,
- regardless of size of value being shifted. */
- if (! flag_traditional)
- {
- 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;
- }
+ /* 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;
@@ -2148,18 +2112,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
warning ("left shift count >= width of type");
}
- /* Use the type of the value to be shifted.
- This is what most traditional C compilers do. */
+ /* Use the type of the value to be shifted. */
result_type = type0;
- /* Unless traditional, convert the shift-count to an integer,
- regardless of size of value being shifted. */
- if (! flag_traditional)
- {
- 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;
- }
+ /* 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;
@@ -2175,18 +2135,14 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
warning ("shift count >= width of type");
}
- /* Use the type of the value to be shifted.
- This is what most traditional C compilers do. */
+ /* Use the type of the value to be shifted. */
result_type = type0;
- /* Unless traditional, convert the shift-count to an integer,
- regardless of size of value being shifted. */
- if (! flag_traditional)
- {
- 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;
- }
+ /* 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;
@@ -2198,9 +2154,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
but don't convert the args to int! */
build_type = integer_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE)
+ || code0 == COMPLEX_TYPE
+ || code0 == VECTOR_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE))
+ || code1 == COMPLEX_TYPE
+ || code1 == VECTOR_TYPE))
short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
@@ -2209,7 +2167,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
/* Anything compares with void *. void * compares with anything.
Otherwise, the targets must be compatible
and both must be object or both incomplete. */
- if (comp_target_types (type0, type1))
+ if (comp_target_types (type0, type1, 1))
result_type = common_type (type0, type1);
else if (VOID_TYPE_P (tt0))
{
@@ -2240,14 +2198,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
- if (! flag_traditional)
- pedwarn ("comparison between pointer and integer");
+ pedwarn ("comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
- if (! flag_traditional)
- pedwarn ("comparison between pointer and integer");
+ pedwarn ("comparison between pointer and integer");
}
break;
@@ -2258,7 +2214,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
shorten = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
- if (comp_target_types (type0, type1))
+ if (comp_target_types (type0, type1, 1))
{
result_type = common_type (type0, type1);
if (pedantic
@@ -2283,7 +2239,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
short_compare = 1;
else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
{
- if (comp_target_types (type0, type1))
+ if (comp_target_types (type0, type1, 1))
{
result_type = common_type (type0, type1);
if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
@@ -2316,14 +2272,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
- if (! flag_traditional)
- pedwarn ("comparison between pointer and integer");
+ pedwarn ("comparison between pointer and integer");
}
else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE)
{
result_type = type1;
- if (! flag_traditional)
- pedwarn ("comparison between pointer and integer");
+ pedwarn ("comparison between pointer and integer");
}
break;
@@ -2347,9 +2301,11 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
break;
}
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+ if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
+ || code0 == VECTOR_TYPE)
&&
- (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
+ (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE
+ || code1 == VECTOR_TYPE))
{
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
@@ -2411,22 +2367,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
&& unsigned0 == unsigned1
&& (unsigned0 || !uns))
result_type
- = signed_or_unsigned_type (unsigned0,
- common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ = c_common_signed_or_unsigned_type
+ (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1))
< TYPE_PRECISION (result_type))
- && (type = signed_or_unsigned_type (unsigned1,
- TREE_TYPE (arg1)),
+ && (type
+ = c_common_signed_or_unsigned_type (unsigned1,
+ TREE_TYPE (arg1)),
int_fits_type_p (arg0, type)))
result_type = type;
else if (TREE_CODE (arg1) == INTEGER_CST
&& (unsigned0 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg0))
< TYPE_PRECISION (result_type))
- && (type = signed_or_unsigned_type (unsigned0,
- TREE_TYPE (arg0)),
+ && (type
+ = c_common_signed_or_unsigned_type (unsigned0,
+ TREE_TYPE (arg0)),
int_fits_type_p (arg1, type)))
result_type = type;
}
@@ -2452,7 +2410,8 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
{
/* Do an unsigned shift if the operand was zero-extended. */
result_type
- = signed_or_unsigned_type (unsigned_arg, TREE_TYPE (arg0));
+ = c_common_signed_or_unsigned_type (unsigned_arg,
+ TREE_TYPE (arg0));
/* Convert value-to-be-shifted to that type. */
if (TREE_TYPE (op0) != result_type)
op0 = convert (result_type, op0);
@@ -2523,22 +2482,24 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
constant expression involving such literals or a
conditional expression involving such literals)
and it is non-negative. */
- if (tree_expr_nonnegative_p (sop))
+ if (c_tree_expr_nonnegative_p (sop))
/* OK */;
/* Do not warn if the comparison is an equality operation,
the unsigned quantity is an integral constant, and it
would fit in the result if the result were signed. */
else if (TREE_CODE (uop) == INTEGER_CST
&& (resultcode == EQ_EXPR || resultcode == NE_EXPR)
- && int_fits_type_p (uop, signed_type (result_type)))
+ && int_fits_type_p
+ (uop, c_common_signed_type (result_type)))
/* OK */;
/* Do not warn if the unsigned quantity is an enumeration
constant and its maximum value would fit in the result
if the result were 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)),
- signed_type (result_type)))
+ && int_fits_type_p
+ (TYPE_MAX_VALUE (TREE_TYPE(uop)),
+ c_common_signed_type (result_type)))
/* OK */;
else
warning ("comparison between signed and unsigned");
@@ -2637,6 +2598,27 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
}
}
+
+/* Return true if `t' is known to be non-negative. */
+
+int
+c_tree_expr_nonnegative_p (t)
+ tree t;
+{
+ if (TREE_CODE (t) == STMT_EXPR)
+ {
+ t=COMPOUND_BODY (STMT_EXPR_STMT (t));
+
+ /* Find the last statement in the chain, ignoring the final
+ * scope statement */
+ while (TREE_CHAIN (t) != NULL_TREE
+ && TREE_CODE (TREE_CHAIN (t)) != SCOPE_STMT)
+ t=TREE_CHAIN (t);
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+ }
+ return tree_expr_nonnegative_p (t);
+}
+
/* Return a tree for the difference of pointers OP0 and OP1.
The resulting tree has type int. */
@@ -2758,11 +2740,13 @@ build_unary_op (code, xarg, flag)
}
else if (!noconvert)
arg = default_conversion (arg);
+ arg = non_lvalue (arg);
break;
case NEGATE_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
- || typecode == COMPLEX_TYPE))
+ || typecode == COMPLEX_TYPE
+ || typecode == VECTOR_TYPE))
{
error ("wrong type argument to unary minus");
return error_mark_node;
@@ -2772,7 +2756,12 @@ build_unary_op (code, xarg, flag)
break;
case BIT_NOT_EXPR:
- if (typecode == COMPLEX_TYPE)
+ if (typecode == INTEGER_TYPE || typecode == VECTOR_TYPE)
+ {
+ if (!noconvert)
+ arg = default_conversion (arg);
+ }
+ else if (typecode == COMPLEX_TYPE)
{
code = CONJ_EXPR;
if (pedantic)
@@ -2780,13 +2769,11 @@ build_unary_op (code, xarg, flag)
if (!noconvert)
arg = default_conversion (arg);
}
- else if (typecode != INTEGER_TYPE)
+ else
{
error ("wrong type argument to bit-complement");
return error_mark_node;
}
- else if (!noconvert)
- arg = default_conversion (arg);
break;
case ABS_EXPR:
@@ -2822,7 +2809,7 @@ build_unary_op (code, xarg, flag)
error ("wrong type argument to unary exclamation mark");
return error_mark_node;
}
- arg = truthvalue_conversion (arg);
+ arg = c_common_truthvalue_conversion (arg);
return invert_truthvalue (arg);
case NOP_EXPR:
@@ -2888,6 +2875,9 @@ build_unary_op (code, xarg, flag)
tree inc;
tree result_type = TREE_TYPE (arg);
+ arg = get_unwidened (arg, 0);
+ argtype = TREE_TYPE (arg);
+
/* Compute the increment. */
if (typecode == POINTER_TYPE)
@@ -2916,9 +2906,6 @@ build_unary_op (code, xarg, flag)
else
inc = integer_one_node;
- arg = get_unwidened (arg, 0);
- argtype = TREE_TYPE (arg);
-
inc = convert (argtype, inc);
/* Handle incrementing a cast-expression. */
@@ -3012,7 +2999,7 @@ build_unary_op (code, xarg, flag)
/* For &x[y], return x+y */
if (TREE_CODE (arg) == ARRAY_REF)
{
- if (mark_addressable (TREE_OPERAND (arg, 0)) == 0)
+ if (!c_mark_addressable (TREE_OPERAND (arg, 0)))
return error_mark_node;
return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0),
TREE_OPERAND (arg, 1), 1);
@@ -3067,7 +3054,7 @@ build_unary_op (code, xarg, flag)
argtype = build_pointer_type (argtype);
- if (mark_addressable (arg) == 0)
+ if (!c_mark_addressable (arg))
return error_mark_node;
{
@@ -3286,13 +3273,14 @@ readonly_warning (arg, msgid)
/* Mark EXP saying that we need to be able to take the
address of it; it should not be allocated in a register.
- Value is 1 if successful. */
+ Returns true if successful. */
-int
-mark_addressable (exp)
+bool
+c_mark_addressable (exp)
tree exp;
{
tree x = exp;
+
while (1)
switch (TREE_CODE (x))
{
@@ -3301,7 +3289,7 @@ mark_addressable (exp)
{
error ("cannot take address of bit-field `%s'",
IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (x, 1))));
- return 0;
+ return false;
}
/* ... fall through ... */
@@ -3316,7 +3304,7 @@ mark_addressable (exp)
case COMPOUND_LITERAL_EXPR:
case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1;
- return 1;
+ return true;
case VAR_DECL:
case CONST_DECL:
@@ -3329,7 +3317,7 @@ mark_addressable (exp)
{
error ("global register variable `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x)));
- return 0;
+ return false;
}
pedwarn ("register variable `%s' used in nested function",
IDENTIFIER_POINTER (DECL_NAME (x)));
@@ -3340,7 +3328,7 @@ mark_addressable (exp)
{
error ("address of global register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
- return 0;
+ return false;
}
/* If we are making this addressable due to its having
@@ -3351,13 +3339,13 @@ mark_addressable (exp)
else if (C_TYPE_FIELDS_VOLATILE (TREE_TYPE (x)))
{
error ("cannot put object with volatile field into register");
- return 0;
+ return false;
}
pedwarn ("address of register variable `%s' requested",
IDENTIFIER_POINTER (DECL_NAME (x)));
}
- put_var_into_stack (x);
+ put_var_into_stack (x, /*rescan=*/true);
/* drops in */
case FUNCTION_DECL:
@@ -3368,7 +3356,7 @@ mark_addressable (exp)
#endif
default:
- return 1;
+ return true;
}
}
@@ -3385,7 +3373,7 @@ build_conditional_expr (ifexp, op1, op2)
tree result_type = NULL;
tree orig_op1 = op1, orig_op2 = op2;
- ifexp = truthvalue_conversion (default_conversion (ifexp));
+ ifexp = c_common_truthvalue_conversion (default_conversion (ifexp));
#if 0 /* Produces wrong result if within sizeof. */
/* Don't promote the operands separately if they promote
@@ -3458,8 +3446,8 @@ build_conditional_expr (ifexp, op1, op2)
/* Do not warn if the signed quantity is an unsuffixed
integer literal (or some static constant expression
involving such literals) and it is non-negative. */
- else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
- || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
+ else if ((unsigned_op2 && c_tree_expr_nonnegative_p (op1))
+ || (unsigned_op1 && c_tree_expr_nonnegative_p (op2)))
/* OK */;
else
warning ("signed and unsigned type in conditional expression");
@@ -3474,7 +3462,7 @@ build_conditional_expr (ifexp, op1, op2)
}
else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
{
- if (comp_target_types (type1, type2))
+ if (comp_target_types (type1, type2, 1))
result_type = common_type (type1, type2);
else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
&& TREE_CODE (orig_op1) != NOP_EXPR)
@@ -3629,7 +3617,12 @@ build_c_cast (type, expr)
if (type == error_mark_node || expr == error_mark_node)
return error_mark_node;
- type = TYPE_MAIN_VARIANT (type);
+
+ /* The ObjC front-end uses TYPE_MAIN_VARIANT to tie together types differing
+ only in <protocol> qualifications. But when constructing cast expressions,
+ the protocols do matter and must be kept around. */
+ if (!flag_objc || !objc_is_id (type))
+ type = TYPE_MAIN_VARIANT (type);
#if 0
/* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */
@@ -3685,8 +3678,7 @@ build_c_cast (type, expr)
else
name = "";
t = digest_init (type, build (CONSTRUCTOR, type, NULL_TREE,
- build_tree_list (field, value)),
- 0, 0);
+ build_tree_list (field, value)), 0);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
return t;
}
@@ -3781,6 +3773,23 @@ build_c_cast (type, expr)
&& !TREE_CONSTANT (value))
warning ("cast to pointer from integer of different size");
+ if (TREE_CODE (type) == POINTER_TYPE
+ && TREE_CODE (otype) == POINTER_TYPE
+ && TREE_CODE (expr) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (expr, 0))
+ && flag_strict_aliasing && warn_strict_aliasing
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ /* Casting the address of a decl to non void pointer. Warn
+ if the cast breaks type based aliasing. */
+ if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
+ warning ("type-punning to incomplete type might break strict-aliasing rules");
+ else if (!alias_sets_conflict_p
+ (get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0))),
+ get_alias_set (TREE_TYPE (type))))
+ warning ("dereferencing type-punned pointer will break strict-aliasing rules");
+ }
+
ovalue = value;
value = convert (type, value);
@@ -4037,9 +4046,11 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (rhstype))
{
overflow_warning (rhs);
- /* Check for Objective-C protocols. This will issue a warning if
- there are protocol violations. No need to use the return value. */
- maybe_objc_comptypes (type, rhstype, 0);
+ /* Check for Objective-C protocols. This will automatically
+ issue a warning if there are protocol violations. No need to
+ use the return value. */
+ if (flag_objc)
+ objc_comptypes (type, rhstype, 0);
return rhs;
}
@@ -4054,7 +4065,12 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
if (codel == REFERENCE_TYPE
&& comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
{
- if (mark_addressable (rhs) == 0)
+ if (!lvalue_p (rhs))
+ {
+ error ("cannot pass rvalue to reference parameter");
+ return error_mark_node;
+ }
+ if (!c_mark_addressable (rhs))
return error_mark_node;
rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
@@ -4073,7 +4089,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
|| codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE
|| codel == BOOLEAN_TYPE)
- && (coder == INTEGER_TYPE || coder == REAL_TYPE
+ && (coder == INTEGER_TYPE || coder == REAL_TYPE
|| coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE
|| coder == BOOLEAN_TYPE))
return convert_and_check (type, rhs);
@@ -4107,7 +4123,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
Meanwhile, the lhs target must have all the qualifiers of
the rhs. */
if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || comp_target_types (memb_type, rhstype))
+ || comp_target_types (memb_type, rhstype, 0))
{
/* If this type won't generate any warnings, use it. */
if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr)
@@ -4173,7 +4189,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* Conversions among pointers */
else if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
- && (coder == POINTER_TYPE || coder == REFERENCE_TYPE))
+ && (coder == codel))
{
tree ttl = TREE_TYPE (type);
tree ttr = TREE_TYPE (rhstype);
@@ -4182,9 +4198,9 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
and vice versa; otherwise, targets must be the same.
Meanwhile, the lhs target must have all the qualifiers of the rhs. */
if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || comp_target_types (type, rhstype)
- || (unsigned_type (TYPE_MAIN_VARIANT (ttl))
- == unsigned_type (TYPE_MAIN_VARIANT (ttr))))
+ || comp_target_types (type, rhstype, 0)
+ || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
+ == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
{
if (pedantic
&& ((VOID_TYPE_P (ttl) && TREE_CODE (ttr) == FUNCTION_TYPE)
@@ -4207,7 +4223,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
/* If this is not a case of ignoring a mismatch in signedness,
no warning. */
else if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
- || comp_target_types (type, rhstype))
+ || comp_target_types (type, rhstype, 0))
;
/* If there is a mismatch, do warn. */
else if (pedantic)
@@ -4262,7 +4278,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
{
if (funname)
{
- tree selector = maybe_building_objc_message_expr ();
+ tree selector = objc_message_selector ();
if (selector && parmnum > 2)
error ("incompatible type for argument %d of `%s'",
@@ -4307,7 +4323,8 @@ c_convert_parm_for_inlining (parm, value, fn)
/* Print a warning using MSGID.
It gets OPNAME as its one parameter.
- If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'".
+ 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. */
@@ -4320,7 +4337,7 @@ warn_for_assignment (msgid, opname, function, argnum)
{
if (opname == 0)
{
- tree selector = maybe_building_objc_message_expr ();
+ tree selector = objc_message_selector ();
char * new_opname;
if (selector && argnum > 2)
@@ -4328,7 +4345,27 @@ warn_for_assignment (msgid, opname, function, argnum)
function = selector;
argnum -= 2;
}
- if (function)
+ 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'");
@@ -4395,8 +4432,7 @@ store_init_value (decl, init)
/* Digest the specified initializer into an expression. */
- value = digest_init (type, init, TREE_STATIC (decl),
- TREE_STATIC (decl) || (pedantic && !flag_isoc99));
+ value = digest_init (type, init, TREE_STATIC (decl));
/* Store the expression if valid; else report error. */
@@ -4496,15 +4532,6 @@ static int spelling_size; /* Size of the spelling stack. */
#define SPELLING_DEPTH() (spelling - spelling_base)
#define RESTORE_SPELLING_DEPTH(DEPTH) (spelling = spelling_base + (DEPTH))
-/* Save and restore the spelling stack around arbitrary C code. */
-
-#define SAVE_SPELLING_DEPTH(code) \
-{ \
- int __depth = SPELLING_DEPTH (); \
- code; \
- RESTORE_SPELLING_DEPTH (__depth); \
-}
-
/* Push an element on the spelling stack with type KIND and assign VALUE
to MEMBER. */
@@ -4657,14 +4684,13 @@ warning_init (msgid)
/* Digest the parser output INIT as an initializer for type TYPE.
Return a C expression of type TYPE to represent the initial value.
- The arguments REQUIRE_CONSTANT and CONSTRUCTOR_CONSTANT request errors
- if non-constant initializers or elements are seen. CONSTRUCTOR_CONSTANT
- applies only to elements of constructors. */
+ REQUIRE_CONSTANT requests an error if non-constant initializers or
+ elements are seen. */
static tree
-digest_init (type, init, require_constant, constructor_constant)
+digest_init (type, init, require_constant)
tree type, init;
- int require_constant, constructor_constant;
+ int require_constant;
{
enum tree_code code = TREE_CODE (type);
tree inside_init = init;
@@ -4843,44 +4869,6 @@ digest_init (type, init, require_constant, constructor_constant)
return error_mark_node;
}
- /* Traditionally, you can write struct foo x = 0;
- and it initializes the first element of x to 0. */
- if (flag_traditional)
- {
- tree top = 0, prev = 0, otype = type;
- while (TREE_CODE (type) == RECORD_TYPE
- || TREE_CODE (type) == ARRAY_TYPE
- || TREE_CODE (type) == QUAL_UNION_TYPE
- || TREE_CODE (type) == UNION_TYPE)
- {
- tree temp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE);
- if (prev == 0)
- top = temp;
- else
- TREE_OPERAND (prev, 1) = build_tree_list (NULL_TREE, temp);
- prev = temp;
- if (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
- else if (TYPE_FIELDS (type))
- type = TREE_TYPE (TYPE_FIELDS (type));
- else
- {
- error_init ("invalid initializer");
- return error_mark_node;
- }
- }
-
- if (otype != type)
- {
- TREE_OPERAND (prev, 1)
- = build_tree_list (NULL_TREE,
- digest_init (type, init, require_constant,
- constructor_constant));
- return top;
- }
- else
- return error_mark_node;
- }
error_init ("invalid initializer");
return error_mark_node;
}
@@ -5240,7 +5228,7 @@ really_start_incremental_init (type)
constructor_max_index = build_int_2 (-1, -1);
/* constructor_max_index needs to be an INTEGER_CST. Attempts
- to initialize VLAs will cause an proper error; avoid tree
+ to initialize VLAs will cause a proper error; avoid tree
checking errors as well by setting a safe value. */
if (constructor_max_index
&& TREE_CODE (constructor_max_index) != INTEGER_CST)
@@ -5260,7 +5248,7 @@ really_start_incremental_init (type)
/* Vectors are like simple fixed-size arrays. */
constructor_max_index =
build_int_2 (TYPE_VECTOR_SUBPARTS (constructor_type) - 1, 0);
- constructor_index = convert (bitsizetype, integer_zero_node);
+ constructor_index = convert (bitsizetype, bitsize_zero_node);
constructor_unfilled_index = constructor_index;
}
else
@@ -5292,6 +5280,7 @@ push_init_level (implicit)
&& constructor_fields == 0)
process_init_element (pop_init_level (1));
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
+ && constructor_max_index
&& tree_int_cst_lt (constructor_max_index, constructor_index))
process_init_element (pop_init_level (1));
else
@@ -5430,7 +5419,7 @@ push_init_level (implicit)
constructor_max_index = build_int_2 (-1, -1);
/* constructor_max_index needs to be an INTEGER_CST. Attempts
- to initialize VLAs will cause an proper error; avoid tree
+ to initialize VLAs will cause a proper error; avoid tree
checking errors as well by setting a safe value. */
if (constructor_max_index
&& TREE_CODE (constructor_max_index) != INTEGER_CST)
@@ -5619,7 +5608,7 @@ pop_init_level (implicit)
}
/* Common handling for both array range and field name designators.
- ARRAY argument is non-zero for array ranges. Returns zero for success. */
+ ARRAY argument is nonzero for array ranges. Returns zero for success. */
static int
set_designator (array)
@@ -6277,8 +6266,7 @@ output_init_element (value, type, field, pending)
|| TREE_CHAIN (field)))))
return;
- value = digest_init (type, value, require_constant_value,
- require_constant_elements);
+ value = digest_init (type, value, require_constant_value);
if (value == error_mark_node)
{
constructor_erroneous = 1;
@@ -6889,12 +6877,9 @@ simple_asm_stmt (expr)
{
tree stmt;
- if (TREE_CHAIN (expr))
- expr = combine_strings (expr);
-
/* Simple asm statements are treated as volatile. */
stmt = add_stmt (build_stmt (ASM_STMT, ridpointers[(int) RID_VOLATILE],
- expr, NULL_TREE, NULL_TREE, NULL_TREE));
+ expr, NULL_TREE, NULL_TREE, NULL_TREE));
ASM_INPUT_P (stmt) = 1;
return stmt;
}
@@ -6916,8 +6901,6 @@ build_asm_stmt (cv_qualifier, string, outputs, inputs, clobbers)
{
tree tail;
- if (TREE_CHAIN (string))
- string = combine_strings (string);
if (TREE_CODE (string) != STRING_CST)
{
error ("asm template is not a string constant");
@@ -6994,7 +6977,11 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
/* Record the contents of OUTPUTS before it is modified. */
for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
- o[i] = TREE_VALUE (tail);
+ {
+ o[i] = TREE_VALUE (tail);
+ if (o[i] == error_mark_node)
+ return;
+ }
/* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of
OUTPUTS some trees for where the values were actually stored. */
OpenPOWER on IntegriCloud