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