diff options
author | Anders Carlsson <andersca@mac.com> | 2008-02-09 19:57:29 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-02-09 19:57:29 +0000 |
commit | 2e64d1a50f87610e458bd967a0d3ab56e90f1be8 (patch) | |
tree | b2eed432b814f367cc0c6db3a63ecb5b1b10586d | |
parent | 43a2ed86115b0f699e62cae4723cd57e189832da (diff) | |
download | bcm5719-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.cpp | 25 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 2 | ||||
-rw-r--r-- | clang/test/Parser/asm.c | 5 |
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'}} +} |