<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sun, May 18, 2014 at 5:19 PM, Alp Toker <span dir="ltr"><<a href="mailto:alp@nuanti.com" target="_blank">alp@nuanti.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5"><br>
On 19/05/2014 02:29, Adam Strzelecki wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
When assigning to POD without user defined copy constructor implicit address<br>
space conversion will be done if assigned value has same type but different<br>
address space and no matching constructor was found.<br>
<br>
This allows OpenCL address space conversion in C++ mode for POD types.<br>
---<br>
  lib/Sema/SemaInit.cpp                     | 22 +++++++++++++++++++++-<br>
  test/SemaCXX/address-space-<u></u>initialize.cpp | 28 ++++++++++++++++++++++++++++<br>
  2 files changed, 49 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp<br>
index fe1f7c8..63ddd72 100644<br>
--- a/lib/Sema/SemaInit.cpp<br>
+++ b/lib/Sema/SemaInit.cpp<br>
@@ -4606,9 +4606,28 @@ void InitializationSequence::<u></u>InitializeFrom(Sema &S,<br>
      if (Kind.getKind() == InitializationKind::IK_Direct ||<br>
          (Kind.getKind() == InitializationKind::IK_Copy &&<br>
           (Context.<u></u>hasSameUnqualifiedType(<u></u>SourceType, DestType) ||<br>
-          S.IsDerivedFrom(SourceType, DestType))))<br>
+          S.IsDerivedFrom(SourceType, DestType)))) {<br>
+<br>
        TryConstructorInitialization(<u></u>S, Entity, Kind, Args,<br>
                                     Entity.getType(), *this);<br>
+<br>
+      // Relax rules and do implicit conversion if copy constructor<br>
+      // initialization fails due address space mismatch and destination class<br>
+      // is POD without user defined copy constructor<br>
+      if (Failed() && Failure == FK_ConstructorOverloadFailed &&<br>
+          Kind.getKind() == InitializationKind::IK_Copy &&<br>
+          SourceType.getAddressSpace() != DestType.getAddressSpace()) {<br>
+        const RecordType *DestRecordType = DestType->getAs<RecordType>();<br>
+        CXXRecordDecl *DestRecordDecl<br>
+          = cast<CXXRecordDecl>(<u></u>DestRecordType->getDecl());<br>
+        if (DestRecordDecl->isPOD() &&<br>
+            !DestRecordDecl-><u></u>hasUserDeclaredCopyConstructor<u></u>() &&<br>
+            DestRecordDecl-><u></u>hasCopyConstructorWithConstPar<u></u>am()) {<br>
+          setSequenceKind(SequenceKind::<u></u>NormalSequence);<br>
+          goto ImplicitConversion;<br>
+        }<br>
+      }<br>
+    }<br>
</blockquote>
<br></div></div>
Would your use case be satisfied with isCXX11PODType(), essentially RD->isTrivial() && RD->isStandardLayout()?<br>
<br>
If so (and if there's interest in going with this) it'd be preferable to define the language extension in those existing terms.<br></blockquote><div><br></div><div>I think you're right that using POD here is a mistake, but I don't really think that trivial and standard layout are the right things to check. Instead, I think the rule should be something like: if you cannot initialize an X from a Y, and dropping the address space from Y allows the initialization to succeed in such a way that it only invokes trivial copy/move constructors, then the initialization is permitted, and is performed by first copying Y into X's address space, then calling the trivial constructor (the latter copy should always be elided in practice).</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Do we want an extension diagnostic here? As David Chisnall pointed out there are other possible interpretations even if this happens to be the one we already use in C mode.<br></blockquote><div><br></div><div>Do we have some underlying standard of which this is an extension?</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Alp.<div><div class="h5"><br>
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
      //     - Otherwise (i.e., for the remaining copy-initialization cases),<br>
      //       user-defined conversion sequences that can convert from the source<br>
      //       type to the destination type or (when a conversion function is<br>
@@ -4636,6 +4655,7 @@ void InitializationSequence::<u></u>InitializeFrom(Sema &S,<br>
      return;<br>
    }<br>
  +ImplicitConversion:<br>
    //    - Otherwise, the initial value of the object being initialized is the<br>
    //      (possibly converted) value of the initializer expression. Standard<br>
    //      conversions (Clause 4) will be used, if necessary, to convert the<br>
diff --git a/test/SemaCXX/address-space-<u></u>initialize.cpp b/test/SemaCXX/address-space-<u></u>initialize.cpp<br>
index 5091338..293a9cf 100644<br>
--- a/test/SemaCXX/address-space-<u></u>initialize.cpp<br>
+++ b/test/SemaCXX/address-space-<u></u>initialize.cpp<br>
@@ -23,3 +23,31 @@ int* as_ptr = nocv_iarray; // expected-error{{cannot initialize a variable of ty<br>
  __attribute__((address_space(<u></u>42))) int* __attribute__((address_space(<u></u>42))) ptr_in_same_addr_space = nocv_iarray;<br>
  __attribute__((address_space(<u></u>42))) int* __attribute__((address_space(<u></u>999))) ptr_in_different_addr_space = nocv_iarray;<br>
  +<br>
+struct A { virtual ~A() {} }; // \<br>
+  expected-note 1 {{candidate constructor (the implicit copy constructor)}} \<br>
+  expected-note 1 {{candidate constructor (the implicit default constructor)}}<br>
+struct C { float x, y; };<br>
+struct D : C { D(const D &i) {} }; // \<br>
+  expected-note 1 {{candidate constructor not viable}}<br>
+<br>
+typedef A *A_ptr;<br>
+typedef A __attribute__((address_space(<u></u>1))) *A_ptr_1;<br>
+typedef C *C_ptr;<br>
+typedef C __attribute__((address_space(<u></u>1))) *C_ptr_1;<br>
+typedef D *D_ptr;<br>
+typedef D __attribute__((address_space(<u></u>1))) *D_ptr_1;<br>
+<br>
+void test_assignment(A_ptr ap, A_ptr_1 ap1,<br>
+                     C_ptr cp, C_ptr_1 cp1,<br>
+                     D_ptr dp, D_ptr_1 dp1) {<br>
+  // No address space conversions<br>
+  A a1 = ap[0];<br>
+  C c1 = cp[0];<br>
+  D d1 = dp[0];<br>
+<br>
+  // Implicit address space conversion allowed only for POD without user defined copy constructor (C)<br>
+  A a2 = ap1[0]; // expected-error{{no matching constructor for initialization}}<br>
+  C c2 = cp1[0];<br>
+  D d2 = dp1[0]; // expected-error{{no matching constructor for initialization}}<br>
+}<br>
</blockquote>
<br>
-- <br>
</div></div><a href="http://www.nuanti.com" target="_blank">http://www.nuanti.com</a><br>
the browser experts<div class="HOEnZb"><div class="h5"><br>
<br>
______________________________<u></u>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>