[PATCH] Fix PR20495: correct inference of the CUDA target for implicit members

Richard Smith richard at metafoo.co.uk
Thu Sep 4 16:47:58 PDT 2014


================
Comment at: lib/Sema/SemaCUDA.cpp:110-111
@@ +109,4 @@
+                                                    bool ConstRHS) {
+  CUDAFunctionTarget InferredTarget;
+  bool HasInferredTarget = false;
+
----------------
`Optional<CUDAFunctionTarget>` InferredTarget;

================
Comment at: lib/Sema/SemaCUDA.cpp:119
@@ +118,3 @@
+  // Infer the target of this member base on the ones it should call.
+  for (const auto &B : ClassDecl->bases()) {
+    const RecordType *BaseType = B.getType()->getAs<RecordType>();
----------------
For a non-abstract class, you should visit virtual bases as well as direct bases. (For an abstract class, you should skip direct and indirect virtual bases.)

================
Comment at: lib/Sema/SemaCUDA.cpp:128-132
@@ +127,7 @@
+        LookupSpecialMember(BaseClassDecl, CSM,
+                            /* ConstArg */ ConstRHS,
+                            /* VolatileArg */ false,
+                            /* RValueThis */ false,
+                            /* ConstThis */ false,
+                            /* VolatileThis */ false);
+
----------------
These are not necessarily correct; the user might have explicitly defaulted a const/volatile/whatever special member function.

================
Comment at: lib/Sema/SemaCUDA.cpp:146-148
@@ +145,5 @@
+      if (ResolutionError) {
+        Diag(ClassDecl->getLocation(),
+             diag::err_implicit_member_target_infer_collision)
+            << (unsigned)CSM << InferredTarget << BaseMethodTarget;
+        return;
----------------
Declaring implicit special members is done lazily, so emitting diagnostics from here will result in erratic behavior. It would be better to defer the diagnostic until the special member is defined in C++98, and to mark the member as deleted in this case in C++11.

================
Comment at: lib/Sema/SemaOverload.cpp:5637
@@ -5636,3 +5636,3 @@
     if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext))
-      if (CheckCUDATarget(Caller, Function)) {
+      if (!Caller->isImplicit() && CheckCUDATarget(Caller, Function)) {
         Candidate.Viable = false;
----------------
Hmm, why do you need this change?

http://reviews.llvm.org/D5199






More information about the cfe-commits mailing list