Anastasia updated this revision to Diff 201011.
Anastasia added a comment.

- Switched back to loop over all method qualifiers
- Moved addr space check into `AddOverloadCandidate`


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

https://reviews.llvm.org/D62156

Files:
  include/clang/Sema/Overload.h
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaInit.cpp
  lib/Sema/SemaOverload.cpp
  test/CodeGenCXX/address-space-of-this.cpp
  test/CodeGenOpenCLCXX/addrspace-ctor.cl
  test/SemaCXX/address-space-ctor.cpp

Index: test/SemaCXX/address-space-ctor.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/address-space-ctor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -std=c++14 -triple=spir -verify -fsyntax-only
+// RUN: %clang_cc1 %s -std=c++17 -triple=spir -verify -fsyntax-only
+
+struct MyType {
+  MyType(int i) : i(i) {}
+  int i;
+};
+
+// FIXME: We can't implicitly convert between address spaces yet.
+MyType __attribute__((address_space(10))) m1 = 123; //expected-error{{no viable conversion from 'int' to '__attribute__((address_space(10))) MyType'}}
+MyType __attribute__((address_space(10))) m2(123);  //expected-error{{no matching constructor for initialization of '__attribute__((address_space(10))) MyType'}}
Index: test/CodeGenOpenCLCXX/addrspace-ctor.cl
===================================================================
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-ctor.cl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s
+
+struct MyType {
+  MyType(int i) : i(i) {}
+  MyType(int i) __constant : i(i) {}
+  int i;
+  void bar();
+};
+
+//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* @const1, i32 1)
+__constant MyType const1 = 1;
+//CHECK: call void @_ZNU3AS26MyTypeC1Ei(%struct.MyType addrspace(2)* @const2, i32 2)
+__constant MyType const2(2);
+//CHECK: call void @_ZNU3AS46MyTypeC1Ei(%struct.MyType addrspace(4)* addrspacecast (%struct.MyType addrspace(1)* @glob to %struct.MyType addrspace(4)*), i32 1)
+MyType glob(1);
Index: test/CodeGenCXX/address-space-of-this.cpp
===================================================================
--- test/CodeGenCXX/address-space-of-this.cpp
+++ test/CodeGenCXX/address-space-of-this.cpp
@@ -1,8 +1,11 @@
 // RUN: %clang_cc1 %s -std=c++14 -triple=spir -emit-llvm -o - | FileCheck %s
 // RUN: %clang_cc1 %s -std=c++17 -triple=spir -emit-llvm -o - | FileCheck %s
+// XFAIL: *
 
+// FIXME: We can't compile address space method qualifiers yet.
+// Therefore there is no way to check correctness of this code.
 struct MyType {
-  MyType(int i) : i(i) {}
+  MyType(int i) __attribute__((address_space(10))) : i(i) {}
   int i;
 };
 //CHECK: call void @_ZN6MyTypeC1Ei(%struct.MyType* addrspacecast (%struct.MyType addrspace(10)* @m to %struct.MyType*), i32 123)
Index: lib/Sema/SemaOverload.cpp
===================================================================
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -6029,8 +6029,13 @@
   //   A defaulted move constructor that is defined as deleted is ignored by
   //   overload resolution.
   CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function);
-  if (Constructor && Constructor->isDefaulted() && Constructor->isDeleted() &&
-      Constructor->isMoveConstructor())
+  if (Constructor && ((Constructor->isDefaulted() && Constructor->isDeleted() &&
+                       Constructor->isMoveConstructor()) ||
+                      // Check that addr space of an object being constructed is
+                      // convertible to the one ctor qualified with.
+                      !Qualifiers::isAddressSpaceSupersetOf(
+                          Constructor->getMethodQualifiers().getAddressSpace(),
+                          CandidateSet.getDestAS())))
     return;
 
   // Overload resolution is always an unevaluated context.
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -3897,6 +3897,7 @@
   // Build the candidate set directly in the initialization sequence
   // structure, so that it will persist if we fail.
   OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
+  CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
 
   // Determine whether we are allowed to call explicit constructors or
   // explicit conversion operators.
@@ -4989,6 +4990,7 @@
   // structure, so that it will persist if we fail.
   OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
   CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion);
+  CandidateSet.setDestAS(DestType.getQualifiers().getAddressSpace());
 
   // Determine whether we are allowed to call explicit constructors or
   // explicit conversion operators.
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -8226,12 +8226,15 @@
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
   if (FTI.hasMethodTypeQualifiers()) {
+    bool DiagOccured = false;
     FTI.MethodQualifiers->forEachQualifier(
         [&](DeclSpec::TQ TypeQual, StringRef QualName, SourceLocation SL) {
           Diag(SL, diag::err_invalid_qualified_constructor)
               << QualName << SourceRange(SL);
+          DiagOccured = true;
         });
-    D.setInvalidType();
+    if (DiagOccured)
+      D.setInvalidType();
   }
 
   // C++0x [class.ctor]p4:
Index: include/clang/Sema/Overload.h
===================================================================
--- include/clang/Sema/Overload.h
+++ include/clang/Sema/Overload.h
@@ -873,6 +873,9 @@
     unsigned NumInlineBytesUsed = 0;
     llvm::AlignedCharArray<alignof(void *), NumInlineBytes> InlineSpace;
 
+    // Address space of the object being constructed.
+    LangAS DestAS = LangAS::Default;
+
     /// If we have space, allocates from inline storage. Otherwise, allocates
     /// from the slab allocator.
     /// FIXME: It would probably be nice to have a SmallBumpPtrAllocator
@@ -968,6 +971,10 @@
                         SourceLocation Loc = SourceLocation(),
                         llvm::function_ref<bool(OverloadCandidate&)> Filter =
                           [](OverloadCandidate&) { return true; });
+
+    LangAS getDestAS() { return DestAS; }
+
+    void setDestAS(LangAS AS) { DestAS = AS; }
   };
 
   bool isBetterOverloadCandidate(Sema &S,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to