]> granicus.if.org Git - clang/commitdiff
[CUDA] Disallow variable-length arrays in CUDA device code.
authorJustin Lebar <jlebar@google.com>
Wed, 28 Sep 2016 22:45:58 +0000 (22:45 +0000)
committerJustin Lebar <jlebar@google.com>
Wed, 28 Sep 2016 22:45:58 +0000 (22:45 +0000)
Reviewers: tra

Subscribers: cfe-commits, jhen

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@282647 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaCUDA.cpp
lib/Sema/SemaType.cpp
test/SemaCUDA/vla-host-device.cu [new file with mode: 0644]
test/SemaCUDA/vla.cu [new file with mode: 0644]

index 36b1ebd22990df992cbdd117baf3ec6baea5454f..44a8b0532a98ed75b65f6903167d13e57c1e7bd6 100644 (file)
@@ -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 "
index 2734e79652662f3280afea1991a99c7d898f4dc5..8459a392446aa8b02205d5c879056a0ba0675ae4 100644 (file)
@@ -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.
index b1939a17157878cb740cb10baa3cb215f1fdbb10..c75bdc7f59a74d70a5c2505189da39bfae57a77e 100644 (file)
@@ -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;
+}
index 1619483f08296ad7cc22777c25758fc58e85aadc..dd833d7221764f1305ef0736309de920c11d00f2 100644 (file)
@@ -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/test/SemaCUDA/vla-host-device.cu b/test/SemaCUDA/vla-host-device.cu
new file mode 100644 (file)
index 0000000..0f54bdf
--- /dev/null
@@ -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/test/SemaCUDA/vla.cu b/test/SemaCUDA/vla.cu
new file mode 100644 (file)
index 0000000..7c73d9d
--- /dev/null
@@ -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}}
+}