re PR c++/69736 ("error: too few arguments to function" in c++14 but not c++11)
Fix PR c++/69736 gcc/cp/ChangeLog: PR c++/69736 * cp-tree.h (REF_PARENTHESIZED_P): Adjust documentation. (maybe_undo_parenthesized_ref): Declare. * semantics.c (maybe_undo_parenthesized_ref): Split out from check_return_expr. (finish_call_expr): Use it. * typeck.c (check_return_expr): Use it. * pt.c (tsubst_copy_and_build) [INDIRECT_REF]: Retain the REF_PARENTHESIZED_P flag. gcc/testsuite/ChangeLog: PR c++/69736 * g++.dg/cpp1y/paren2.C: New test. From-SVN: r233691
This commit is contained in:
parent
a8b233b7f2
commit
1137001cd9
7 changed files with 83 additions and 12 deletions
|
@ -1,3 +1,15 @@
|
|||
2016-02-25 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
PR c++/69736
|
||||
* cp-tree.h (REF_PARENTHESIZED_P): Adjust documentation.
|
||||
(maybe_undo_parenthesized_ref): Declare.
|
||||
* semantics.c (maybe_undo_parenthesized_ref): Split out from
|
||||
check_return_expr.
|
||||
(finish_call_expr): Use it.
|
||||
* typeck.c (check_return_expr): Use it.
|
||||
* pt.c (tsubst_copy_and_build) [INDIRECT_REF]: Retain the
|
||||
REF_PARENTHESIZED_P flag.
|
||||
|
||||
2016-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/69922
|
||||
|
|
|
@ -3393,7 +3393,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE))
|
||||
|
||||
/* Indicates whether a COMPONENT_REF has been parenthesized, or an
|
||||
INDIRECT_REF comes from parenthesizing a VAR_DECL. Currently only set
|
||||
INDIRECT_REF comes from parenthesizing a _DECL. Currently only set
|
||||
some of the time in C++14 mode. */
|
||||
|
||||
#define REF_PARENTHESIZED_P(NODE) \
|
||||
|
@ -6361,6 +6361,7 @@ extern tree finish_label_stmt (tree);
|
|||
extern void finish_label_decl (tree);
|
||||
extern cp_expr finish_parenthesized_expr (cp_expr);
|
||||
extern tree force_paren_expr (tree);
|
||||
extern tree maybe_undo_parenthesized_ref (tree);
|
||||
extern tree finish_non_static_data_member (tree, tree, tree);
|
||||
extern tree begin_stmt_expr (void);
|
||||
extern tree finish_stmt_expr_expr (tree, tree);
|
||||
|
|
|
@ -15961,6 +15961,10 @@ tsubst_copy_and_build (tree t,
|
|||
else
|
||||
r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR,
|
||||
complain|decltype_flag);
|
||||
|
||||
if (TREE_CODE (r) == INDIRECT_REF)
|
||||
REF_PARENTHESIZED_P (r) = REF_PARENTHESIZED_P (t);
|
||||
|
||||
RETURN (r);
|
||||
}
|
||||
|
||||
|
|
|
@ -1673,6 +1673,30 @@ force_paren_expr (tree expr)
|
|||
return expr;
|
||||
}
|
||||
|
||||
/* If T is an id-expression obfuscated by force_paren_expr, undo the
|
||||
obfuscation and return the underlying id-expression. Otherwise
|
||||
return T. */
|
||||
|
||||
tree
|
||||
maybe_undo_parenthesized_ref (tree t)
|
||||
{
|
||||
if (cxx_dialect >= cxx14
|
||||
&& INDIRECT_REF_P (t)
|
||||
&& REF_PARENTHESIZED_P (t))
|
||||
{
|
||||
t = TREE_OPERAND (t, 0);
|
||||
while (TREE_CODE (t) == NON_LVALUE_EXPR
|
||||
|| TREE_CODE (t) == NOP_EXPR)
|
||||
t = TREE_OPERAND (t, 0);
|
||||
|
||||
gcc_assert (TREE_CODE (t) == ADDR_EXPR
|
||||
|| TREE_CODE (t) == STATIC_CAST_EXPR);
|
||||
t = TREE_OPERAND (t, 0);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Finish a parenthesized expression EXPR. */
|
||||
|
||||
cp_expr
|
||||
|
@ -2256,6 +2280,10 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
|
|||
|
||||
gcc_assert (!TYPE_P (fn));
|
||||
|
||||
/* If FN may be a FUNCTION_DECL obfuscated by force_paren_expr, undo
|
||||
it so that we can tell this is a call to a known function. */
|
||||
fn = maybe_undo_parenthesized_ref (fn);
|
||||
|
||||
orig_fn = fn;
|
||||
|
||||
if (processing_template_decl)
|
||||
|
|
|
@ -8917,17 +8917,7 @@ check_return_expr (tree retval, bool *no_warning)
|
|||
|
||||
/* 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);
|
||||
}
|
||||
retval = maybe_undo_parenthesized_ref (retval);
|
||||
|
||||
/* Under C++11 [12.8/32 class.copy], a returned lvalue is sometimes
|
||||
treated as an rvalue for the purposes of overload resolution to
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-02-25 Patrick Palka <ppalka@gcc.gnu.org>
|
||||
|
||||
PR c++/69736
|
||||
* g++.dg/cpp1y/paren2.C: New test.
|
||||
|
||||
2016-02-24 Martin Sebor <msebor@redhat.com>
|
||||
|
||||
PR c/51147
|
||||
|
|
31
gcc/testsuite/g++.dg/cpp1y/paren2.C
Normal file
31
gcc/testsuite/g++.dg/cpp1y/paren2.C
Normal file
|
@ -0,0 +1,31 @@
|
|||
// PR c++/69736
|
||||
// { dg-do compile { target c++14 } }
|
||||
|
||||
void fn1(bool = true)
|
||||
{
|
||||
(fn1)();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fn2(T a = true)
|
||||
{
|
||||
(fn1)();
|
||||
}
|
||||
|
||||
void foo ()
|
||||
{
|
||||
(fn2<bool>)();
|
||||
}
|
||||
|
||||
struct X
|
||||
{
|
||||
static void fn3(bool = true)
|
||||
{
|
||||
(X::fn3)();
|
||||
}
|
||||
|
||||
void fn4(bool = true)
|
||||
{
|
||||
(X::fn4)();
|
||||
}
|
||||
};
|
Loading…
Add table
Reference in a new issue