diff options
author | Justin Lebar <jlebar@google.com> | 2016-09-28 22:45:58 +0000 |
---|---|---|
committer | Justin Lebar <jlebar@google.com> | 2016-09-28 22:45:58 +0000 |
commit | b17840de33e316a633749bab2c97c470d93ce933 (patch) | |
tree | 01e3fcbd55d5caa92cc7f3c932716ab845a67928 /clang | |
parent | 2a8db34044c3a994bc2198730ac61a8a7f38878f (diff) | |
download | bcm5719-llvm-b17840de33e316a633749bab2c97c470d93ce933.tar.gz bcm5719-llvm-b17840de33e316a633749bab2c97c470d93ce933.zip |
[CUDA] Disallow variable-length arrays in CUDA device code.
Reviewers: tra
Subscribers: cfe-commits, jhen
Differential Revision: https://reviews.llvm.org/D25050
llvm-svn: 282647
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCUDA.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCUDA/vla-host-device.cu | 21 | ||||
-rw-r--r-- | clang/test/SemaCUDA/vla.cu | 12 |
6 files changed, 63 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 36b1ebd2299..44a8b0532a9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6713,6 +6713,10 @@ def err_shared_var_init : Error< def err_device_static_local_var : Error< "Within a __device__/__global__ function, " "only __shared__ variables may be marked \"static\"">; +def err_cuda_vla : Error< + "cannot use variable-length arrays in " + "%select{__device__|__global__|__host__|__host__ __device__}0 functions">; + def warn_non_pod_vararg_with_format_string : Warning< "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic " "%select{function|block|method|constructor}2; expected type from format " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2734e796526..8459a392446 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -9255,6 +9255,8 @@ public: /// ExprTy should be the string "try" or "throw", as appropriate. bool CheckCUDAExceptionExpr(SourceLocation Loc, StringRef ExprTy); + bool CheckCUDAVLA(SourceLocation Loc); + /// Finds a function in \p Matches with highest calling priority /// from \p Caller context and erases all functions with lower /// calling priority. diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp index b1939a17157..c75bdc7f59a 100644 --- a/clang/lib/Sema/SemaCUDA.cpp +++ b/clang/lib/Sema/SemaCUDA.cpp @@ -539,3 +539,23 @@ bool Sema::CheckCUDAExceptionExpr(SourceLocation Loc, StringRef ExprTy) { } return true; } + +bool Sema::CheckCUDAVLA(SourceLocation Loc) { + assert(getLangOpts().CUDA && "Should only be called during CUDA compilation"); + FunctionDecl *CurFn = dyn_cast<FunctionDecl>(CurContext); + if (!CurFn) + return true; + CUDAFunctionTarget Target = IdentifyCUDATarget(CurFn); + if (Target == CFT_Global || Target == CFT_Device) { + Diag(Loc, diag::err_cuda_vla) << Target; + return false; + } + if (Target == CFT_HostDevice && getLangOpts().CUDAIsDevice) { + PartialDiagnostic ErrPD{PartialDiagnostic::NullDiagnostic()}; + ErrPD.Reset(diag::err_cuda_vla); + ErrPD << Target; + CurFn->addDeferredDiag({Loc, std::move(ErrPD)}); + return false; + } + return true; +} diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1619483f082..dd833d72217 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2241,6 +2241,10 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, Diag(Loc, diag::err_opencl_vla); return QualType(); } + // CUDA device code doesn't support VLAs. + if (getLangOpts().CUDA && T->isVariableArrayType() && !CheckCUDAVLA(Loc)) + return QualType(); + // If this is not C99, extwarn about VLA's and C99 array size modifiers. if (!getLangOpts().C99) { if (T->isVariableArrayType()) { diff --git a/clang/test/SemaCUDA/vla-host-device.cu b/clang/test/SemaCUDA/vla-host-device.cu new file mode 100644 index 00000000000..0f54bdf4917 --- /dev/null +++ b/clang/test/SemaCUDA/vla-host-device.cu @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fcuda-is-device -verify -S %s -o /dev/null +// RUN: %clang_cc1 -verify -DHOST %s -S -o /dev/null + +#include "Inputs/cuda.h" + +#ifdef HOST +// expected-no-diagnostics +#endif + +__host__ __device__ void hd(int n) { + int x[n]; +#ifndef HOST + // expected-error@-2 {{cannot use variable-length arrays in __host__ __device__ functions}} +#endif +} + +// No error because never codegen'ed for device. +__host__ __device__ inline void hd_inline(int n) { + int x[n]; +} +void call_hd_inline() { hd_inline(42); } diff --git a/clang/test/SemaCUDA/vla.cu b/clang/test/SemaCUDA/vla.cu new file mode 100644 index 00000000000..7c73d9d91bf --- /dev/null +++ b/clang/test/SemaCUDA/vla.cu @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fcuda-is-device -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify -DHOST %s + +#include "Inputs/cuda.h" + +void host(int n) { + int x[n]; +} + +__device__ void device(int n) { + int x[n]; // expected-error {{cannot use variable-length arrays in __device__ functions}} +} |