diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-11 00:23:13 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-11 00:23:13 +0000 |
commit | 14311925f2010316c1380cd391039d5098089590 (patch) | |
tree | 52da4650792dee2fb413a8979dfe780c8dbc3bb4 | |
parent | de75e92fbf0a5822891a3933e269102722230b5d (diff) | |
download | bcm5719-llvm-14311925f2010316c1380cd391039d5098089590.tar.gz bcm5719-llvm-14311925f2010316c1380cd391039d5098089590.zip |
fix PR3258 by rejecting invalid numeric operands.
llvm-svn: 66618
-rw-r--r-- | clang/include/clang/AST/Stmt.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticASTKinds.def | 4 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 24 | ||||
-rw-r--r-- | clang/test/Sema/asm.c | 6 |
4 files changed, 31 insertions, 7 deletions
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index d87cee05661..e5fa3099925 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -1011,6 +1011,10 @@ public: return getOutputConstraint(i)[0] == '+'; } + /// getNumPlusOperands - Return the number of output operands that have a "+" + /// constraint. + unsigned getNumPlusOperands() const; + //===--- Input operands ---===// unsigned getNumInputs() const { return NumInputs; } diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.def b/clang/include/clang/Basic/DiagnosticASTKinds.def index 0ec49d85086..0b3ae7c9428 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.def +++ b/clang/include/clang/Basic/DiagnosticASTKinds.def @@ -26,4 +26,6 @@ DIAG(err_asm_unknown_symbolic_operand_name, ERROR, DIAG(err_asm_unterminated_symbolic_operand_name, ERROR, "unterminated symbolic operand name in inline assembly string") DIAG(err_asm_empty_symbolic_operand_name, ERROR, - "empty symbolic operand name in inline assembly string")
\ No newline at end of file + "empty symbolic operand name in inline assembly string") +DIAG(err_asm_invalid_operand_number, ERROR, + "invalid operand number in inline asm string")
\ No newline at end of file diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 4156af6ef98..cc120a684c5 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -143,6 +143,17 @@ std::string AsmStmt::getOutputConstraint(unsigned i) const { Constraints[i]->getByteLength()); } +/// getNumPlusOperands - Return the number of output operands that have a "+" +/// constraint. +unsigned AsmStmt::getNumPlusOperands() const { + unsigned Res = 0; + for (unsigned i = 0, e = getNumOutputs(); i != e; ++i) + if (isOutputPlusConstraint(i)) + ++Res; + return Res; +} + + Expr *AsmStmt::getInputExpr(unsigned i) { return cast<Expr>(Exprs[i + NumOutputs]); @@ -266,12 +277,15 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces, char *End; unsigned long N = strtoul(CurPtr-1, &End, 10); assert(End != CurPtr-1 && "We know that EscapedChar is a digit!"); - CurPtr = End; - - // FIXME: This should be caught during Sema. - //unsigned NumOperands = S.getNumOutputs() + S.getNumInputs(); - //assert(N < NumOperands && "Operand number out of range!"); + unsigned NumOperands = + getNumOutputs() + getNumPlusOperands() + getNumInputs(); + if (N >= NumOperands) { + DiagOffs = CurPtr-StrStart-1; + return diag::err_asm_invalid_operand_number; + } + + CurPtr = End; Pieces.push_back(AsmStringPiece(N, Modifier)); continue; } diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c index 32f32c66918..6ed9c50d627 100644 --- a/clang/test/Sema/asm.c +++ b/clang/test/Sema/asm.c @@ -55,7 +55,7 @@ void test6(long i) { asm("nop" : : "er"(i)); } -void asm_string_tests() { +void asm_string_tests(int i) { asm("%!"); // simple asm string, %! is not an error. asm("%!" : ); // expected-error {{invalid % escape in inline assembly string}} asm("xyz %" : ); // expected-error {{invalid % escape in inline assembly string}} @@ -64,4 +64,8 @@ void asm_string_tests() { asm ("%[somename]" :: "i"(4)); // expected-error {{unknown symbolic operand name in inline assembly string}} asm ("%[somename" :: "i"(4)); // expected-error {{unterminated symbolic operand name in inline assembly string}} asm ("%[]" :: "i"(4)); // expected-error {{empty symbolic operand name in inline assembly string}} + + // PR3258 + asm("%9" :: "i"(4)); // expected-error {{invalid operand number in inline asm string}} + asm("%1" : "+r"(i)); // ok, referring to input. } |