public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ PATCH for c++/51406, 51161 (wrong-code with static cast to rvalue ref)
@ 2011-12-14  5:25 Jason Merrill
  2016-03-03 22:39 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2011-12-14  5:25 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 301 bytes --]

The code for casting to rvalue ref was assuming that no base adjustment 
would be necessary.  This patch delegates to the normal lvalue binding 
code, and then changes the result to be an rvalue reference.

Tested x86_64-pc-linux-gnu, applying to trunk.  Will apply to 4.5/4.6 as 
well after testing.

[-- Attachment #2: 51406.patch --]
[-- Type: text/x-patch, Size: 2652 bytes --]

commit ed6825825765c8c02a53dc011e252ddfacc9f5e5
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Dec 13 23:02:02 2011 -0500

    	PR c++/51406
    	PR c++/51161
    	* typeck.c (build_static_cast_1): Fix cast of lvalue to
    	base rvalue reference.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4973d7d..b168963 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5856,12 +5856,22 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
      cv2 T2 if cv2 T2 is reference-compatible with cv1 T1 (8.5.3)."  */
   if (TREE_CODE (type) == REFERENCE_TYPE
       && TYPE_REF_IS_RVALUE (type)
-      && lvalue_or_rvalue_with_address_p (expr)
+      && real_lvalue_p (expr)
       && reference_related_p (TREE_TYPE (type), intype)
       && (c_cast_p || at_least_as_qualified_p (TREE_TYPE (type), intype)))
     {
-      expr = build_typed_address (expr, type);
-      return convert_from_reference (expr);
+      /* Handle the lvalue case here by casting to lvalue reference and
+	 then changing it to an rvalue reference.  Casting an xvalue to
+	 rvalue reference will be handled by the main code path.  */
+      tree lref = cp_build_reference_type (TREE_TYPE (type), false);
+      result = (perform_direct_initialization_if_possible
+		(lref, expr, c_cast_p, complain));
+      result = cp_fold_convert (type, result);
+      /* Make sure we don't fold back down to a named rvalue reference,
+	 because that would be an lvalue.  */
+      if (DECL_P (result))
+	result = build1 (NON_LVALUE_EXPR, type, result);
+      return convert_from_reference (result);
     }
 
   /* Resolve overloaded address here rather than once in
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast3.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast3.C
new file mode 100644
index 0000000..6c70324
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast3.C
@@ -0,0 +1,17 @@
+// PR c++/51406
+// { dg-do run { target c++11 } }
+
+extern "C" int printf(const char *,...);
+extern "C" void abort();
+
+struct A { int a; A() : a(1) {} };
+struct B { int b; B() : b(2) {} };
+struct X : A, B {};
+
+int main() {
+    X x;
+    int a=static_cast<A&&>(x).a;
+    int b=static_cast<B&&>(x).b;
+    // printf ("%d %d\n", a, b);
+    if (a!=1 || b!=2) abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast4.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast4.C
new file mode 100644
index 0000000..13f369d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast4.C
@@ -0,0 +1,13 @@
+// PR c++/51161
+// { dg-do compile { target c++11 } }
+
+struct A{};
+struct B : A{};
+struct C : A{};
+struct D : B, C{};
+
+int main()
+{
+  D d;
+  static_cast<A &&>(d);		// { dg-error "ambiguous" }
+}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: C++ PATCH for c++/51406, 51161 (wrong-code with static cast to rvalue ref)
  2011-12-14  5:25 C++ PATCH for c++/51406, 51161 (wrong-code with static cast to rvalue ref) Jason Merrill
@ 2016-03-03 22:39 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2016-03-03 22:39 UTC (permalink / raw)
  To: gcc-patches List

[-- Attachment #1: Type: text/plain, Size: 591 bytes --]

On 12/14/2011 12:14 AM, Jason Merrill wrote:
> The code for casting to rvalue ref was assuming that no base adjustment
> would be necessary.  This patch delegates to the normal lvalue binding
> code, and then changes the result to be an rvalue reference.

The test for DECL_P isn't sufficient to catch all cases where the result 
of cp_fold_convert is still an lvalue.  Now that we're doing delayed 
folding, let's replace the cp_fold_convert with an unconditional 
NON_LVALUE_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk.  For GCC 5 I'm changing 
DECL_P to real_lvalue_p instead.



[-- Attachment #2: 51406.patch --]
[-- Type: text/x-patch, Size: 1357 bytes --]

commit 46ab061b39527bbdd427bdf887eb6954768d4b61
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 2 01:11:30 2016 -0500

    	PR c++/51406
    
    	* typeck.c (build_static_cast_1): Avoid folding back to lvalue.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 5145879..20f0afc 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6704,11 +6704,7 @@ build_static_cast_1 (tree type, tree expr, bool c_cast_p,
 	  tree lref = cp_build_reference_type (TREE_TYPE (type), false);
 	  result = (perform_direct_initialization_if_possible
 		    (lref, expr, c_cast_p, complain));
-	  result = cp_fold_convert (type, result);
-	  /* Make sure we don't fold back down to a named rvalue reference,
-	     because that would be an lvalue.  */
-	  if (DECL_P (result))
-	    result = build1 (NON_LVALUE_EXPR, type, result);
+	  result = build1 (NON_LVALUE_EXPR, type, result);
 	  return convert_from_reference (result);
 	}
       else
diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-cast5.C b/gcc/testsuite/g++.dg/cpp0x/rv-cast5.C
new file mode 100644
index 0000000..c2473e2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/rv-cast5.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct hold {
+  T value;
+  constexpr T&& operator()() && { return static_cast<T&&>(value); }
+};
+
+int main()
+{
+  hold<bool&&>{42}();
+}

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2016-03-03 22:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-14  5:25 C++ PATCH for c++/51406, 51161 (wrong-code with static cast to rvalue ref) Jason Merrill
2016-03-03 22:39 ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).