Author: Alexey Bataev Date: 2019-12-13T16:51:46-05:00 New Revision: 8035bb4a6573f7d20f17044a68a1405691000525
URL: https://github.com/llvm/llvm-project/commit/8035bb4a6573f7d20f17044a68a1405691000525 DIFF: https://github.com/llvm/llvm-project/commit/8035bb4a6573f7d20f17044a68a1405691000525.diff LOG: [OPENMP]Fix skipping of functions body. When parsing the code with OpenMP and the function's body must be skipped, need to skip also OpenMP annotation tokens. Otherwise the counters for braces/parens are unbalanced and parsing fails. Added: clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp Modified: clang/include/clang/Parse/Parser.h clang/include/clang/Parse/RAIIObjectsForParser.h clang/lib/Parse/ParseOpenMP.cpp clang/lib/Parse/Parser.cpp clang/test/OpenMP/openmp_check.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index a1e7bbba9b8e..7d13a4b597c1 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -56,6 +56,7 @@ namespace clang { /// class Parser : public CodeCompletionHandler { friend class ColonProtectionRAIIObject; + friend class ParsingOpenMPDirectiveRAII; friend class InMessageExpressionRAIIObject; friend class PoisonSEHIdentifiersRAIIObject; friend class ObjCDeclContextSwitch; @@ -215,6 +216,9 @@ class Parser : public CodeCompletionHandler { /// ColonProtectionRAIIObject RAII object. bool ColonIsSacred; + /// Parsing OpenMP directive mode. + bool OpenMPDirectiveParsing = false; + /// When true, we are directly inside an Objective-C message /// send expression. /// diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h index 558106eb684d..fb092c050783 100644 --- a/clang/include/clang/Parse/RAIIObjectsForParser.h +++ b/clang/include/clang/Parse/RAIIObjectsForParser.h @@ -287,6 +287,25 @@ namespace clang { } }; + /// Activates OpenMP parsing mode to preseve OpenMP specific annotation + /// tokens. + class ParsingOpenMPDirectiveRAII { + Parser &P; + bool OldVal; + + public: + ParsingOpenMPDirectiveRAII(Parser &P) + : P(P), OldVal(P.OpenMPDirectiveParsing) { + P.OpenMPDirectiveParsing = true; + } + + /// This can be used to restore the state early, before the dtor + /// is run. + void restore() { P.OpenMPDirectiveParsing = OldVal; } + + ~ParsingOpenMPDirectiveRAII() { restore(); } + }; + /// RAII object that makes '>' behave either as an operator /// or as the closing angle bracket for a template argument list. class GreaterThanIsOperatorScope { diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 442d2ce0e0f5..9dbbcc08db86 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1332,6 +1332,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, DeclSpec::TST TagType, Decl *Tag) { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); + ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SourceLocation Loc = ConsumeAnnotationToken(); @@ -1667,6 +1668,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); + ParsingOpenMPDirectiveRAII DirScope(*this); ParenBraceBracketBalancer BalancerRAIIObj(*this); SmallVector<OMPClause *, 5> Clauses; SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 2645f27e656f..ed4e6ff0fc53 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -278,6 +278,10 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) { case tok::annot_pragma_openmp: case tok::annot_pragma_openmp_end: // Stop before an OpenMP pragma boundary. + if (OpenMPDirectiveParsing) + return false; + ConsumeAnnotationToken(); + break; case tok::annot_module_begin: case tok::annot_module_end: case tok::annot_module_include: diff --git a/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp b/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp new file mode 100644 index 000000000000..c7ba432d5090 --- /dev/null +++ b/clang/test/OpenMP/crash-skipped-bodies-template-inst.cpp @@ -0,0 +1,30 @@ +// RUN: not %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:28:5 -fopenmp %s -o - 2>&1 | FileCheck %s +template <class T> +auto make_func() { + struct impl { + impl* func() { + int x; + if (x = 10) { + #pragma omp parallel + ; + } + // Check that body of this function is actually skipped. + // CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a condition without parentheses + return this; + } + }; + + int x; + if (x = 10) {} + // Check that this function is not skipped. + // CHECK: crash-skipped-bodies-template-inst.cpp:18:9: warning: using the result of an assignment as a condition without parentheses + return impl(); +} + +void foo() { + []() { + make_func<int>(); + m + // CHECK: COMPLETION: make_func : [#auto#]make_func<<#class T#>>() + }; +} diff --git a/clang/test/OpenMP/openmp_check.cpp b/clang/test/OpenMP/openmp_check.cpp index cd4706b57e44..6a8dd17fc836 100644 --- a/clang/test/OpenMP/openmp_check.cpp +++ b/clang/test/OpenMP/openmp_check.cpp @@ -19,7 +19,6 @@ int nested(int a) { #if __cplusplus <= 199711L // expected-warning@-2 {{'auto' type specifier is a C++11 extension}} // expected-error@-3 {{expected expression}} - // expected-error@-4 {{expected ';' at end of declaration}} #endif #pragma omp parallel @@ -29,14 +28,5 @@ int nested(int a) { } }; F(); -#if __cplusplus <= 199711L - // expected-error@-2 {{C++ requires a type specifier for all declarations}} -#endif return a; -#if __cplusplus <= 199711L - // expected-error@-2 {{expected unqualified-id}} -#endif } -#if __cplusplus <= 199711L -// expected-error@-2 {{extraneous closing brace ('}')}} -#endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits