yaxunl created this revision.
yaxunl added reviewers: tra, rjmccall.

Clang infers defaulted ctor as `__device__ __host__` and virtual dtor as 
`__host__`.

It diagnose the following code in device compilation as B() references ~A() 
implicitly.

  struct A {  virtual ~A(); };
  struct B: public A { B(); };
  B::B() = default;

Clang should not diagnose the above code since B() may be used in host function 
only.
Clang should diagnose only if B() is used in device function or kernel.

This patch fixes that by assuming defaulted class member as not always emitted. 
Therefore
a definition of defaulted special member function does not trigger a 
diagnostic, unless
the defaulted special member function is really called.


https://reviews.llvm.org/D67509

Files:
  lib/Sema/SemaCUDA.cpp
  test/SemaCUDA/default-ctor.cu


Index: test/SemaCUDA/default-ctor.cu
===================================================================
--- /dev/null
+++ test/SemaCUDA/default-ctor.cu
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only 
-fcuda-is-device -verify %s
+
+#define __host__ __attribute__((host))
+#define __device__ __attribute__((device))
+
+struct Base {
+  virtual ~Base(); // expected-note {{'~Base' declared here}}
+};
+
+struct Unused : public Base {
+  Unused();
+};
+
+// Unused defaulted constructor should not cause diagnostics.
+Unused::Unused() = default;
+
+struct Used : public Base // expected-note {{'~Used' declared here}}
+{
+  Used();
+};
+
+Used::Used() = default; // expected-error {{reference to __host__ function 
'~Base' in __host__ __device__ function}}
+
+__device__ void f() {
+  Used x; // expected-error {{reference to __host__ function '~Used' in 
__device__ function}}
+          // expected-note@-1 {{called by 'f'}}
+}
Index: lib/Sema/SemaCUDA.cpp
===================================================================
--- lib/Sema/SemaCUDA.cpp
+++ lib/Sema/SemaCUDA.cpp
@@ -611,8 +611,12 @@
   // emitted, because (say) the definition could include "inline".
   FunctionDecl *Def = FD->getDefinition();
 
+  CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(FD);
+
   if (Def &&
-      
!isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
+      !isDiscardableGVALinkage(
+          S.getASTContext().GetGVALinkageForFunction(Def)) &&
+      !(MD && MD->isDefaulted()))
     return true;
 
   // Otherwise, the function is known-emitted if it's in our set of


Index: test/SemaCUDA/default-ctor.cu
===================================================================
--- /dev/null
+++ test/SemaCUDA/default-ctor.cu
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#define __host__ __attribute__((host))
+#define __device__ __attribute__((device))
+
+struct Base {
+  virtual ~Base(); // expected-note {{'~Base' declared here}}
+};
+
+struct Unused : public Base {
+  Unused();
+};
+
+// Unused defaulted constructor should not cause diagnostics.
+Unused::Unused() = default;
+
+struct Used : public Base // expected-note {{'~Used' declared here}}
+{
+  Used();
+};
+
+Used::Used() = default; // expected-error {{reference to __host__ function '~Base' in __host__ __device__ function}}
+
+__device__ void f() {
+  Used x; // expected-error {{reference to __host__ function '~Used' in __device__ function}}
+          // expected-note@-1 {{called by 'f'}}
+}
Index: lib/Sema/SemaCUDA.cpp
===================================================================
--- lib/Sema/SemaCUDA.cpp
+++ lib/Sema/SemaCUDA.cpp
@@ -611,8 +611,12 @@
   // emitted, because (say) the definition could include "inline".
   FunctionDecl *Def = FD->getDefinition();
 
+  CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(FD);
+
   if (Def &&
-      !isDiscardableGVALinkage(S.getASTContext().GetGVALinkageForFunction(Def)))
+      !isDiscardableGVALinkage(
+          S.getASTContext().GetGVALinkageForFunction(Def)) &&
+      !(MD && MD->isDefaulted()))
     return true;
 
   // Otherwise, the function is known-emitted if it's in our set of
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to