================
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+struct S {                                     // #ctors
+  S(int);                                      // #sint
+  void f() const;                              // #f-const
+  void f() __attribute__((address_space(1)));  // #f-as \
+                                               // expected-error {{function 
type may not be qualified with an address space}}
+};
+
+using const_int = const int;
+using as1_int = __attribute__((address_space(1))) int;
+using const_S = const S;
+using as1_S = __attribute__((address_space(1))) S;
+
+void testQualifiers() {
+  // Ok; const is dropped on prvalues of non-class type.
+  (void)(const_int{1});
+  // Ok; address space is dropped on prvalues of non-class type.
+  (void)(as1_int{1});
+  // Ok; const is retained on prvalues of class type; const qualified
+  // member function called.
+  const_S{1}.f();
+  // Error; address space is retained on prvalues of class type, but no
+  // constructor or member function can be called.
+  as1_S{1}.f();
+  // expected-error@-1 {{no matching constructor for initialization of 'as1_S' 
(aka '__attribute__((address_space(1))) S')}}
+  // expected-error@-2 {{no matching member function for call to 'f'}}
+  // expected-note@#ctors 2 {{candidate constructor ignored: cannot be used to 
construct an object in address space '__attribute__((address_space(1)))'}}
+  // expected-note@#sint {{candidate constructor ignored: cannot be used to 
construct an object in address space '__attribute__((address_space(1)))'}}
+  // expected-note@#f-const {{candidate function not viable: 'this' object is 
in address space '1', but method expects object in generic address space}}
+  // expected-note@#f-as {{candidate function not viable: 'this' object is in 
address space '1', but method expects object in generic address space}}
+}
+
+void temporaryMaterializationTest() {
+  // An address-space-qualified class temporary retains the address space on
+  // the materialized object, so no constructor can be used.
+  as1_S{0};
+  // expected-error@-1 {{no matching constructor for initialization of 'as1_S' 
(aka '__attribute__((address_space(1))) S')}}
+  // expected-note@#ctors 2 {{candidate constructor ignored: cannot be used to 
construct an object in address space '__attribute__((address_space(1)))'}}
+  // expected-note@#sint {{candidate constructor ignored: cannot be used to 
construct an object in address space '__attribute__((address_space(1)))'}}
+}
+
+// FIXME: All qualifiers including address space are retained on array elements
+//        The code in getNonLValueExprType() to remove qualifiers from prvalues
+//        acts on the array type and not the element. The code to remove 
address
+//        spaces is never hit. I am not sure this if this is correct behavior.
----------------
tahonermann wrote:

I just happened to discover [section 3.3.9, "Temporary materialization" in the 
C++ for OpenCL 
specification](https://www.khronos.org/opencl/assets/CXX_for_OpenCL.html#_temporary_materialization).
 I don't know how I managed to not find it before. It is explicit in stating 
that temporaries are constructed in the private address space. The examples 
provided are helpful too.
> All temporaries are materialized in `__private` address space. If a reference 
> with another address space is bound to them, a conversion will be generated 
> in case it is valid, otherwise compilation will fail with a diagnostic.

https://github.com/llvm/llvm-project/pull/221233
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to