]> granicus.if.org Git - clang/commitdiff
fix PR3258 by rejecting invalid numeric operands.
authorChris Lattner <sabre@nondot.org>
Wed, 11 Mar 2009 00:23:13 +0000 (00:23 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 11 Mar 2009 00:23:13 +0000 (00:23 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66618 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
include/clang/Basic/DiagnosticASTKinds.def
lib/AST/Stmt.cpp
test/Sema/asm.c

index d87cee05661f6d362b2242d9d3b6954a1bd9c5de..e5fa30999259404d9ff53bb5d2c947da28d02c82 100644 (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; }  
index 0ec49d850869dee2ee22f639d785c7502eb73925..0b3ae7c942829bf84ffa806acd61a72302668ead 100644 (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")
\ 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
index 4156af6ef98686e65680c84629aa770f295d19e1..cc120a684c5fda27e50ffd2a559430117b97df91 100644 (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!");
-      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;
     }
index 32f32c669186b814da08c96cd91a920d421aafaf..6ed9c50d62764d6ead6dd139ae395d50851e4ab6 100644 (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.
 }