summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-02-09 19:57:29 +0000
committerAnders Carlsson <andersca@mac.com>2008-02-09 19:57:29 +0000
commit2e64d1a50f87610e458bd967a0d3ab56e90f1be8 (patch)
treeb2eed432b814f367cc0c6db3a63ecb5b1b10586d
parent43a2ed86115b0f699e62cae4723cd57e189832da (diff)
downloadbcm5719-llvm-2e64d1a50f87610e458bd967a0d3ab56e90f1be8.tar.gz
bcm5719-llvm-2e64d1a50f87610e458bd967a0d3ab56e90f1be8.zip
Behave correctly if a constraint expression is invalid.
llvm-svn: 46910
-rw-r--r--clang/Parse/ParseStmt.cpp25
-rw-r--r--clang/include/clang/Parse/Parser.h2
-rw-r--r--clang/test/Parser/asm.c5
3 files changed, 21 insertions, 11 deletions
diff --git a/clang/Parse/ParseStmt.cpp b/clang/Parse/ParseStmt.cpp
index f8ae4a05585..db91f0dec7e 100644
--- a/clang/Parse/ParseStmt.cpp
+++ b/clang/Parse/ParseStmt.cpp
@@ -995,12 +995,15 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
RParenLoc = ConsumeParen();
} else {
// Parse Outputs, if present.
- ParseAsmOperandsOpt(Names, Constraints, Exprs);
+ if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
+ return true;
NumOutputs = Names.size();
// Parse Inputs, if present.
- ParseAsmOperandsOpt(Names, Constraints, Exprs);
+ if (ParseAsmOperandsOpt(Names, Constraints, Exprs))
+ return true;
+
assert(Names.size() == Constraints.size() &&
Constraints.size() == Exprs.size()
&& "Input operand size mismatch!");
@@ -1048,16 +1051,16 @@ Parser::StmtResult Parser::ParseAsmStatement(bool &msAsm) {
/// asm-string-literal '(' expression ')'
/// '[' identifier ']' asm-string-literal '(' expression ')'
///
-void Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
+bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
llvm::SmallVectorImpl<ExprTy*> &Constraints,
llvm::SmallVectorImpl<ExprTy*> &Exprs) {
// Only do anything if this operand is present.
- if (Tok.isNot(tok::colon)) return;
+ if (Tok.isNot(tok::colon)) return false;
ConsumeToken();
// 'asm-operands' isn't present?
if (!isTokenStringLiteral() && Tok.isNot(tok::l_square))
- return;
+ return false;
while (1) {
// Read the [id] if present.
@@ -1067,7 +1070,7 @@ void Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_ident);
SkipUntil(tok::r_paren);
- return;
+ return true;
}
IdentifierInfo *II = Tok.getIdentifierInfo();
@@ -1081,27 +1084,29 @@ void Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
ExprResult Constraint = ParseAsmStringLiteral();
if (Constraint.isInvalid) {
SkipUntil(tok::r_paren);
- return;
+ return true;
}
Constraints.push_back(Constraint.Val);
if (Tok.isNot(tok::l_paren)) {
Diag(Tok, diag::err_expected_lparen_after, "asm operand");
SkipUntil(tok::r_paren);
- return;
+ return true;
}
// Read the parenthesized expression.
ExprResult Res = ParseSimpleParenExpression();
if (Res.isInvalid) {
SkipUntil(tok::r_paren);
- return;
+ return true;
}
Exprs.push_back(Res.Val);
// Eat the comma and continue parsing if it exists.
- if (Tok.isNot(tok::comma)) return;
+ if (Tok.isNot(tok::comma)) return false;
ConsumeToken();
}
+
+ return true;
}
Parser::DeclTy *Parser::ParseFunctionStatementBody(DeclTy *Decl,
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 1987e964ecf..5a9eae03a59 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -410,7 +410,7 @@ private:
StmtResult ParseObjCTryStmt(SourceLocation atLoc, bool &processAtKeyword);
StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
- void ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
+ bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
llvm::SmallVectorImpl<ExprTy*> &Constraints,
llvm::SmallVectorImpl<ExprTy*> &Exprs);
diff --git a/clang/test/Parser/asm.c b/clang/test/Parser/asm.c
index a09b545a8e0..6a19acaaed6 100644
--- a/clang/test/Parser/asm.c
+++ b/clang/test/Parser/asm.c
@@ -3,3 +3,8 @@
void f1() {
asm ("ret" : : :); // expected-error {{expected string literal}}
}
+
+void f2() {
+ asm("foo" : "=r" (a)); // expected-error {{use of undeclared identifier 'a'}}
+ asm("foo" : : "r" (b)); // expected-error {{use of undeclared identifier 'b'}}
+}
OpenPOWER on IntegriCloud