[clang] 790cbaa - [OpenCL] Fix diagnostics with templates in kernel args.

Anastasia Stulova via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 10 10:56:35 PST 2022


Author: Anastasia Stulova
Date: 2022-11-10T18:55:12Z
New Revision: 790cbaafc9e276aa740373c00849951338056174

URL: https://github.com/llvm/llvm-project/commit/790cbaafc9e276aa740373c00849951338056174
DIFF: https://github.com/llvm/llvm-project/commit/790cbaafc9e276aa740373c00849951338056174.diff

LOG: [OpenCL] Fix diagnostics with templates in kernel args.

Improve checking for the standard layout type when diagnosing
the kernel argument with templated types. The check doesn't work
correctly for references or pointers due to the lazy template
instantiation.

Current fix only improves cases where nested types in the templates
do not depend on the template parameters.

Differential Revision: https://reviews.llvm.org/D134445

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/test/SemaOpenCLCXX/invalid-kernel.clcpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 3bec6b0f65e7b..bac87c0127236 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9234,10 +9234,23 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
     // reference if an implementation supports them in kernel parameters.
     if (S.getLangOpts().OpenCLCPlusPlus &&
         !S.getOpenCLOptions().isAvailableOption(
-            "__cl_clang_non_portable_kernel_param_types", S.getLangOpts()) &&
-        !PointeeType->isAtomicType() && !PointeeType->isVoidType() &&
-        !PointeeType->isStandardLayoutType())
+            "__cl_clang_non_portable_kernel_param_types", S.getLangOpts())) {
+     auto CXXRec = PointeeType.getCanonicalType()->getAsCXXRecordDecl();
+     bool IsStandardLayoutType = true;
+     if (CXXRec) {
+       // If template type is not ODR-used its definition is only available
+       // in the template definition not its instantiation.
+       // FIXME: This logic doesn't work for types that depend on template
+       // parameter (PR58590).
+       if (!CXXRec->hasDefinition())
+         CXXRec = CXXRec->getTemplateInstantiationPattern();
+       if (!CXXRec || !CXXRec->hasDefinition() || !CXXRec->isStandardLayout())
+         IsStandardLayoutType = false;
+     }
+     if (!PointeeType->isAtomicType() && !PointeeType->isVoidType() &&
+        !IsStandardLayoutType)
       return InvalidKernelParam;
+    }
 
     return PtrKernelParam;
   }

diff  --git a/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
index 9bd147364483c..8795fd7173018 100644
--- a/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
+++ b/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
@@ -93,3 +93,24 @@ kernel void trivial_r(__global Trivial &in) {}
 #ifndef UNSAFEKERNELPARAMETER
 //expected-error at -2{{'__global Trivial &__private' cannot be used as the type of a kernel parameter}}
 #endif
+
+// Nested types and templates
+struct Outer {
+  struct Inner{
+    int i;
+  };
+};
+template<class T>
+struct OuterTempl {
+  struct Inner{
+    int i;
+  };
+};
+// FIXME: (PR58590) Use of template parameter dependent types doesn't
+// work yet due to lazy instantiation of reference types.
+//template<class T>
+//struct Templ {
+//T i;
+//};
+
+extern kernel void nested(constant Outer::Inner& r1, constant OuterTempl<int>::Inner& r2/*, constant Templ<int>& r3*/);


        


More information about the cfe-commits mailing list