olestrohm updated this revision to Diff 350561.
olestrohm added a comment.

I've reverted to using Constructors and prioritizing based on which constructor 
is the most qualified.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102850/new/

https://reviews.llvm.org/D102850

Files:
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
  clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp


Index: clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
===================================================================
--- clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
+++ clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
@@ -1,14 +1,22 @@
-// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only
+// RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s
 
 __constant int g1; // expected-error {{variable in constant address space must 
be initialized}}
 __constant int g2 = 0;
 
 struct X {
   int x;
+//CHECK: -CXXConstructorDecl {{.*}} X 'void (){{( __attribute__.*)?}} 
__generic'
+  X() /*__generic*/ : x(0) {}
+//CHECK: -CXXConstructorDecl {{.*}} used X 'void (){{( __attribute__.*)?}} 
__private'
+  X() __private : x(0) {}
+//CHECK: -CXXConstructorDecl {{.*}} used X 'void (){{( __attribute__.*)?}} 
__global'
+  X() __global : x(0) {}
   constexpr X() __constant : x(0) {}
   constexpr X(int x) __constant : x(x) {}
 };
 
+__global X gx;
+
 //expected-note@+2{{candidate constructor (the implicit copy constructor) not 
viable: no known conversion from 'int' to 'const __generic Y' for 1st argument}}
 //expected-note@+1{{candidate constructor (the implicit move constructor) not 
viable: no known conversion from 'int' to '__generic Y' for 1st argument}}
 struct Y {
@@ -20,6 +28,7 @@
   __constant X cx1;
   __constant X cx2(1);
   __local X lx;
+  __private X x;
 
   __private Y py;
   __constant Y cy1; // expected-error{{variable in constant address space must 
be initialized}}
Index: clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
===================================================================
--- clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
+++ clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
@@ -11,8 +11,7 @@
   int x;
 
   // Local variables are handled in local_addrspace_init.clcpp
-  // FIXME: __private and __generic constructors clash for __private variable
-  // X() /*__generic*/ = default;
+  X() /*__generic*/ : x(0) {}
   X() __private : x(0) {}
   X() __global : x(0) {}
   constexpr X() __constant : x(0) {}
@@ -30,7 +29,7 @@
 // CHECK: @_ZZ1kE3cx2 = internal addrspace(2) constant %struct.X { i32 1 }
 
 kernel void k() {
-  // Check that the constructor for px is executed
+  // Check that the constructor for px calls the __private constructor.
   // CHECK: %px = alloca %struct.X
   // CHECK-NEXT: call spir_func void @_ZN1XC1Ev(%struct.X* {{.*}}%px)
   __private X px;
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -9867,6 +9867,19 @@
            S.IdentifyCUDAPreference(Caller, Cand2.Function);
   }
 
+  const auto *CD1 = dyn_cast_or_null<CXXConstructorDecl>(Cand1.Function);
+  const auto *CD2 = dyn_cast_or_null<CXXConstructorDecl>(Cand2.Function);
+  if (CD1 && CD2) {
+    QualType TT1 = CD1->getThisObjectType();
+    QualType TT2 = CD2->getThisObjectType();
+    if (TT1.getUnqualifiedType() == TT2.getUnqualifiedType() && TT1 != TT2) {
+      if (TT2.isAtLeastAsQualifiedAs(TT1))
+        return true;
+      if (TT1.isAtLeastAsQualifiedAs(TT2))
+        return false;
+    }
+  }
+
   return false;
 }
 


Index: clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
===================================================================
--- clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
+++ clang/test/SemaOpenCLCXX/addrspace-constructors.clcpp
@@ -1,14 +1,22 @@
-// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only
+// RUN: %clang_cc1 %s -pedantic -ast-dump -verify | FileCheck %s
 
 __constant int g1; // expected-error {{variable in constant address space must be initialized}}
 __constant int g2 = 0;
 
 struct X {
   int x;
+//CHECK: -CXXConstructorDecl {{.*}} X 'void (){{( __attribute__.*)?}} __generic'
+  X() /*__generic*/ : x(0) {}
+//CHECK: -CXXConstructorDecl {{.*}} used X 'void (){{( __attribute__.*)?}} __private'
+  X() __private : x(0) {}
+//CHECK: -CXXConstructorDecl {{.*}} used X 'void (){{( __attribute__.*)?}} __global'
+  X() __global : x(0) {}
   constexpr X() __constant : x(0) {}
   constexpr X(int x) __constant : x(x) {}
 };
 
+__global X gx;
+
 //expected-note@+2{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const __generic Y' for 1st argument}}
 //expected-note@+1{{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int' to '__generic Y' for 1st argument}}
 struct Y {
@@ -20,6 +28,7 @@
   __constant X cx1;
   __constant X cx2(1);
   __local X lx;
+  __private X x;
 
   __private Y py;
   __constant Y cy1; // expected-error{{variable in constant address space must be initialized}}
Index: clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
===================================================================
--- clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
+++ clang/test/CodeGenOpenCLCXX/addrspace-constructors.clcpp
@@ -11,8 +11,7 @@
   int x;
 
   // Local variables are handled in local_addrspace_init.clcpp
-  // FIXME: __private and __generic constructors clash for __private variable
-  // X() /*__generic*/ = default;
+  X() /*__generic*/ : x(0) {}
   X() __private : x(0) {}
   X() __global : x(0) {}
   constexpr X() __constant : x(0) {}
@@ -30,7 +29,7 @@
 // CHECK: @_ZZ1kE3cx2 = internal addrspace(2) constant %struct.X { i32 1 }
 
 kernel void k() {
-  // Check that the constructor for px is executed
+  // Check that the constructor for px calls the __private constructor.
   // CHECK: %px = alloca %struct.X
   // CHECK-NEXT: call spir_func void @_ZN1XC1Ev(%struct.X* {{.*}}%px)
   __private X px;
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -9867,6 +9867,19 @@
            S.IdentifyCUDAPreference(Caller, Cand2.Function);
   }
 
+  const auto *CD1 = dyn_cast_or_null<CXXConstructorDecl>(Cand1.Function);
+  const auto *CD2 = dyn_cast_or_null<CXXConstructorDecl>(Cand2.Function);
+  if (CD1 && CD2) {
+    QualType TT1 = CD1->getThisObjectType();
+    QualType TT2 = CD2->getThisObjectType();
+    if (TT1.getUnqualifiedType() == TT2.getUnqualifiedType() && TT1 != TT2) {
+      if (TT2.isAtLeastAsQualifiedAs(TT1))
+        return true;
+      if (TT1.isAtLeastAsQualifiedAs(TT2))
+        return false;
+    }
+  }
+
   return false;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to