diff mbox

C++ PATCH for c++/60019 / CWG 5 (copy-initialization of cv-qualified object)

Message ID 536D1B42.2090205@redhat.com
State New
Headers show

Commit Message

Jason Merrill May 9, 2014, 6:15 p.m. UTC
CWG DR 5 specifies that in the two-step copy-initialization process, the 
temporary object of the target type which is created and then copied 
into the target object has cv-unqualified type; this allows volatile 
objects to be copy-initialized with the usual copy-constructor signature.

Tested x86_64-pc-linux-gnu, applying to trunk.
diff mbox

Patch

commit b99bece161794661520f1e613b67638f5c478dd5
Author: Jason Merrill <jason@redhat.com>
Date:   Thu May 8 17:15:58 2014 -0400

    	DR 5
    	PR c++/60019
    	* call.c (build_user_type_conversion_1): The copy-init temporary
    	is cv-unqualified.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index cff7ef3..187fc77 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -3693,11 +3693,20 @@  build_user_type_conversion_1 (tree totype, tree expr, int flags,
       return cand;
     }
 
+  tree convtype;
+  if (!DECL_CONSTRUCTOR_P (cand->fn))
+    convtype = non_reference (TREE_TYPE (TREE_TYPE (cand->fn)));
+  else if (cand->second_conv->kind == ck_rvalue)
+    /* DR 5: [in the first step of copy-initialization]...if the function
+       is a constructor, the call initializes a temporary of the
+       cv-unqualified version of the destination type. */
+    convtype = cv_unqualified (totype);
+  else
+    convtype = totype;
   /* Build the user conversion sequence.  */
   conv = build_conv
     (ck_user,
-     (DECL_CONSTRUCTOR_P (cand->fn)
-      ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
+     convtype,
      build_identity_conv (TREE_TYPE (expr), expr));
   conv->cand = cand;
   if (cand->viable == -1)
diff --git a/gcc/testsuite/g++.dg/init/copy7.C b/gcc/testsuite/g++.dg/init/copy7.C
new file mode 100644
index 0000000..655fae2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/copy7.C
@@ -0,0 +1,9 @@ 
+// CWG 5
+
+struct C { };
+C c;
+struct A {
+  A(const A&);
+  A(const C&);
+};
+const volatile A a = c;    // Okay