+2012-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/53220
+ * c-typeck.c (array_to_pointer_conversion): Give -Wc++-compat warning
+ about array compound literals.
+
2012-05-30 Richard Guenther <rguenther@suse.de>
PR middle-end/53501
if (TREE_CODE (exp) == INDIRECT_REF)
return convert (ptrtype, TREE_OPERAND (exp, 0));
+ /* In C++ array compound literals are temporary objects unless they are
+ const or appear in namespace scope, so they are destroyed too soon
+ to use them for much of anything (c++/53220). */
+ if (warn_cxx_compat && TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
+ {
+ tree decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ if (!TREE_READONLY (decl) && !TREE_STATIC (decl))
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+ "converting an array compound literal to a pointer "
+ "is ill-formed in C++");
+ }
+
adr = build_unary_op (loc, ADDR_EXPR, exp, 1);
return convert (ptrtype, adr);
}
+2012-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/53220
+ * call.c (convert_like_real) [ck_list]: Take array address directly.
+ * typeck.c (decay_conversion): Reject decay of an array compound
+ literal.
+
2012-05-29 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53491
(elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
array = build_array_of_n_type (elttype, len);
array = finish_compound_literal (array, new_ctor, complain);
+ /* Take the address explicitly rather than via decay_conversion
+ to avoid the error about taking the address of a temporary. */
+ array = cp_build_addr_expr (array, complain);
+ array = cp_convert (build_pointer_type (elttype), array);
/* Build up the initializer_list object. */
totype = complete_type (totype);
field = next_initializable_field (TYPE_FIELDS (totype));
- CONSTRUCTOR_APPEND_ELT (vec, field, decay_conversion (array));
+ CONSTRUCTOR_APPEND_ELT (vec, field, array);
field = next_initializable_field (DECL_CHAIN (field));
CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
new_ctor = build_constructor (totype, vec);
return error_mark_node;
}
+ /* Don't let an array compound literal decay to a pointer. It can
+ still be used to initialize an array or bind to a reference. */
+ if (TREE_CODE (exp) == TARGET_EXPR)
+ {
+ error ("taking address of temporary array");
+ return error_mark_node;
+ }
+
ptrtype = build_pointer_type (TREE_TYPE (type));
if (TREE_CODE (exp) == VAR_DECL)
a cast containing an initializer. Its value is an object of the
type specified in the cast, containing the elements specified in
the initializer; it is an lvalue. As an extension, GCC supports
-compound literals in C90 mode and in C++.
+compound literals in C90 mode and in C++, though the semantics are
+somewhat different in C++.
Usually, the specified type is a structure. Assume that
@code{struct foo} and @code{structure} are declared as shown:
@}
@end smallexample
-You can also construct an array. If all the elements of the compound literal
-are (made up of) simple constant expressions, suitable for use in
+You can also construct an array, though this is dangerous in C++, as
+explained below. If all the elements of the compound literal are
+(made up of) simple constant expressions, suitable for use in
initializers of objects of static storage duration, then the compound
literal can be coerced to a pointer to its first element and used in
such an initializer, as shown here:
static int z[] = @{1, 0, 0@};
@end smallexample
+In C, a compound literal designates an unnamed object with static or
+automatic storage duration. In C++, a compound literal designates a
+temporary object, which only lives until the end of its
+full-expression. As a result, well-defined C code that takes the
+address of a subobject of a compound literal can be undefined in C++.
+For instance, if the array compound literal example above appeared
+inside a function, any subsequent use of @samp{foo} in C++ has
+undefined behavior because the lifetime of the array ends after the
+declaration of @samp{foo}. As a result, the C++ compiler now rejects
+the conversion of a temporary array to a pointer.
+
+As an optimization, the C++ compiler sometimes gives array compound
+literals longer lifetimes: when the array either appears outside a
+function or has const-qualified type. If @samp{foo} and its
+initializer had elements of @samp{char *const} type rather than
+@samp{char *}, or if @samp{foo} were a global variable, the array
+would have static storage duration. But it is probably safest just to
+avoid the use of array compound literals in code compiled as C++.
+
@node Designated Inits
@section Designated Initializers
@cindex initializers with labeled elements
+2012-05-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/53220
+ * c-c++-common/array-lit.c: New.
+ * g++.dg/ext/complit12.C: #if 0 out decay-to-pointer test.
+
2012-05-30 Richard Guenther <rguenther@suse.de>
PR middle-end/53501
--- /dev/null
+/* { dg-options "-std=c99 -Wc++-compat -Werror" { target c } } */
+/* { dg-prune-output "treated as errors" } */
+#include <stdio.h>
+
+int main()
+{
+ for (int *p = (int[]){ 1, 2, 3, 0 }; /* { dg-error "array" } */
+ *p; ++p) {
+ printf("%d\n", *p);
+ }
+ return 0;
+}
T t;
if (c != 11)
return 5;
- MA ma = bar ((M[2]) { M(), M() }, m);
- if (c != 12)
- return 7;
M mm[2] = ((M[2]) { f(M()), f(M()) });
- if (c != 14)
+ if (c != 13)
return 8;
+#if 0
+ MA ma = bar ((M[2]) { M(), M() }, m);
+ if (c != 14)
+ return 7;
+#endif
}
if (c != 0)
return 6;