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@-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*/); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits