extern bool trivial_type_p (const_tree);
extern bool implicit_lifetime_type_p (tree);
extern bool trivially_copyable_p (const_tree);
+extern bool trivially_copy_constructible_p (tree);
extern bool has_trivial_abi_attribute (tree);
extern void validate_trivial_abi_attribute (tree);
extern bool type_has_unique_obj_representations (const_tree, bool = false);
/* Since small trivially constructible types are cheap to construct, we
suppress the warning for them. 64B is a common size of a cache line. */
- tree vec = make_tree_vec (1);
- TREE_VEC_ELT (vec, 0) = TREE_TYPE (expr);
if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
|| (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64
- && is_trivially_xible (INIT_EXPR, type, vec)))
+ && trivially_copy_constructible_p (type)))
return;
/* If we can initialize a reference directly, suggest that to avoid the
static tree
eval_is_trivially_copy_constructible_type (tree type)
{
- tree arg = make_tree_vec (1);
- TREE_VEC_ELT (arg, 0)
- = build_stub_type (type, cp_type_quals (type) | TYPE_QUAL_CONST, false);
- if (is_trivially_xible (INIT_EXPR, type, arg))
+ if (trivially_copy_constructible_p (type))
return boolean_true_node;
else
return boolean_false_node;
return scalarish_type_p (t);
}
+/* Returns true iff type T is a trivially copy constructible type. */
+
+bool
+trivially_copy_constructible_p (tree t)
+{
+ tree arg = make_tree_vec (1);
+ TREE_VEC_ELT (arg, 0)
+ = build_stub_type (t, cp_type_quals (t) | TYPE_QUAL_CONST, false);
+ return is_trivially_xible (INIT_EXPR, t, arg);
+}
+
/* Returns 1 iff type T is an implicit-lifetime type, as defined in
[basic.types.general] and [class.prop]. */
@}
@end smallexample
-It does not warn when the type being copied is a trivially-copyable type whose
-size is less than 64 bytes.
+It does not warn when the type being copied is a trivially copy constructible
+type whose size is less than 64 bytes.
This warning also warns when a loop variable in a range-based for-loop is
initialized with a value of a different type resulting in a copy. For example:
--- /dev/null
+// PR c++/125697
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wrange-loop-construct" }
+
+template <typename> struct pair {
+ int first;
+ int second;
+ template <typename _U1> pair(const pair<_U1> &&);
+};
+void
+foo (const pair<int> (&arr)[1])
+{
+ for (const auto x : arr) // { dg-bogus "creates a copy" }
+ (void) x;
+}
+static_assert(__is_trivially_copyable(pair<int>));
+static_assert(!__is_trivially_constructible(pair<int>));
+
+template <typename> struct pairbig {
+ int first;
+ int second;
+ char arr[64];
+ template <typename _U1> pairbig(const pairbig<_U1> &&);
+};
+void
+bar (const pairbig<int> (&arr)[1])
+{
+ for (const auto x : arr) // { dg-warning "creates a copy" }
+ (void) x;
+}
+static_assert(__is_trivially_copyable(pairbig<int>));
+static_assert(!__is_trivially_constructible(pairbig<int>));
+
+template <typename> struct pairnontriv {
+ int first;
+ int second;
+ pairnontriv(const pairnontriv &);
+ template <typename _U1> pairnontriv(const pairnontriv<_U1> &&);
+};
+void
+baz (const pairnontriv<int> (&arr)[1])
+{
+ for (const auto x : arr) // { dg-warning "creates a copy" }
+ (void) x;
+}
+static_assert(!__is_trivially_copyable(pairnontriv<int>));
+static_assert(!__is_trivially_constructible(pairnontriv<int>));