aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@gcc.gnu.org>2016-02-25 01:14:27 +0000
committerPatrick Palka <ppalka@gcc.gnu.org>2016-02-25 01:14:27 +0000
commit1137001cd9b3751964b44ab80861cf7a91aa197b (patch)
treef621bb008d6f17792de60637f9e2e5e36d9e9ead /gcc/cp
parenta8b233b7f204138b2629db2b818c807df4a1ef52 (diff)
downloadgcc-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/ChangeLog12
-rw-r--r--gcc/cp/cp-tree.h3
-rw-r--r--gcc/cp/pt.c4
-rw-r--r--gcc/cp/semantics.c28
-rw-r--r--gcc/cp/typeck.c12
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