#include "expr.h"
#include "toplev.h"
#include "intl.h"
-#include "defaults.h"
#include "ggc.h"
/* Nonzero if we've already printed a "missing braces around initializer"
/* If both args specify argument types, we must merge the two
lists, argument by argument. */
+ pushlevel (0);
+ declare_parm_level (1);
+
len = list_length (p1);
newargs = 0;
parm_done: ;
}
+ poplevel (0, 0, 0);
+
t1 = build_function_type (valtype, newargs);
/* ... falls through ... */
}
if (TREE_CODE (exp) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (exp, 1))
/* If it's thinner than an int, promote it like a
- C_PROMOTING_INTEGER_TYPE_P, otherwise leave it alone. */
+ 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);
- if (C_PROMOTING_INTEGER_TYPE_P (type))
+ if (c_promoting_integer_type_p (type))
{
/* Traditionally, unsignedness is preserved in default promotions.
Also preserve unsignedness if not really getting any wider. */
return convert (integer_type_node, exp);
}
- if (code == BOOLEAN_TYPE)
- 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);
{
/* Optionally warn about conversions that
differ from the default conversions. */
- if (warn_conversion)
+ if (warn_conversion || warn_traditional)
{
int formal_prec = TYPE_PRECISION (type);
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);
+ 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);
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);
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);
+ 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);
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);
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);
}
- /* Detect integer changing in width or signedness. */
- else if (INTEGRAL_TYPE_P (type)
+ /* Detect integer changing in width or signedness.
+ These warnings are only activated with
+ -Wconversion, not with -Wtraditional. */
+ else if (warn_conversion && INTEGRAL_TYPE_P (type)
&& INTEGRAL_TYPE_P (TREE_TYPE (val)))
{
tree would_have_been = default_conversion (val);
if (TREE_CHAIN (list) == 0)
{
+ /* Convert arrays to pointers when there really is a comma operator. */
+ if (!first_p && TREE_CODE (TREE_TYPE (TREE_VALUE (list))) == ARRAY_TYPE)
+ TREE_VALUE (list) = default_conversion (TREE_VALUE (list));
+
#if 0 /* If something inside inhibited lvalueness, we should not override. */
/* Consider (x, y+0), which is not an lvalue since y+0 is not. */
return TREE_VALUE (list);
}
- if (TREE_CHAIN (list) != 0 && TREE_CHAIN (TREE_CHAIN (list)) == 0)
- {
- /* Convert arrays to pointers when there really is a comma operator. */
- if (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (list)))) == ARRAY_TYPE)
- TREE_VALUE (TREE_CHAIN (list))
- = default_conversion (TREE_VALUE (TREE_CHAIN (list)));
- }
-
rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
return value;
}
+
+/* Interpret a cast of expression EXPR to type TYPE. */
+tree
+c_cast_expr (type, expr)
+ tree type, expr;
+{
+ int saved_wsp = warn_strict_prototypes;
+
+ /* This avoids warnings about unprototyped casts on
+ integers. E.g. "#define SIG_DFL (void(*)())0". */
+ if (TREE_CODE (expr) == INTEGER_CST)
+ warn_strict_prototypes = 0;
+ type = groktypename (type);
+ warn_strict_prototypes = saved_wsp;
+
+ return build_c_cast (type, expr);
+}
+
\f
/* Build an assignment expression of lvalue LHS from value RHS.
MODIFYCODE is the code for a binary operator that we use
if (TREE_CODE (init) == NON_LVALUE_EXPR)
inside_init = TREE_OPERAND (init, 0);
+ inside_init = fold (inside_init);
+
/* Initialization of an array of chars from a string constant
optionally enclosed in braces. */
{
constructor_index = convert (bitsizetype, first);
- if (last != 0 && tree_int_cst_lt (last, first))
+ if (last)
{
- error_init ("empty index range in initializer");
- last = 0;
- }
- else if (last)
- {
- last = convert (bitsizetype, last);
- if (constructor_max_index != 0
- && tree_int_cst_lt (constructor_max_index, last))
+ if (tree_int_cst_equal (first, last))
+ last = 0;
+ else if (tree_int_cst_lt (last, first))
{
- error_init ("array index range in initializer exceeds array bounds");
+ error_init ("empty index range in initializer");
last = 0;
}
+ else
+ {
+ last = convert (bitsizetype, last);
+ if (constructor_max_index != 0
+ && tree_int_cst_lt (constructor_max_index, last))
+ {
+ error_init ("array index range in initializer exceeds array bounds");
+ last = 0;
+ }
+ }
}
+
designator_depth++;
designator_errorneous = 0;
if (constructor_range_stack || last)
constructor_range_stack = 0;
}
\f
+/* Build a simple asm-statement, from one string literal. */
+tree
+simple_asm_stmt (expr)
+ tree expr;
+{
+ STRIP_NOPS (expr);
+
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ expr = TREE_OPERAND (expr, 0);
+
+ if (TREE_CODE (expr) == STRING_CST)
+ {
+ tree stmt;
+
+ if (TREE_CHAIN (expr))
+ expr = combine_strings (expr);
+ stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr,
+ NULL_TREE, NULL_TREE,
+ NULL_TREE));
+ ASM_INPUT_P (stmt) = 1;
+ return stmt;
+ }
+
+ error ("argument of `asm' is not a constant string");
+ return NULL_TREE;
+}
+
/* Build an asm-statement, whose components are a CV_QUALIFIER, a
STRING, some OUTPUTS, some INPUTS, and some CLOBBERS. */