diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 1beddb5808fa2..b66ecf0724b1c 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1357,6 +1357,7 @@ def warn_pragma_acc_unimplemented_clause_parsing InGroup; def err_acc_invalid_directive : Error<"invalid OpenACC directive '%0'">; +def err_acc_missing_directive : Error<"expected OpenACC directive">; // OpenMP support. def warn_pragma_omp_ignored : Warning< diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index ba29d75fe35a5..e0c8d43955646 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -42,6 +42,14 @@ OpenACCDirectiveKind GetOpenACCDirectiveKind(StringRef Name) { // Parse and consume the tokens for OpenACC Directive/Construct kinds. OpenACCDirectiveKind ParseOpenACCDirectiveKind(Parser &P) { Token FirstTok = P.getCurToken(); + + // Just #pragma acc can get us immediately to the end, make sure we don't + // introspect on the spelling before then. + if (FirstTok.isAnnotation()) { + P.Diag(FirstTok, diag::err_acc_missing_directive); + return OpenACCDirectiveKind::Invalid; + } + P.ConsumeToken(); std::string FirstTokSpelling = P.getPreprocessor().getSpelling(FirstTok); diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c index e0607e7cfe316..8642833691ede 100644 --- a/clang/test/ParserOpenACC/parse-constructs.c +++ b/clang/test/ParserOpenACC/parse-constructs.c @@ -1,6 +1,12 @@ // RUN: %clang_cc1 %s -verify -fopenacc void func() { + + // expected-error@+2{{expected OpenACC directive}} + // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} +#pragma acc + for(;;){} + // expected-error@+2{{invalid OpenACC directive 'invalid'}} // expected-warning@+1{{OpenACC directives not yet implemented, pragma ignored}} #pragma acc invalid