diff options
author | Patrick Palka <ppalka@gcc.gnu.org> | 2016-02-25 01:14:27 +0000 |
---|---|---|
committer | Patrick Palka <ppalka@gcc.gnu.org> | 2016-02-25 01:14:27 +0000 |
commit | 1137001cd9b3751964b44ab80861cf7a91aa197b (patch) | |
tree | f621bb008d6f17792de60637f9e2e5e36d9e9ead /gcc/cp | |
parent | a8b233b7f204138b2629db2b818c807df4a1ef52 (diff) | |
download | gcc-1137001cd9b3751964b44ab80861cf7a91aa197b.zip gcc-1137001cd9b3751964b44ab80861cf7a91aa197b.tar.gz gcc-1137001cd9b3751964b44ab80861cf7a91aa197b.tar.bz2 |
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
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 4 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 28 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 12 |
5 files changed, 47 insertions, 12 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 28a3168..3ae4daf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3c23a83a..88c6367 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e9cdf6e8..cd3eb67 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -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); } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index c15b160..fad233a 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -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) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 5e62220..5145879 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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 |