r197553 - [OPENMP] Fix for parsing OpenMP directives with extra braces, brackets and parens
Alp Toker
alp at nuanti.com
Wed Dec 18 11:17:17 PST 2013
Reviewed by Aaron, r197597 and r197598.
Alp.
On 18/12/2013 18:48, Alp Toker wrote:
> Hi,
>
> SkipUntil and BalancedDelimiterTracker are meant to track balanced
> tokens so this was inherently an incorrect change to the Parser.
>
> The same or better recovery can be achieved, and the tests made to
> pass, by reverting r197553 and applying this one line fix to SkipUntil():
>
> --- a/lib/Parse/Parser.cpp
> +++ b/lib/Parse/Parser.cpp
> @@ -298,6 +298,7 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind>
> Toks, SkipUntilFlags Flags) {
> // Ran out of tokens.
> return false;
>
> + case tok::annot_pragma_openmp_end:
> case tok::annot_module_begin:
> case tok::annot_module_end:
> case tok::annot_module_include:
>
>
> Alp.
>
>
>
> On 18/12/2013 18:03, Alp Toker wrote:
>>
>> On 18/12/2013 17:30, Alp Toker wrote:
>>> Hi Alexey,
>>>
>>> There's a lot I don't understand about your commit so I'm somewhat
>>> uncomfortable here.
>>>
>>> I tried reverting your changes to BalancedDelimiterTracker locally
>>> and the tests still pass.
>>>
>>> It seems to go against the main purpose of ExpectAndConsume() and
>>> BalancedDelimiterTracker to skip counting braces, and I don't like
>>> the added complexity impacting key C/C++ parse facilities.
>>>
>>> Would a simple custom consume-to-end-of-annotation while loop serve
>>> your purpose better?
>>>
>>> Also, if you want to diagnose and provide recovery for this error it
>>> shouldn't be specific to 'omp' pragmas. There's a strong expectation
>>> that recovery should work the same and I think that'll fall into
>>> place naturally if you implement this properly instead of the way
>>> you did.
>>>
>>> So this patch has enough complexity (and issues in its current form,
>>> including the other ones Aaron cited) to roll it out and put it
>>> through pre-commit review. It's entirely possible though that I
>>> missed something -- what do you think?
>>
>> Joey pointed out that Hal did in fact review some of these changes
>> last month. We're discussing it now to see if the less intrusive
>> approach can work.
>>
>> Alp.
>>
>>
>>>
>>> Alp.
>>>
>>>
>>>
>>>
>>> On 18/12/2013 08:46, Alexey Bataev wrote:
>>>> Author: abataev
>>>> Date: Wed Dec 18 02:46:25 2013
>>>> New Revision: 197553
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=197553&view=rev
>>>> Log:
>>>> [OPENMP] Fix for parsing OpenMP directives with extra braces,
>>>> brackets and parens
>>>>
>>>> Modified:
>>>> cfe/trunk/include/clang/Parse/Parser.h
>>>> cfe/trunk/lib/Parse/ParseOpenMP.cpp
>>>> cfe/trunk/lib/Parse/Parser.cpp
>>>> cfe/trunk/lib/Parse/RAIIObjectsForParser.h
>>>> cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>> cfe/trunk/test/OpenMP/threadprivate_messages.cpp
>>>>
>>>> Modified: cfe/trunk/include/clang/Parse/Parser.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/include/clang/Parse/Parser.h (original)
>>>> +++ cfe/trunk/include/clang/Parse/Parser.h Wed Dec 18 02:46:25 2013
>>>> @@ -684,9 +684,13 @@ private:
>>>> /// If the input is malformed, this emits the specified
>>>> diagnostic. Next, if
>>>> /// SkipToTok is specified, it calls SkipUntil(SkipToTok).
>>>> Finally, true is
>>>> /// returned.
>>>> + /// If NoCount is true, it ignores parens/brackets/braces as
>>>> regular tokens
>>>> + /// and does not count them. By default it recursively skips
>>>> properly-nested
>>>> + /// parens/brackets/braces.
>>>> bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
>>>> const char *DiagMsg = "",
>>>> - tok::TokenKind SkipToTok = tok::unknown);
>>>> + tok::TokenKind SkipToTok = tok::unknown,
>>>> + bool NoCount = false);
>>>> /// \brief The parser expects a semicolon and, if present,
>>>> will consume it.
>>>> ///
>>>> @@ -789,7 +793,9 @@ public:
>>>> StopAtSemi = 1 << 0, ///< Stop skipping at semicolon
>>>> /// \brief Stop skipping at specified token, but don't skip
>>>> the token itself
>>>> StopBeforeMatch = 1 << 1,
>>>> - StopAtCodeCompletion = 1 << 2 ///< Stop at code completion
>>>> + StopAtCodeCompletion = 1 << 2, ///< Stop at code completion
>>>> + NoBracketsCount = 1 << 3 /// \brief Don't count
>>>> braces/brackets/parens
>>>> + /// to skip balanced pairs
>>>> };
>>>> friend LLVM_CONSTEXPR SkipUntilFlags operator|(SkipUntilFlags L,
>>>>
>>>> Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
>>>> +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Wed Dec 18 02:46:25 2013
>>>> @@ -48,7 +48,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
>>>> if (Tok.isNot(tok::annot_pragma_openmp_end)) {
>>>> Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
>>>> << getOpenMPDirectiveName(OMPD_threadprivate);
>>>> - SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch |
>>>> NoBracketsCount);
>>>> }
>>>> // Skip the last annot_pragma_openmp_end.
>>>> ConsumeToken();
>>>> @@ -66,7 +66,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpen
>>>> << getOpenMPDirectiveName(DKind);
>>>> break;
>>>> }
>>>> - SkipUntil(tok::annot_pragma_openmp_end);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, NoBracketsCount);
>>>> return DeclGroupPtrTy();
>>>> }
>>>> @@ -105,14 +105,14 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>> if (Tok.isNot(tok::annot_pragma_openmp_end)) {
>>>> Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
>>>> << getOpenMPDirectiveName(OMPD_threadprivate);
>>>> - SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch |
>>>> NoBracketsCount);
>>>> }
>>>> DeclGroupPtrTy Res =
>>>> Actions.ActOnOpenMPThreadprivateDirective(Loc,
>>>> Identifiers);
>>>> Directive = Actions.ActOnDeclStmt(Res, Loc,
>>>> Tok.getLocation());
>>>> }
>>>> - SkipUntil(tok::annot_pragma_openmp_end);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, NoBracketsCount);
>>>> break;
>>>> case OMPD_parallel: {
>>>> ConsumeToken();
>>>> @@ -171,13 +171,13 @@ StmtResult Parser::ParseOpenMPDeclarativ
>>>> break;
>>>> case OMPD_unknown:
>>>> Diag(Tok, diag::err_omp_unknown_directive);
>>>> - SkipUntil(tok::annot_pragma_openmp_end);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, NoBracketsCount);
>>>> break;
>>>> case OMPD_task:
>>>> case NUM_OPENMP_DIRECTIVES:
>>>> Diag(Tok, diag::err_omp_unexpected_directive)
>>>> << getOpenMPDirectiveName(DKind);
>>>> - SkipUntil(tok::annot_pragma_openmp_end);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, NoBracketsCount);
>>>> break;
>>>> }
>>>> return Directive;
>>>> @@ -194,7 +194,8 @@ bool Parser::ParseOpenMPSimpleVarList(Op
>>>> bool AllowScopeSpecifier) {
>>>> VarList.clear();
>>>> // Parse '('.
>>>> - BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end);
>>>> + BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> + true);
>>>> if (T.expectAndConsume(diag::err_expected_lparen_after,
>>>> getOpenMPDirectiveName(Kind)))
>>>> return true;
>>>> @@ -214,17 +215,17 @@ bool Parser::ParseOpenMPSimpleVarList(Op
>>>> ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
>>>> IsCorrect = false;
>>>> SkipUntil(tok::comma, tok::r_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> - StopBeforeMatch);
>>>> + StopBeforeMatch | NoBracketsCount);
>>>> } else if (ParseUnqualifiedId(SS, false, false, false,
>>>> ParsedType(),
>>>> TemplateKWLoc, Name)) {
>>>> IsCorrect = false;
>>>> SkipUntil(tok::comma, tok::r_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> - StopBeforeMatch);
>>>> + StopBeforeMatch | NoBracketsCount);
>>>> } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
>>>> Tok.isNot(tok::annot_pragma_openmp_end)) {
>>>> IsCorrect = false;
>>>> SkipUntil(tok::comma, tok::r_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> - StopBeforeMatch);
>>>> + StopBeforeMatch | NoBracketsCount);
>>>> Diag(PrevTok.getLocation(), diag::err_expected_ident)
>>>> << SourceRange(PrevTok.getLocation(), PrevTokLocation);
>>>> } else {
>>>> @@ -287,13 +288,13 @@ OMPClause *Parser::ParseOpenMPClause(Ope
>>>> case OMPC_unknown:
>>>> Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
>>>> << getOpenMPDirectiveName(DKind);
>>>> - SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
>>>> + SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch |
>>>> NoBracketsCount);
>>>> break;
>>>> case OMPC_threadprivate:
>>>> case NUM_OPENMP_CLAUSES:
>>>> Diag(Tok, diag::err_omp_unexpected_clause)
>>>> << getOpenMPClauseName(CKind) <<
>>>> getOpenMPDirectiveName(DKind);
>>>> - SkipUntil(tok::comma, tok::annot_pragma_openmp_end,
>>>> StopBeforeMatch);
>>>> + SkipUntil(tok::comma, tok::annot_pragma_openmp_end,
>>>> StopBeforeMatch | NoBracketsCount);
>>>> break;
>>>> }
>>>> return ErrorFound ? 0 : Clause;
>>>> @@ -308,7 +309,8 @@ OMPClause *Parser::ParseOpenMPSimpleClau
>>>> SourceLocation Loc = Tok.getLocation();
>>>> SourceLocation LOpen = ConsumeToken();
>>>> // Parse '('.
>>>> - BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end);
>>>> + BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> + true);
>>>> if (T.expectAndConsume(diag::err_expected_lparen_after,
>>>> getOpenMPClauseName(Kind)))
>>>> return 0;
>>>> @@ -342,7 +344,8 @@ OMPClause *Parser::ParseOpenMPVarListCla
>>>> SourceLocation Loc = Tok.getLocation();
>>>> SourceLocation LOpen = ConsumeToken();
>>>> // Parse '('.
>>>> - BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end);
>>>> + BalancedDelimiterTracker T(*this, tok::l_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> + true);
>>>> if (T.expectAndConsume(diag::err_expected_lparen_after,
>>>> getOpenMPClauseName(Kind)))
>>>> return 0;
>>>> @@ -357,7 +360,7 @@ OMPClause *Parser::ParseOpenMPVarListCla
>>>> Vars.push_back(VarExpr.take());
>>>> } else {
>>>> SkipUntil(tok::comma, tok::r_paren,
>>>> tok::annot_pragma_openmp_end,
>>>> - StopBeforeMatch);
>>>> + StopBeforeMatch | NoBracketsCount);
>>>> }
>>>> // Skip ',' if any
>>>> IsComma = Tok.is(tok::comma);
>>>>
>>>> Modified: cfe/trunk/lib/Parse/Parser.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/lib/Parse/Parser.cpp (original)
>>>> +++ cfe/trunk/lib/Parse/Parser.cpp Wed Dec 18 02:46:25 2013
>>>> @@ -159,7 +159,8 @@ static bool IsCommonTypo(tok::TokenKind
>>>> /// SkipToTok is specified, it calls SkipUntil(SkipToTok).
>>>> Finally, true is
>>>> /// returned.
>>>> bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok,
>>>> unsigned DiagID,
>>>> - const char *Msg, tok::TokenKind
>>>> SkipToTok) {
>>>> + const char *Msg, tok::TokenKind
>>>> SkipToTok,
>>>> + bool NoCount) {
>>>> if (Tok.is(ExpectedTok) || Tok.is(tok::code_completion)) {
>>>> ConsumeAnyToken();
>>>> return false;
>>>> @@ -189,8 +190,12 @@ bool Parser::ExpectAndConsume(tok::Token
>>>> } else
>>>> Diag(Tok, DiagID) << Msg;
>>>> - if (SkipToTok != tok::unknown)
>>>> - SkipUntil(SkipToTok, StopAtSemi);
>>>> + if (SkipToTok != tok::unknown) {
>>>> + SkipUntilFlags Flags = StopAtSemi;
>>>> + if (NoCount)
>>>> + Flags = Flags | NoBracketsCount;
>>>> + SkipUntil(SkipToTok, Flags);
>>>> + }
>>>> return true;
>>>> }
>>>> @@ -314,26 +319,32 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok
>>>> case tok::l_paren:
>>>> // Recursively skip properly-nested parens.
>>>> ConsumeParen();
>>>> - if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> - SkipUntil(tok::r_paren, StopAtCodeCompletion);
>>>> - else
>>>> - SkipUntil(tok::r_paren);
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount)) {
>>>> + if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> + SkipUntil(tok::r_paren, StopAtCodeCompletion);
>>>> + else
>>>> + SkipUntil(tok::r_paren);
>>>> + }
>>>> break;
>>>> case tok::l_square:
>>>> // Recursively skip properly-nested square brackets.
>>>> ConsumeBracket();
>>>> - if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> - SkipUntil(tok::r_square, StopAtCodeCompletion);
>>>> - else
>>>> - SkipUntil(tok::r_square);
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount)) {
>>>> + if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> + SkipUntil(tok::r_square, StopAtCodeCompletion);
>>>> + else
>>>> + SkipUntil(tok::r_square);
>>>> + }
>>>> break;
>>>> case tok::l_brace:
>>>> // Recursively skip properly-nested braces.
>>>> ConsumeBrace();
>>>> - if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> - SkipUntil(tok::r_brace, StopAtCodeCompletion);
>>>> - else
>>>> - SkipUntil(tok::r_brace);
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount)) {
>>>> + if (HasFlagsSet(Flags, StopAtCodeCompletion))
>>>> + SkipUntil(tok::r_brace, StopAtCodeCompletion);
>>>> + else
>>>> + SkipUntil(tok::r_brace);
>>>> + }
>>>> break;
>>>> // Okay, we found a ']' or '}' or ')', which we think
>>>> should be balanced.
>>>> @@ -342,17 +353,17 @@ bool Parser::SkipUntil(ArrayRef<tok::Tok
>>>> // higher level, we will assume that this matches the
>>>> unbalanced token
>>>> // and return it. Otherwise, this is a spurious RHS token,
>>>> which we skip.
>>>> case tok::r_paren:
>>>> - if (ParenCount && !isFirstTokenSkipped)
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount) && ParenCount &&
>>>> !isFirstTokenSkipped)
>>>> return false; // Matches something.
>>>> ConsumeParen();
>>>> break;
>>>> case tok::r_square:
>>>> - if (BracketCount && !isFirstTokenSkipped)
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount) && BracketCount &&
>>>> !isFirstTokenSkipped)
>>>> return false; // Matches something.
>>>> ConsumeBracket();
>>>> break;
>>>> case tok::r_brace:
>>>> - if (BraceCount && !isFirstTokenSkipped)
>>>> + if (!HasFlagsSet(Flags, NoBracketsCount) && BraceCount &&
>>>> !isFirstTokenSkipped)
>>>> return false; // Matches something.
>>>> ConsumeBrace();
>>>> break;
>>>> @@ -2031,7 +2042,7 @@ bool BalancedDelimiterTracker::expectAnd
>>>> const char *Msg,
>>>> tok::TokenKind
>>>> SkipToToc ) {
>>>> LOpen = P.Tok.getLocation();
>>>> - if (P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc))
>>>> + if (P.ExpectAndConsume(Kind, DiagID, Msg, SkipToToc, NoCount))
>>>> return true;
>>>> if (getDepth() < MaxDepth)
>>>> @@ -2056,16 +2067,21 @@ bool BalancedDelimiterTracker::diagnoseM
>>>> // If we're not already at some kind of closing bracket, skip
>>>> to our closing
>>>> // token.
>>>> + Parser::SkipUntilFlags Flags = Parser::StopAtSemi |
>>>> Parser::StopBeforeMatch;
>>>> + if (NoCount)
>>>> + Flags = Flags | Parser::NoBracketsCount;
>>>> if (P.Tok.isNot(tok::r_paren) && P.Tok.isNot(tok::r_brace) &&
>>>> P.Tok.isNot(tok::r_square) &&
>>>> - P.SkipUntil(Close, FinalToken,
>>>> - Parser::StopAtSemi | Parser::StopBeforeMatch) &&
>>>> + P.SkipUntil(Close, FinalToken, Flags) &&
>>>> P.Tok.is(Close))
>>>> LClose = P.ConsumeAnyToken();
>>>> return true;
>>>> }
>>>> void BalancedDelimiterTracker::skipToEnd() {
>>>> - P.SkipUntil(Close, Parser::StopBeforeMatch);
>>>> + Parser::SkipUntilFlags Flags = Parser::StopBeforeMatch;
>>>> + if (NoCount)
>>>> + Flags = Flags | Parser::NoBracketsCount;
>>>> + P.SkipUntil(Close, Flags);
>>>> consumeClose();
>>>> }
>>>>
>>>> Modified: cfe/trunk/lib/Parse/RAIIObjectsForParser.h
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/RAIIObjectsForParser.h?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/lib/Parse/RAIIObjectsForParser.h (original)
>>>> +++ cfe/trunk/lib/Parse/RAIIObjectsForParser.h Wed Dec 18 02:46:25
>>>> 2013
>>>> @@ -361,6 +361,7 @@ namespace clang {
>>>> tok::TokenKind Kind, Close, FinalToken;
>>>> SourceLocation (Parser::*Consumer)();
>>>> SourceLocation LOpen, LClose;
>>>> + bool NoCount;
>>>> unsigned short &getDepth() {
>>>> switch (Kind) {
>>>> @@ -378,9 +379,10 @@ namespace clang {
>>>> public:
>>>> BalancedDelimiterTracker(Parser& p, tok::TokenKind k,
>>>> - tok::TokenKind FinalToken = tok::semi)
>>>> + tok::TokenKind FinalToken = tok::semi,
>>>> + bool NoCount = false)
>>>> : GreaterThanIsOperatorScope(p.GreaterThanIsOperator, true),
>>>> - P(p), Kind(k), FinalToken(FinalToken)
>>>> + P(p), Kind(k), FinalToken(FinalToken), NoCount(NoCount)
>>>> {
>>>> switch (Kind) {
>>>> default: llvm_unreachable("Unexpected balanced token");
>>>>
>>>> Modified: cfe/trunk/test/OpenMP/parallel_messages.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_messages.cpp?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/test/OpenMP/parallel_messages.cpp (original)
>>>> +++ cfe/trunk/test/OpenMP/parallel_messages.cpp Wed Dec 18 02:46:25
>>>> 2013
>>>> @@ -6,6 +6,18 @@ void foo() {
>>>> #pragma omp parallel // expected-error {{unexpected OpenMP
>>>> directive '#pragma omp parallel'}}
>>>> int main(int argc, char **argv) {
>>>> + #pragma omp parallel { // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> + #pragma omp parallel ( // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> + #pragma omp parallel [ // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> + #pragma omp parallel ] // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> + #pragma omp parallel ) // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> + #pragma omp parallel } // expected-warning {{extra tokens at the
>>>> end of '#pragma omp parallel' are ignored}}
>>>> + foo();
>>>> #pragma omp parallel
>>>> #pragma omp parallel unknown() // expected-warning {{extra
>>>> tokens at the end of '#pragma omp parallel' are ignored}}
>>>> foo();
>>>>
>>>> Modified: cfe/trunk/test/OpenMP/threadprivate_messages.cpp
>>>> URL:
>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/threadprivate_messages.cpp?rev=197553&r1=197552&r2=197553&view=diff
>>>> ==============================================================================
>>>>
>>>> --- cfe/trunk/test/OpenMP/threadprivate_messages.cpp (original)
>>>> +++ cfe/trunk/test/OpenMP/threadprivate_messages.cpp Wed Dec 18
>>>> 02:46:25 2013
>>>> @@ -24,6 +24,12 @@ int foo() { // expected-note {{declared
>>>> return (a);
>>>> }
>>>> +#pragma omp threadprivate (a) ( // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> +#pragma omp threadprivate (a) [ // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> +#pragma omp threadprivate (a) { // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> +#pragma omp threadprivate (a) ) // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> +#pragma omp threadprivate (a) ] // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> +#pragma omp threadprivate (a) } // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'a'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>> #pragma omp threadprivate a // expected-error {{expected '('
>>>> after 'threadprivate'}}
>>>> #pragma omp threadprivate(d // expected-error {{expected ')'}}
>>>> expected-note {{to match this '('}} expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'd'}}
>>>> #pragma omp threadprivate(d)) // expected-error {{'#pragma omp
>>>> threadprivate' must precede all references to variable 'd'}}
>>>> expected-warning {{extra tokens at the end of '#pragma omp
>>>> threadprivate' are ignored}}
>>>>
>>>>
>>>> _______________________________________________
>>>> cfe-commits mailing list
>>>> cfe-commits at cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>
>>
>
--
http://www.nuanti.com
the browser experts
More information about the cfe-commits
mailing list