r282911 - [CUDA] Emit a warning if a CUDA host/device/global attribute is placed after '(...)'.

Justin Lebar via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 30 12:55:55 PDT 2016


Author: jlebar
Date: Fri Sep 30 14:55:55 2016
New Revision: 282911

URL: http://llvm.org/viewvc/llvm-project?rev=282911&view=rev
Log:
[CUDA] Emit a warning if a CUDA host/device/global attribute is placed after '(...)'.

Summary:
This is probably the sane place for the attribute to go, but nvcc
specifically rejects it.  Other GNU-style attributes are allowed in this
position (although judging from the warning it emits for
host/device/global, those attributes are applied to the lambda's
anonymous struct, not to the function itself).

It would be nice to have a FixIt message here, but doing so, or even
just getting the correct range for the attribute, including its '((' and
'))'s, is apparently Hard.

Reviewers: rnk

Subscribers: cfe-commits, tra

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

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/test/Parser/lambda-attr.cu

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=282911&r1=282910&r2=282911&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Sep 30 14:55:55 2016
@@ -1022,6 +1022,10 @@ def err_pragma_invalid_keyword : Error<
 def warn_pragma_unroll_cuda_value_in_parens : Warning<
   "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
   InGroup<CudaCompat>;
+
+def warn_cuda_attr_lambda_position : Warning<
+  "nvcc does not allow '__%0__' to appear after '()' in lambdas">,
+  InGroup<CudaCompat>;
 } // end of Parse Issue category.
 
 let CategoryName = "Modules Issue" in {

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=282911&r1=282910&r2=282911&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Sep 30 14:55:55 2016
@@ -1134,6 +1134,18 @@ ExprResult Parser::ParseLambdaExpression
     MaybeParseGNUAttributes(D);
   }
 
+  // Helper to emit a warning if we see a CUDA host/device/global attribute
+  // after '(...)'. nvcc doesn't accept this.
+  auto WarnIfHasCUDATargetAttr = [&] {
+    if (getLangOpts().CUDA)
+      for (auto *A = Attr.getList(); A != nullptr; A = A->getNext())
+        if (A->getKind() == AttributeList::AT_CUDADevice ||
+            A->getKind() == AttributeList::AT_CUDAHost ||
+            A->getKind() == AttributeList::AT_CUDAGlobal)
+          Diag(A->getLoc(), diag::warn_cuda_attr_lambda_position)
+              << A->getName()->getName();
+  };
+
   TypeResult TrailingReturnType;
   if (Tok.is(tok::l_paren)) {
     ParseScope PrototypeScope(this,
@@ -1210,6 +1222,8 @@ ExprResult Parser::ParseLambdaExpression
 
     PrototypeScope.Exit();
 
+    WarnIfHasCUDATargetAttr();
+
     SourceLocation NoLoc;
     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
                                            /*isAmbiguous=*/false,
@@ -1275,6 +1289,8 @@ ExprResult Parser::ParseLambdaExpression
         DeclEndLoc = Range.getEnd();
     }
 
+    WarnIfHasCUDATargetAttr();
+
     SourceLocation NoLoc;
     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
                                                /*isAmbiguous=*/false,

Modified: cfe/trunk/test/Parser/lambda-attr.cu
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/lambda-attr.cu?rev=282911&r1=282910&r2=282911&view=diff
==============================================================================
--- cfe/trunk/test/Parser/lambda-attr.cu (original)
+++ cfe/trunk/test/Parser/lambda-attr.cu Fri Sep 30 14:55:55 2016
@@ -1,33 +1,42 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -fcuda-is-device -verify %s
 
-// expected-no-diagnostics
-
 __attribute__((device)) void device_fn() {}
 __attribute__((device)) void hd_fn() {}
 
 __attribute__((device)) void device_attr() {
   ([]() __attribute__((device)) { device_fn(); })();
+  // expected-warning at -1 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([] __attribute__((device)) () { device_fn(); })();
   ([] __attribute__((device)) { device_fn(); })();
 
   ([&]() __attribute__((device)){ device_fn(); })();
+  // expected-warning at -1 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([&] __attribute__((device)) () { device_fn(); })();
   ([&] __attribute__((device)) { device_fn(); })();
 
   ([&](int) __attribute__((device)){ device_fn(); })(0);
+  // expected-warning at -1 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([&] __attribute__((device)) (int) { device_fn(); })(0);
 }
 
 __attribute__((host)) __attribute__((device)) void host_device_attrs() {
   ([]() __attribute__((host)) __attribute__((device)){ hd_fn(); })();
+  // expected-warning at -1 {{nvcc does not allow '__host__' to appear after '()' in lambdas}}
+  // expected-warning at -2 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([] __attribute__((host)) __attribute__((device)) () { hd_fn(); })();
   ([] __attribute__((host)) __attribute__((device)) { hd_fn(); })();
 
   ([&]() __attribute__((host)) __attribute__((device)){ hd_fn(); })();
+  // expected-warning at -1 {{nvcc does not allow '__host__' to appear after '()' in lambdas}}
+  // expected-warning at -2 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([&] __attribute__((host)) __attribute__((device)) () { hd_fn(); })();
   ([&] __attribute__((host)) __attribute__((device)) { hd_fn(); })();
 
   ([&](int) __attribute__((host)) __attribute__((device)){ hd_fn(); })(0);
+  // expected-warning at -1 {{nvcc does not allow '__host__' to appear after '()' in lambdas}}
+  // expected-warning at -2 {{nvcc does not allow '__device__' to appear after '()' in lambdas}}
   ([&] __attribute__((host)) __attribute__((device)) (int) { hd_fn(); })(0);
 }
+
+// TODO: Add tests for __attribute__((global)) once we support global lambdas.




More information about the cfe-commits mailing list