[clang] 8035bb4 - [OPENMP]Fix skipping of functions body.
Alexey Bataev via cfe-commits
cfe-commits at lists.llvm.org
Fri Dec 13 13:56:09 PST 2019
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 at -2 {{'auto' type specifier is a C++11 extension}}
// expected-error at -3 {{expected expression}}
- // expected-error at -4 {{expected ';' at end of declaration}}
#endif
#pragma omp parallel
@@ -29,14 +28,5 @@ int nested(int a) {
}
};
F();
-#if __cplusplus <= 199711L
- // expected-error at -2 {{C++ requires a type specifier for all declarations}}
-#endif
return a;
-#if __cplusplus <= 199711L
- // expected-error at -2 {{expected unqualified-id}}
-#endif
}
-#if __cplusplus <= 199711L
-// expected-error at -2 {{extraneous closing brace ('}')}}
-#endif
More information about the cfe-commits
mailing list