tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
int quals;
tree unqual_elt;
+ tree d1 = TYPE_DOMAIN (t1);
+ tree d2 = TYPE_DOMAIN (t2);
+ bool d1_variable, d2_variable;
+ bool d1_zero, d2_zero;
/* We should not have any type quals on arrays at all. */
gcc_assert (!TYPE_QUALS (t1) && !TYPE_QUALS (t2));
+ d1_zero = d1 == 0 || !TYPE_MAX_VALUE (d1);
+ d2_zero = d2 == 0 || !TYPE_MAX_VALUE (d2);
+
+ d1_variable = (!d1_zero
+ && (TREE_CODE (TYPE_MIN_VALUE (d1)) != INTEGER_CST
+ || TREE_CODE (TYPE_MAX_VALUE (d1)) != INTEGER_CST));
+ d2_variable = (!d2_zero
+ && (TREE_CODE (TYPE_MIN_VALUE (d2)) != INTEGER_CST
+ || TREE_CODE (TYPE_MAX_VALUE (d2)) != INTEGER_CST));
+
/* Save space: see if the result is identical to one of the args. */
- if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
+ if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)
+ && (d2_variable || d2_zero || !d1_variable))
return build_type_attribute_variant (t1, attributes);
- if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2))
+ if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)
+ && (d1_variable || d1_zero || !d2_variable))
return build_type_attribute_variant (t2, attributes);
if (elt == TREE_TYPE (t1) && !TYPE_DOMAIN (t2) && !TYPE_DOMAIN (t1))
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));
+ TYPE_DOMAIN ((TYPE_DOMAIN (t1)
+ && (d2_variable
+ || d2_zero
+ || !d1_variable))
+ ? t1
+ : t2));
t1 = c_build_qualified_type (t1, quals);
return build_type_attribute_variant (t1, attributes);
}
return t2;
}
\f
-/* Wrapper around c_common_type that is used by c-common.c. ENUMERAL_TYPEs
+/* Wrapper around c_common_type that is used by c-common.c and other
+ front end optimizations that remove promotions. ENUMERAL_TYPEs
are allowed here and are converted to their compatible integer types.
BOOLEAN_TYPEs are allowed here and return either boolean_type_node or
preferably a non-Boolean type as the common type. */
check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
TYPE_ARG_TYPES (fntype));
- result = build3 (CALL_EXPR, TREE_TYPE (fntype),
- function, coerced_params, NULL_TREE);
- TREE_SIDE_EFFECTS (result) = 1;
-
if (require_constant_value)
{
- result = fold_initializer (result);
+ result = fold_build3_initializer (CALL_EXPR, TREE_TYPE (fntype),
+ function, coerced_params, NULL_TREE);
if (TREE_CONSTANT (result)
&& (name == NULL_TREE
pedwarn_init ("initializer element is not constant");
}
else
- result = fold (result);
+ result = fold_build3 (CALL_EXPR, TREE_TYPE (fntype),
+ function, coerced_params, NULL_TREE);
if (VOID_TYPE_P (TREE_TYPE (result)))
return result;
{
if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (0, "suggest parentheses around + or - inside shift");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around + or - inside shift");
}
if (code == TRUTH_ORIF_EXPR)
{
if (code1 == TRUTH_ANDIF_EXPR
|| code2 == TRUTH_ANDIF_EXPR)
- warning (0, "suggest parentheses around && within ||");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around && within ||");
}
if (code == BIT_IOR_EXPR)
|| code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == BIT_AND_EXPR || code2 == BIT_XOR_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (0, "suggest parentheses around arithmetic in operand of |");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around arithmetic in operand of |");
/* Check cases like x|y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (0, "suggest parentheses around comparison in operand of |");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of |");
}
if (code == BIT_XOR_EXPR)
|| code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == BIT_AND_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (0, "suggest parentheses around arithmetic in operand of ^");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around arithmetic in operand of ^");
/* Check cases like x^y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (0, "suggest parentheses around comparison in operand of ^");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of ^");
}
if (code == BIT_AND_EXPR)
{
if (code1 == PLUS_EXPR || code1 == MINUS_EXPR
|| code2 == PLUS_EXPR || code2 == MINUS_EXPR)
- warning (0, "suggest parentheses around + or - in operand of &");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around + or - in operand of &");
/* Check cases like x&y==z */
if (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison)
- warning (0, "suggest parentheses around comparison in operand of &");
+ warning (OPT_Wparentheses,
+ "suggest parentheses around comparison in operand of &");
}
/* Similarly, check for cases like 1<=i<=10 that are probably errors. */
if (TREE_CODE_CLASS (code) == tcc_comparison
&& (TREE_CODE_CLASS (code1) == tcc_comparison
|| TREE_CODE_CLASS (code2) == tcc_comparison))
- warning (0, "comparisons like X<=Y<=Z do not have their mathematical meaning");
+ warning (OPT_Wparentheses, "comparisons like X<=Y<=Z do not "
+ "have their mathematical meaning");
}
if (argtype == 0)
argtype = TREE_TYPE (arg);
- val = build1 (code, argtype, arg);
- return require_constant_value ? fold_initializer (val) : fold (val);
+ return require_constant_value ? fold_build1_initializer (code, argtype, arg)
+ : fold_build1 (code, argtype, arg);
}
/* Return nonzero if REF is an lvalue valid for this language.
"pointer target type"));
}
- if (pedantic && !DECL_IN_SYSTEM_HEADER (fundecl))
+ if (pedantic && (!fundecl || !DECL_IN_SYSTEM_HEADER (fundecl)))
pedwarn ("ISO C prohibits argument conversion to union type");
return build1 (NOP_EXPR, type, rhs);
/* Check if the right-hand side has a format attribute but the
left-hand side doesn't. */
- if (warn_missing_format_attribute)
+ if (warn_missing_format_attribute
+ && check_missing_format_attribute (type, rhstype))
{
- tree rattrs = TYPE_ATTRIBUTES (ttr), ra;
- for (ra = rattrs; ra; ra = TREE_CHAIN (ra))
- {
- if (is_attribute_p ("format", TREE_PURPOSE (ra)))
- break;
- }
- if (ra)
- {
- tree lattrs = TYPE_ATTRIBUTES (ttl), la;
- for (la = lattrs; la; la = TREE_CHAIN (la))
- {
- if (is_attribute_p ("format", TREE_PURPOSE (la)))
- break;
- }
- if (!la)
- switch (errtype)
- {
- case ic_argpass:
- case ic_argpass_nonproto:
- warning (OPT_Wmissing_format_attribute,
- "argument %d of %qE might be "
- "a candidate for a format attribute",
- parmnum, rname);
- break;
- case ic_assign:
- warning (OPT_Wmissing_format_attribute,
- "assignment left-hand side might be "
- "a candidate for a format attribute");
- break;
- case ic_init:
- warning (OPT_Wmissing_format_attribute,
- "initialization left-hand side might be "
- "a candidate for a format attribute");
- break;
- case ic_return:
- warning (OPT_Wmissing_format_attribute,
- "return type might be "
- "a candidate for a format attribute");
- break;
- default:
- gcc_unreachable ();
- }
- }
+ switch (errtype)
+ {
+ case ic_argpass:
+ case ic_argpass_nonproto:
+ warning (OPT_Wmissing_format_attribute,
+ "argument %d of %qE might be "
+ "a candidate for a format attribute",
+ parmnum, rname);
+ break;
+ case ic_assign:
+ warning (OPT_Wmissing_format_attribute,
+ "assignment left-hand side might be "
+ "a candidate for a format attribute");
+ break;
+ case ic_init:
+ warning (OPT_Wmissing_format_attribute,
+ "initialization left-hand side might be "
+ "a candidate for a format attribute");
+ break;
+ case ic_return:
+ warning (OPT_Wmissing_format_attribute,
+ "return type might be "
+ "a candidate for a format attribute");
+ break;
+ default:
+ gcc_unreachable ();
+ }
}
/* Any non-function converts to a [const][volatile] void *
static int designator_depth;
/* Nonzero if there were diagnosed errors in this designator list. */
-static int designator_errorneous;
+static int designator_erroneous;
\f
/* This stack has a level for each implicit or explicit level of
constructor_incremental = 1;
constructor_designated = 0;
designator_depth = 0;
- designator_errorneous = 0;
+ designator_erroneous = 0;
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
p->range_stack = constructor_range_stack;
constructor_range_stack = 0;
designator_depth = 0;
- designator_errorneous = 0;
+ designator_erroneous = 0;
}
/* Don't die if an entire brace-pair level is superfluous
/* If there were errors in this designator list already, bail out
silently. */
- if (designator_errorneous)
+ if (designator_erroneous)
return 1;
if (!designator_depth)
if (set_designator (1))
return;
- designator_errorneous = 1;
+ designator_erroneous = 1;
if (!INTEGRAL_TYPE_P (TREE_TYPE (first))
|| (last && !INTEGRAL_TYPE_P (TREE_TYPE (last))))
}
designator_depth++;
- designator_errorneous = 0;
+ designator_erroneous = 0;
if (constructor_range_stack || last)
push_range_stack (last);
}
if (set_designator (0))
return;
- designator_errorneous = 1;
+ designator_erroneous = 1;
if (TREE_CODE (constructor_type) != RECORD_TYPE
&& TREE_CODE (constructor_type) != UNION_TYPE)
{
constructor_fields = tail;
designator_depth++;
- designator_errorneous = 0;
+ designator_erroneous = 0;
if (constructor_range_stack)
push_range_stack (NULL_TREE);
}
bool strict_string = value.original_code == STRING_CST;
designator_depth = 0;
- designator_errorneous = 0;
+ designator_erroneous = 0;
/* Handle superfluous braces around string cst as in
char x[] = {"foo"}; */
tree
c_finish_return (tree retval)
{
- tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl));
+ tree valtype = TREE_TYPE (TREE_TYPE (current_function_decl)), ret_stmt;
+ bool no_warning = false;
if (TREE_THIS_VOLATILE (current_function_decl))
warning (0, "function declared %<noreturn%> has a %<return%> statement");
current_function_returns_null = 1;
if ((warn_return_type || flag_isoc99)
&& valtype != 0 && TREE_CODE (valtype) != VOID_TYPE)
- pedwarn_c99 ("%<return%> with no value, in "
- "function returning non-void");
+ {
+ pedwarn_c99 ("%<return%> with no value, in "
+ "function returning non-void");
+ no_warning = true;
+ }
}
else if (valtype == 0 || TREE_CODE (valtype) == VOID_TYPE)
{
retval = build2 (MODIFY_EXPR, TREE_TYPE (res), res, t);
}
- return add_stmt (build_stmt (RETURN_EXPR, retval));
+ ret_stmt = build_stmt (RETURN_EXPR, retval);
+ TREE_NO_WARNING (ret_stmt) |= no_warning;
+ return add_stmt (ret_stmt);
}
\f
struct c_switch {
found:
if (COND_EXPR_ELSE (inner_if))
- warning (0, "%Hsuggest explicit braces to avoid ambiguous %<else%>",
+ warning (OPT_Wparentheses,
+ "%Hsuggest explicit braces to avoid ambiguous %<else%>",
&if_locus);
}
/* Diagnose ";" via the special empty statement node that we create. */
if (extra_warnings)
{
- if (TREE_CODE (then_block) == NOP_EXPR && !TREE_TYPE (then_block))
+ tree *inner_then = &then_block, *inner_else = &else_block;
+
+ if (TREE_CODE (*inner_then) == STATEMENT_LIST
+ && STATEMENT_LIST_TAIL (*inner_then))
+ inner_then = &STATEMENT_LIST_TAIL (*inner_then)->stmt;
+ if (*inner_else && TREE_CODE (*inner_else) == STATEMENT_LIST
+ && STATEMENT_LIST_TAIL (*inner_else))
+ inner_else = &STATEMENT_LIST_TAIL (*inner_else)->stmt;
+
+ if (TREE_CODE (*inner_then) == NOP_EXPR && !TREE_TYPE (*inner_then))
{
- if (!else_block)
+ if (!*inner_else)
warning (0, "%Hempty body in an if-statement",
- EXPR_LOCUS (then_block));
- then_block = alloc_stmt_list ();
+ EXPR_LOCUS (*inner_then));
+
+ *inner_then = alloc_stmt_list ();
}
- if (else_block
- && TREE_CODE (else_block) == NOP_EXPR
- && !TREE_TYPE (else_block))
+ if (*inner_else
+ && TREE_CODE (*inner_else) == NOP_EXPR
+ && !TREE_TYPE (*inner_else))
{
warning (0, "%Hempty body in an else-statement",
- EXPR_LOCUS (else_block));
- else_block = alloc_stmt_list ();
+ EXPR_LOCUS (*inner_else));
+
+ *inner_else = alloc_stmt_list ();
}
}
}
t = build_and_jump (&blab);
- exit = build3 (COND_EXPR, void_type_node, cond, exit, t);
- exit = fold (exit);
+ exit = fold_build3 (COND_EXPR, void_type_node, cond, exit, t);
if (cond_is_first)
SET_EXPR_LOCATION (exit, start_locus);
else
if (last == error_mark_node
|| (last == BIND_EXPR_BODY (body)
&& BIND_EXPR_VARS (body) == NULL))
- return last;
+ {
+ /* Do not warn if the return value of a statement expression is
+ unused. */
+ if (EXPR_P (last))
+ TREE_NO_WARNING (last) = 1;
+ return last;
+ }
/* Extract the type of said expression. */
type = TREE_TYPE (last);
&& (unsigned0 || !uns))
result_type
= c_common_signed_or_unsigned_type
- (unsigned0, c_common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
+ (unsigned0, common_type (TREE_TYPE (arg0), TREE_TYPE (arg1)));
else if (TREE_CODE (arg0) == INTEGER_CST
&& (unsigned1 || !uns)
&& (TYPE_PRECISION (TREE_TYPE (arg1))
build_type = result_type;
{
- tree result = build2 (resultcode, build_type, op0, op1);
-
/* Treat expressions in initializers specially as they can't trap. */
- result = require_constant_value ? fold_initializer (result)
- : fold (result);
+ tree result = require_constant_value ? fold_build2_initializer (resultcode,
+ build_type,
+ op0, op1)
+ : fold_build2 (resultcode, build_type,
+ op0, op1);
if (final_type != 0)
result = convert (final_type, result);