summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-10 20:35:18 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-10 20:35:18 +0000
commitd0f428f3ede23100856ae3a06fd18576330b2dcb (patch)
tree193087f90b293e295fcee1521772d1f6161d0b8b
parentae364744ca7f0d79e23a4f30ec777efe4a10b7d7 (diff)
downloadppe42-gcc-d0f428f3ede23100856ae3a06fd18576330b2dcb.tar.gz
ppe42-gcc-d0f428f3ede23100856ae3a06fd18576330b2dcb.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@216106 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/cp-tree.h9
-rw-r--r--gcc/cp/semantics.c2
-rw-r--r--gcc/cp/typeck.c14
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/paren1.C31
5 files changed, 59 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8a29a7627ce..1d0c58bac9e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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-08 Jason Merrill <jason@redhat.com>
PR c++/63405
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 99cc7ec64c6..d149810bc42 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -100,7 +100,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)
@@ -3038,11 +3038,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. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8174eca4c95..5c6a9d3ce83 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1630,6 +1630,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;
}
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 9a80727dd8e..03d7ab807d7 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8579,6 +8579,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 >= cxx1y
+ && 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++0x [12.8/16 class.copy], a returned lvalue is sometimes
treated as an rvalue for the purposes of overload resolution to
favor move constructors over copy constructors.
diff --git a/gcc/testsuite/g++.dg/cpp1y/paren1.C b/gcc/testsuite/g++.dg/cpp1y/paren1.C
new file mode 100644
index 00000000000..809f2510099
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/paren1.C
@@ -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>();
OpenPOWER on IntegriCloud