summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-11 00:23:13 +0000
committerChris Lattner <sabre@nondot.org>2009-03-11 00:23:13 +0000
commit14311925f2010316c1380cd391039d5098089590 (patch)
tree52da4650792dee2fb413a8979dfe780c8dbc3bb4
parentde75e92fbf0a5822891a3933e269102722230b5d (diff)
downloadbcm5719-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.h4
-rw-r--r--clang/include/clang/Basic/DiagnosticASTKinds.def4
-rw-r--r--clang/lib/AST/Stmt.cpp24
-rw-r--r--clang/test/Sema/asm.c6
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.
}
OpenPOWER on IntegriCloud