]> granicus.if.org Git - clang/commitdiff
Fix PR20081: Parsing templates in the presence of -x cuda -std=c++11
authorEli Bendersky <eliben@google.com>
Fri, 20 Jun 2014 13:09:59 +0000 (13:09 +0000)
committerEli Bendersky <eliben@google.com>
Fri, 20 Jun 2014 13:09:59 +0000 (13:09 +0000)
http://reviews.llvm.org/D4222

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

lib/Parse/ParseTemplate.cpp
test/Parser/cuda-kernel-call-c++11.cu [new file with mode: 0644]
test/Parser/cuda-kernel-call.cu

index 6551fe25da9f49b8f4e9898e1e19e676035cc2c4..fa6401f083a6001db2b9ada78acbb35c7a942605 100644 (file)
@@ -751,7 +751,9 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
 
   // This template-id is terminated by a token which starts with a '>'. Outside
   // C++11, this is now error recovery, and in C++11, this is error recovery if
-  // the token isn't '>>'.
+  // the token isn't '>>' or '>>>'.
+  // '>>>' is for CUDA, where this sequence of characters is parsed into
+  // tok::greatergreatergreater, rather than two separate tokens.
 
   RAngleLoc = Tok.getLocation();
 
@@ -781,7 +783,8 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
     Hint2 = FixItHint::CreateInsertion(Next.getLocation(), " ");
 
   unsigned DiagId = diag::err_two_right_angle_brackets_need_space;
-  if (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater))
+  if (getLangOpts().CPlusPlus11 &&
+      (Tok.is(tok::greatergreater) || Tok.is(tok::greatergreatergreater)))
     DiagId = diag::warn_cxx98_compat_two_right_angle_brackets;
   else if (Tok.is(tok::greaterequal))
     DiagId = diag::err_right_angle_bracket_equal_needs_space;
diff --git a/test/Parser/cuda-kernel-call-c++11.cu b/test/Parser/cuda-kernel-call-c++11.cu
new file mode 100644 (file)
index 0000000..8f833f7
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename> struct S {};
+template<typename> void f();
+
+
+void foo(void) {
+  // In C++11 mode, all of these are expected to parse correctly, and the CUDA
+  // language should not interfere with that.
+
+  // expected-no-diagnostics
+
+  S<S<S<int>>> s3;
+
+  S<S<S<S<int>>>> s4;
+
+  S<S<S<S<S<int>>>>> s5;
+
+  (void)(&f<S<S<int>>>==0);
+}
index 92e46e3acaf53cf1adf6ad0634f98ed86eeab18a..1970c558c5063cd21afe2ba60ace27f5aabcb7ff 100644 (file)
@@ -10,7 +10,8 @@ void foo(void) {
 
   foo<<<>>>();  // expected-error {{expected expression}}
 
-  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
+  // The following two are parse errors because -std=c++11 is not enabled.
 
+  S<S<S<int>>> s; // expected-error 2{{use '> >'}}
   (void)(&f<S<S<int>>>==0); // expected-error 2{{use '> >'}}
 }