Commit f14edc1a by Jason Merrill Committed by Jason Merrill

Core 1402

	Core 1402
cp/
	* call.c (joust): An implicitly deleted move function is
	worse than any non-deleted function.
	* method.c (process_subob_fn): No special rules for move.
	(synthesized_method_walk, implicitly_declare_fn): Likewise.
	Warn about virtual base with non-trivial move assignment.
	* cp-tree.h (struct lang_decl_fn): Remove suppress_implicit_decl.
	(FNDECL_SUPPRESS_IMPLICIT_DECL): Remove.
c-family/
	* c.opt (Wvirtual-move-assign): New.

From-SVN: r192813
parent 57c3feb4
2012-10-25 Jason Merrill <jason@redhat.com>
* c.opt (Wvirtual-move-assign): New.
* c.opt (Winherited-variadic-ctor): New.
2012-10-25 Marc Glisse <marc.glisse@inria.fr>
......
......@@ -741,6 +741,10 @@ Wvolatile-register-var
C ObjC C++ ObjC++ Var(warn_volatile_register_var) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn when a register variable is declared volatile
Wvirtual-move-assign
C++ ObjC++ Var(warn_virtual_move_assign) Warning Init(1)
Warn if a virtual base has a non-trivial move assignment operator
Wwrite-strings
C ObjC C++ ObjC++ Var(warn_write_strings) Warning
In C++, nonzero means warn about deprecated conversion from string literals to 'char *'. In C, similar warning, except that the conversion is of course not deprecated by the ISO C standard.
......
2012-10-25 Jason Merrill <jason@redhat.com>
Core 1402
* call.c (joust): An implicitly deleted move function is
worse than any non-deleted function.
* method.c (process_subob_fn): No special rules for move.
(synthesized_method_walk, implicitly_declare_fn): Likewise.
Warn about virtual base with non-trivial move assignment.
* cp-tree.h (struct lang_decl_fn): Remove suppress_implicit_decl.
(FNDECL_SUPPRESS_IMPLICIT_DECL): Remove.
* semantics.c (finish_omp_threadprivate): Call complete_type.
* class.c (one_inherited_ctor): Warn about variadic inherited ctor.
......
......@@ -8246,6 +8246,22 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
&& (IS_TYPE_OR_DECL_P (cand1->fn)))
return 1;
/* Prefer a non-deleted function over an implicitly deleted move
constructor or assignment operator. This differs slightly from the
wording for issue 1402 (which says the move op is ignored by overload
resolution), but this way produces better error messages. */
if (TREE_CODE (cand1->fn) == FUNCTION_DECL
&& TREE_CODE (cand2->fn) == FUNCTION_DECL
&& DECL_DELETED_FN (cand1->fn) != DECL_DELETED_FN (cand2->fn))
{
if (DECL_DELETED_FN (cand1->fn) && DECL_DEFAULTED_FN (cand1->fn)
&& move_fn_p (cand1->fn))
return -1;
if (DECL_DELETED_FN (cand2->fn) && DECL_DEFAULTED_FN (cand2->fn)
&& move_fn_p (cand2->fn))
return 1;
}
/* a viable function F1
is defined to be a better function than another viable function F2 if
for all arguments i, ICSi(F1) is not a worse conversion sequence than
......
......@@ -1954,7 +1954,7 @@ struct GTY(()) lang_decl_fn {
unsigned thunk_p : 1;
unsigned this_thunk_p : 1;
unsigned hidden_friend_p : 1;
unsigned suppress_implicit_decl : 1;
/* 1 spare bit. */
/* For a non-thunk function decl, this is a tree list of
friendly classes. For a thunk function decl, it is the
......@@ -3144,12 +3144,6 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define DECL_HIDDEN_FRIEND_P(NODE) \
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p)
/* Nonzero if NODE is a FUNCTION_DECL generated by implicitly_declare_fn
that we shouldn't actually declare implicitly; it is only used for
comparing to an =default declaration. */
#define FNDECL_SUPPRESS_IMPLICIT_DECL(NODE) \
(LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->suppress_implicit_decl)
/* Nonzero if DECL has been declared threadprivate by
#pragma omp threadprivate. */
#define CP_DECL_THREADPRIVATE_P(DECL) \
......
......@@ -4722,6 +4722,16 @@ using scalars of wider type, which normally is more performance efficient;
and @code{as a single scalar}, which means that vector fits into a
scalar type.
@item -Wno-virtual-move-assign
@opindex Wvirtual-move-assign
@opindex Wno-virtual-move-assign
Suppress warnings about inheriting from a virtual base with a
non-trivial C++11 move assignment operator. This is dangerous because
if the virtual base is reachable along more than one path, it will be
moved multiple times, which can mean both objects end up in the
moved-from state. If the move assignment operator is written to avoid
moving from a moved-from object, this warning can be disabled.
@item -Wvla
@opindex Wvla
@opindex Wno-vla
......
......@@ -3,13 +3,11 @@
struct A
{
int moved = 0;
A& operator=(A&&) { ++moved; }
~A() { if (moved > 1) __builtin_abort(); }
A& operator=(A&&);
};
struct B: virtual A { B& operator=(B&&) = default; };
struct C: virtual A { }; // { dg-error "operator=.const A&" }
struct B: virtual A { B& operator=(B&&) = default; }; // { dg-warning "virtual base" }
struct C: virtual A { }; // { dg-warning "virtual base" }
int main()
{
......@@ -17,5 +15,5 @@ int main()
b2 = static_cast<B&&>(b1);
C c1, c2;
c2 = static_cast<C&&>(c1); // { dg-error "operator=.const C&" }
c2 = static_cast<C&&>(c1);
}
// DR 1402
// { dg-options -std=c++11 }
template <class T> T&& move(T& t);
struct A
{
A(const A&);
};
struct B
{
B(B&&);
};
struct C
{
A a;
B b;
};
extern C c1;
C c2(move(c1));
// DR 1402
// { dg-options -std=c++11 }
template <class T> T&& move(T& t);
struct A
{
A(const A&);
};
struct B
{
B(B&&) = delete; // { dg-prune-output "declared" }
};
struct C // { dg-error "deleted" }
{
A a;
B b;
};
extern C c1;
C c2(move(c1)); // { dg-error "deleted" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment