fix PR3258 by rejecting invalid numeric operands.

llvm-svn: 66618
This commit is contained in:
Chris Lattner 2009-03-11 00:23:13 +00:00
parent de75e92fbf
commit 14311925f2
4 changed files with 31 additions and 7 deletions

View File

@ -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; }

View File

@ -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")
"empty symbolic operand name in inline assembly string")
DIAG(err_asm_invalid_operand_number, ERROR,
"invalid operand number in inline asm string")

View File

@ -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!");
unsigned NumOperands =
getNumOutputs() + getNumPlusOperands() + getNumInputs();
if (N >= NumOperands) {
DiagOffs = CurPtr-StrStart-1;
return diag::err_asm_invalid_operand_number;
}
CurPtr = End;
// FIXME: This should be caught during Sema.
//unsigned NumOperands = S.getNumOutputs() + S.getNumInputs();
//assert(N < NumOperands && "Operand number out of range!");
Pieces.push_back(AsmStringPiece(N, Modifier));
continue;
}

View File

@ -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.
}