forked from OSchip/llvm-project
Fix a parser crash when there are #pragmas in a context which requires a single
statement (after a case label, if, etc). Patch by Olivier Goffart! llvm-svn: 193545
This commit is contained in:
parent
4404eb4857
commit
426a47bddb
|
@ -1470,10 +1470,7 @@ private:
|
|||
/// A SmallVector of types.
|
||||
typedef SmallVector<ParsedType, 12> TypeVector;
|
||||
|
||||
StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0) {
|
||||
StmtVector Stmts;
|
||||
return ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc);
|
||||
}
|
||||
StmtResult ParseStatement(SourceLocation *TrailingElseLoc = 0);
|
||||
StmtResult ParseStatementOrDeclaration(StmtVector &Stmts,
|
||||
bool OnlyStatement,
|
||||
SourceLocation *TrailingElseLoc = 0);
|
||||
|
|
|
@ -41,6 +41,21 @@ using namespace clang;
|
|||
// C99 6.8: Statements and Blocks.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/// \brief Parse a standalone statement (for instance, as the body of an 'if',
|
||||
/// 'while', or 'for').
|
||||
StmtResult Parser::ParseStatement(SourceLocation *TrailingElseLoc) {
|
||||
StmtResult Res;
|
||||
|
||||
// We may get back a null statement if we found a #pragma. Keep going until
|
||||
// we get an actual statement.
|
||||
do {
|
||||
StmtVector Stmts;
|
||||
Res = ParseStatementOrDeclaration(Stmts, true, TrailingElseLoc);
|
||||
} while (!Res.isInvalid() && !Res.get());
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
/// ParseStatementOrDeclaration - Read 'statement' or 'declaration'.
|
||||
/// StatementOrDeclaration:
|
||||
/// statement
|
||||
|
|
|
@ -149,6 +149,28 @@ void PR14046f() {
|
|||
}
|
||||
// CHECK: declare extern_weak i32 @PR14046e()
|
||||
|
||||
// Parse #pragma weak after a label or case statement
|
||||
extern int PR16705a(void);
|
||||
extern int PR16705b(void);
|
||||
extern int PR16705c(void);
|
||||
void PR16705f(int a) {
|
||||
switch(a) {
|
||||
case 1:
|
||||
#pragma weak PR16705a
|
||||
PR16705a();
|
||||
default:
|
||||
#pragma weak PR16705b
|
||||
PR16705b();
|
||||
}
|
||||
label:
|
||||
#pragma weak PR16705c
|
||||
PR16705c();
|
||||
}
|
||||
|
||||
// CHECK: declare extern_weak i32 @PR16705a()
|
||||
// CHECK: declare extern_weak i32 @PR16705b()
|
||||
// CHECK: declare extern_weak i32 @PR16705c()
|
||||
|
||||
|
||||
///////////// TODO: stuff that still doesn't work
|
||||
|
||||
|
|
|
@ -15,3 +15,30 @@ extern int z;
|
|||
extern int a;
|
||||
/* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a b
|
||||
/* expected-warning {{extra tokens at end of '#pragma weak'}}*/ #pragma weak a = x c
|
||||
|
||||
|
||||
void pragma_is_not_a_statement(int x)
|
||||
{
|
||||
int t;
|
||||
|
||||
{
|
||||
if (x)
|
||||
#pragma weak t
|
||||
else // expected-error {{expected expression}}
|
||||
#pragma weak t
|
||||
}
|
||||
|
||||
switch (x) {
|
||||
case 1:
|
||||
#pragma weak t
|
||||
} // expected-error {{expected statement}}
|
||||
switch(x) {
|
||||
default:
|
||||
#pragma weak t
|
||||
} // expected-error {{expected statement}}
|
||||
|
||||
label:
|
||||
#pragma weak t
|
||||
} // expected-error {{expected statement}}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue