re PR c++/63437 ([C++14] Parenthesized "movable but not copyable" object doesn't compile in return statement)
PR c++/63437 * cp-tree.h (REF_PARENTHESIZED_P): Also allow INDIRECT_REF. * semantics.c (force_paren_expr): And set it. * typeck.c (check_return_expr): And handle it. From-SVN: r216042
This commit is contained in:
parent
94c4084cf0
commit
96e780c087
@ -1,3 +1,10 @@
|
||||
2014-10-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/63437
|
||||
* cp-tree.h (REF_PARENTHESIZED_P): Also allow INDIRECT_REF.
|
||||
* semantics.c (force_paren_expr): And set it.
|
||||
* typeck.c (check_return_expr): And handle it.
|
||||
|
||||
2014-10-09 Marc Glisse <marc.glisse@inria.fr>
|
||||
|
||||
* decl.c (grokdeclarator): constexpr only implies const in C++11.
|
||||
|
@ -101,7 +101,7 @@ c-common.h, not after.
|
||||
TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR)
|
||||
FNDECL_USED_AUTO (in FUNCTION_DECL)
|
||||
DECLTYPE_FOR_LAMBDA_PROXY (in DECLTYPE_TYPE)
|
||||
REF_PARENTHESIZED_P (in COMPONENT_REF, SCOPE_REF)
|
||||
REF_PARENTHESIZED_P (in COMPONENT_REF, INDIRECT_REF)
|
||||
AGGR_INIT_ZERO_FIRST (in AGGR_INIT_EXPR)
|
||||
3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out).
|
||||
ICS_BAD_FLAG (in _CONV)
|
||||
@ -3059,11 +3059,12 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
||||
#define PAREN_STRING_LITERAL_P(NODE) \
|
||||
TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))
|
||||
|
||||
/* Indicates whether a COMPONENT_REF has been parenthesized. Currently
|
||||
only set some of the time in C++14 mode. */
|
||||
/* Indicates whether a COMPONENT_REF has been parenthesized, or an
|
||||
INDIRECT_REF comes from parenthesizing a VAR_DECL. Currently only set
|
||||
some of the time in C++14 mode. */
|
||||
|
||||
#define REF_PARENTHESIZED_P(NODE) \
|
||||
TREE_LANG_FLAG_2 (COMPONENT_REF_CHECK (NODE))
|
||||
TREE_LANG_FLAG_2 (TREE_CHECK2 ((NODE), COMPONENT_REF, INDIRECT_REF))
|
||||
|
||||
/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a
|
||||
constructor call, rather than an ordinary function call. */
|
||||
|
@ -1637,6 +1637,8 @@ force_paren_expr (tree expr)
|
||||
bool rval = !!(kind & clk_rvalueref);
|
||||
type = cp_build_reference_type (type, rval);
|
||||
expr = build_static_cast (type, expr, tf_error);
|
||||
if (expr != error_mark_node)
|
||||
REF_PARENTHESIZED_P (expr) = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8671,6 +8671,20 @@ check_return_expr (tree retval, bool *no_warning)
|
||||
if (VOID_TYPE_P (functype))
|
||||
return error_mark_node;
|
||||
|
||||
/* If we had an id-expression obfuscated by force_paren_expr, we need
|
||||
to undo it so we can try to treat it as an rvalue below. */
|
||||
if (cxx_dialect >= cxx14
|
||||
&& INDIRECT_REF_P (retval)
|
||||
&& REF_PARENTHESIZED_P (retval))
|
||||
{
|
||||
retval = TREE_OPERAND (retval, 0);
|
||||
while (TREE_CODE (retval) == NON_LVALUE_EXPR
|
||||
|| TREE_CODE (retval) == NOP_EXPR)
|
||||
retval = TREE_OPERAND (retval, 0);
|
||||
gcc_assert (TREE_CODE (retval) == ADDR_EXPR);
|
||||
retval = TREE_OPERAND (retval, 0);
|
||||
}
|
||||
|
||||
/* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
|
||||
treated as an rvalue for the purposes of overload resolution to
|
||||
favor move constructors over copy constructors.
|
||||
|
31
gcc/testsuite/g++.dg/cpp1y/paren1.C
Normal file
31
gcc/testsuite/g++.dg/cpp1y/paren1.C
Normal file
@ -0,0 +1,31 @@
|
||||
// PR c++/63437
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct X // movable but not copyable
|
||||
{
|
||||
X() = default;
|
||||
X(X &&) = default;
|
||||
|
||||
X(const X &) = delete;
|
||||
};
|
||||
|
||||
X non_parenthesized()
|
||||
{
|
||||
X x;
|
||||
return x; // works
|
||||
}
|
||||
|
||||
X parenthesized()
|
||||
{
|
||||
X x;
|
||||
return (x); // error: use of deleted function 'X::X(const X&)'
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T parenthesized_t()
|
||||
{
|
||||
T t;
|
||||
return (t);
|
||||
}
|
||||
|
||||
template X parenthesized_t<X>();
|
Loading…
Reference in New Issue
Block a user