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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233691
138bc75d-0d04-0410-961f-
82ee72b054a4
+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
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) \
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);
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);
}
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
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)
/* 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
+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
--- /dev/null
+// 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)();
+ }
+};