Skip to content

Commit 8035bb4

Browse files
committed
[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.
1 parent e8af4fd commit 8035bb4

File tree

6 files changed

+59
-10
lines changed

6 files changed

+59
-10
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ namespace clang {
5656
///
5757
class Parser : public CodeCompletionHandler {
5858
friend class ColonProtectionRAIIObject;
59+
friend class ParsingOpenMPDirectiveRAII;
5960
friend class InMessageExpressionRAIIObject;
6061
friend class PoisonSEHIdentifiersRAIIObject;
6162
friend class ObjCDeclContextSwitch;
@@ -215,6 +216,9 @@ class Parser : public CodeCompletionHandler {
215216
/// ColonProtectionRAIIObject RAII object.
216217
bool ColonIsSacred;
217218

219+
/// Parsing OpenMP directive mode.
220+
bool OpenMPDirectiveParsing = false;
221+
218222
/// When true, we are directly inside an Objective-C message
219223
/// send expression.
220224
///

clang/include/clang/Parse/RAIIObjectsForParser.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,25 @@ namespace clang {
287287
}
288288
};
289289

290+
/// Activates OpenMP parsing mode to preseve OpenMP specific annotation
291+
/// tokens.
292+
class ParsingOpenMPDirectiveRAII {
293+
Parser &P;
294+
bool OldVal;
295+
296+
public:
297+
ParsingOpenMPDirectiveRAII(Parser &P)
298+
: P(P), OldVal(P.OpenMPDirectiveParsing) {
299+
P.OpenMPDirectiveParsing = true;
300+
}
301+
302+
/// This can be used to restore the state early, before the dtor
303+
/// is run.
304+
void restore() { P.OpenMPDirectiveParsing = OldVal; }
305+
306+
~ParsingOpenMPDirectiveRAII() { restore(); }
307+
};
308+
290309
/// RAII object that makes '>' behave either as an operator
291310
/// or as the closing angle bracket for a template argument list.
292311
class GreaterThanIsOperatorScope {

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
13321332
AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
13331333
DeclSpec::TST TagType, Decl *Tag) {
13341334
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1335+
ParsingOpenMPDirectiveRAII DirScope(*this);
13351336
ParenBraceBracketBalancer BalancerRAIIObj(*this);
13361337

13371338
SourceLocation Loc = ConsumeAnnotationToken();
@@ -1667,6 +1668,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
16671668
StmtResult
16681669
Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
16691670
assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1671+
ParsingOpenMPDirectiveRAII DirScope(*this);
16701672
ParenBraceBracketBalancer BalancerRAIIObj(*this);
16711673
SmallVector<OMPClause *, 5> Clauses;
16721674
SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>

clang/lib/Parse/Parser.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,10 @@ bool Parser::SkipUntil(ArrayRef<tok::TokenKind> Toks, SkipUntilFlags Flags) {
278278
case tok::annot_pragma_openmp:
279279
case tok::annot_pragma_openmp_end:
280280
// Stop before an OpenMP pragma boundary.
281+
if (OpenMPDirectiveParsing)
282+
return false;
283+
ConsumeAnnotationToken();
284+
break;
281285
case tok::annot_module_begin:
282286
case tok::annot_module_end:
283287
case tok::annot_module_include:
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: not %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:28:5 -fopenmp %s -o - 2>&1 | FileCheck %s
2+
template <class T>
3+
auto make_func() {
4+
struct impl {
5+
impl* func() {
6+
int x;
7+
if (x = 10) {
8+
#pragma omp parallel
9+
;
10+
}
11+
// Check that body of this function is actually skipped.
12+
// CHECK-NOT: crash-skipped-bodies-template-inst.cpp:7:{{[0-9]+}}: warning: using the result of an assignment as a condition without parentheses
13+
return this;
14+
}
15+
};
16+
17+
int x;
18+
if (x = 10) {}
19+
// Check that this function is not skipped.
20+
// CHECK: crash-skipped-bodies-template-inst.cpp:18:9: warning: using the result of an assignment as a condition without parentheses
21+
return impl();
22+
}
23+
24+
void foo() {
25+
[]() {
26+
make_func<int>();
27+
m
28+
// CHECK: COMPLETION: make_func : [#auto#]make_func<<#class T#>>()
29+
};
30+
}

clang/test/OpenMP/openmp_check.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ int nested(int a) {
1919
#if __cplusplus <= 199711L
2020
// expected-warning@-2 {{'auto' type specifier is a C++11 extension}}
2121
// expected-error@-3 {{expected expression}}
22-
// expected-error@-4 {{expected ';' at end of declaration}}
2322
#endif
2423

2524
#pragma omp parallel
@@ -29,14 +28,5 @@ int nested(int a) {
2928
}
3029
};
3130
F();
32-
#if __cplusplus <= 199711L
33-
// expected-error@-2 {{C++ requires a type specifier for all declarations}}
34-
#endif
3531
return a;
36-
#if __cplusplus <= 199711L
37-
// expected-error@-2 {{expected unqualified-id}}
38-
#endif
3932
}
40-
#if __cplusplus <= 199711L
41-
// expected-error@-2 {{extraneous closing brace ('}')}}
42-
#endif

0 commit comments

Comments
 (0)