summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJustin Lebar <jlebar@google.com>2016-09-28 22:45:58 +0000
committerJustin Lebar <jlebar@google.com>2016-09-28 22:45:58 +0000
commitb17840de33e316a633749bab2c97c470d93ce933 (patch)
tree01e3fcbd55d5caa92cc7f3c932716ab845a67928 /clang
parent2a8db34044c3a994bc2198730ac61a8a7f38878f (diff)
downloadbcm5719-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.td4
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaCUDA.cpp20
-rw-r--r--clang/lib/Sema/SemaType.cpp4
-rw-r--r--clang/test/SemaCUDA/vla-host-device.cu21
-rw-r--r--clang/test/SemaCUDA/vla.cu12
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}}
+}
OpenPOWER on IntegriCloud