if (AGGREGATE_TYPE_P (return_type))
rhs = build_compound_literal (return_type,
- build_constructor (return_type,
- NULL_TREE));
+ build_constructor (return_type, 0));
else
rhs = fold_build1 (NOP_EXPR, return_type, integer_zero_node);
val = build1 (ADDR_EXPR, argtype, arg);
- if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
- TREE_INVARIANT (val) = TREE_CONSTANT (val) = 1;
-
return val;
default:
if (pedantic)
pedwarn ("ISO C forbids casts to union type");
t = digest_init (type,
- build_constructor (type,
- build_tree_list (field, value)),
+ build_constructor_single (type, field, value),
true, 0);
TREE_CONSTANT (t) = TREE_CONSTANT (value);
TREE_INVARIANT (t) = TREE_INVARIANT (value);
warning (OPT_Wc___compat, "request for implicit conversion from "
"%qT to %qT not permitted in C++", rhstype, type);
+ /* Check if the right-hand side has a format attribute but the
+ left-hand side doesn't. */
+ if (warn_missing_format_attribute)
+ {
+ 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 ();
+ }
+ }
+ }
+
/* Any non-function converts to a [const][volatile] void *
and vice versa; otherwise, targets must be the same.
Meanwhile, the lhs target must have all the qualifiers of the rhs. */
if (TREE_CODE (inside_init) == CONSTRUCTOR)
{
- tree link;
+ unsigned HOST_WIDE_INT ix;
+ tree value;
+ bool constant_p = true;
/* 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;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (inside_init), ix, value)
+ if (!CONSTANT_CLASS_P (value))
+ {
+ constant_p = false;
+ break;
+ }
- if (link == NULL)
- return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
+ if (constant_p)
+ return build_vector_from_ctor (type,
+ CONSTRUCTOR_ELTS (inside_init));
}
}
inside_init = error_mark_node;
}
+ /* Added to enable additional -Wmissing-format-attribute warnings. */
+ if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
+ inside_init = convert_for_assignment (type, inside_init, ic_init, NULL_TREE,
+ NULL_TREE, 0);
return inside_init;
}
/* If we are saving up the elements rather than allocating them,
this is the list of elements so far (in reverse order,
most recent first). */
-static tree constructor_elements;
+static VEC(constructor_elt,gc) *constructor_elements;
/* 1 if constructor should be incrementally stored into a constructor chain,
0 if all the elements should be kept in AVL tree. */
tree unfilled_index;
tree unfilled_fields;
tree bit_index;
- tree elements;
+ VEC(constructor_elt,gc) *elements;
struct init_node *pending_elts;
int offset;
int depth;
tree decl;
struct constructor_stack *constructor_stack;
struct constructor_range_stack *constructor_range_stack;
- tree elements;
+ VEC(constructor_elt,gc) *elements;
struct spelling *spelling;
struct spelling *spelling_base;
int spelling_size;
constructor_constant = TREE_CONSTANT (value);
constructor_simple = TREE_STATIC (value);
constructor_elements = CONSTRUCTOR_ELTS (value);
- if (constructor_elements
+ if (!VEC_empty (constructor_elt, constructor_elements)
&& (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == ARRAY_TYPE))
set_nonincremental_init ();
{
/* A nonincremental scalar initializer--just return
the element, after verifying there is just one. */
- if (constructor_elements == 0)
+ if (VEC_empty (constructor_elt,constructor_elements))
{
if (!constructor_erroneous)
error_init ("empty scalar initializer");
ret.value = error_mark_node;
}
- else if (TREE_CHAIN (constructor_elements) != 0)
+ else if (VEC_length (constructor_elt,constructor_elements) != 1)
{
error_init ("extra elements in scalar initializer");
- ret.value = TREE_VALUE (constructor_elements);
+ ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
}
else
- ret.value = TREE_VALUE (constructor_elements);
+ ret.value = VEC_index (constructor_elt,constructor_elements,0)->value;
}
else
{
else
{
ret.value = build_constructor (constructor_type,
- nreverse (constructor_elements));
+ constructor_elements);
if (constructor_constant)
TREE_CONSTANT (ret.value) = TREE_INVARIANT (ret.value) = 1;
if (constructor_constant && constructor_simple)
static void
set_nonincremental_init (void)
{
- tree chain;
+ unsigned HOST_WIDE_INT ix;
+ tree index, value;
if (TREE_CODE (constructor_type) != RECORD_TYPE
&& TREE_CODE (constructor_type) != ARRAY_TYPE)
return;
- for (chain = constructor_elements; chain; chain = TREE_CHAIN (chain))
- add_pending_init (TREE_PURPOSE (chain), TREE_VALUE (chain));
+ FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
+ add_pending_init (index, value);
constructor_elements = 0;
if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
}
else if (TREE_CODE (constructor_type) == UNION_TYPE)
{
- if (constructor_elements
- && TREE_PURPOSE (constructor_elements) == field)
- return TREE_VALUE (constructor_elements);
+ if (!VEC_empty (constructor_elt, constructor_elements)
+ && (VEC_last (constructor_elt, constructor_elements)->index
+ == field))
+ return VEC_last (constructor_elt, constructor_elements)->value;
}
return 0;
}
output_init_element (tree value, bool strict_string, tree type, tree field,
int pending)
{
+ constructor_elt *celt;
+
if (type == error_mark_node || value == error_mark_node)
{
constructor_erroneous = 1;
return;
}
else if (TREE_CODE (constructor_type) == UNION_TYPE
- && constructor_elements)
+ && !VEC_empty (constructor_elt, constructor_elements))
{
- if (TREE_SIDE_EFFECTS (TREE_VALUE (constructor_elements)))
+ if (TREE_SIDE_EFFECTS (VEC_last (constructor_elt,
+ constructor_elements)->value))
warning_init ("initialized field with side-effects overwritten");
/* We can have just one union field set. */
if (field && TREE_CODE (field) == INTEGER_CST)
field = copy_node (field);
- constructor_elements
- = tree_cons (field, value, constructor_elements);
+ celt = VEC_safe_push (constructor_elt, gc, constructor_elements, NULL);
+ celt->index = field;
+ celt->value = value;
/* Advance the variable that indicates sequential elements output. */
if (TREE_CODE (constructor_type) == ARRAY_TYPE)
leaving those to give errors later? */
return c_common_truthvalue_conversion (expr);
}
+\f
+
+/* Convert EXPR to a contained DECL, updating *TC, *TI and *SE as
+ required. */
+
+tree
+c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
+ bool *ti ATTRIBUTE_UNUSED, bool *se)
+{
+ if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
+ {
+ tree decl = COMPOUND_LITERAL_EXPR_DECL (expr);
+ /* Executing a compound literal inside a function reinitializes
+ it. */
+ if (!TREE_STATIC (decl))
+ *se = true;
+ return decl;
+ }
+ else
+ return expr;
+}