forked from OSchip/llvm-project
fix PR3258 by rejecting invalid numeric operands.
llvm-svn: 66618
This commit is contained in:
parent
de75e92fbf
commit
14311925f2
|
@ -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; }
|
||||
|
|
|
@ -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")
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue