]> granicus.if.org Git - clang/commitdiff
checking for symbolic operands as well as % at end of string.
authorChris Lattner <sabre@nondot.org>
Wed, 11 Mar 2009 00:06:36 +0000 (00:06 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 11 Mar 2009 00:06:36 +0000 (00:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66614 91177308-0d34-0410-b5e6-96231b3b80d8

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

index e18278ae8bdfb9b8e6ed8adead5e7b021bc8442d..0ec49d850869dee2ee22f639d785c7502eb73925 100644 (file)
@@ -20,3 +20,10 @@ DIAG(note_expr_divide_by_zero, NOTE,
 // inline asm related.
 DIAG(err_asm_invalid_escape, ERROR,
     "invalid %% escape in inline assembly string")
+DIAG(err_asm_unknown_symbolic_operand_name, ERROR,
+     "unknown symbolic operand name in inline assembly string")
+     
+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
index 8062884d7ea4f357afa4dffed620ec64ecbeca37..4156af6ef98686e65680c84629aa770f295d19e1 100644 (file)
@@ -229,8 +229,11 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     }
     
     // Escaped "%" character in asm string.
-    // FIXME: This should be caught during Sema.
-    assert(CurPtr != StrEnd && "Trailing '%' in asm string.");
+    if (CurPtr == StrEnd) {
+      // % at end of string is invalid (no escape).
+      DiagOffs = CurPtr-StrStart-1;
+      return diag::err_asm_invalid_escape;
+    }
     
     char EscapedChar = *CurPtr++;
     if (EscapedChar == '%') {  // %% -> %
@@ -275,16 +278,26 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     
     // Handle %[foo], a symbolic operand reference.
     if (EscapedChar == '[') {
+      DiagOffs = CurPtr-StrStart-1;
+      
+      // Find the ']'.
       const char *NameEnd = (const char*)memchr(CurPtr, ']', StrEnd-CurPtr);
-      // FIXME: Should be caught by sema.
-      // FIXME: Does sema catch multiple operands with the same name?
-      assert(NameEnd != 0 && "Could not parse symbolic name");
+      if (NameEnd == 0)
+        return diag::err_asm_unterminated_symbolic_operand_name;
+      if (NameEnd == CurPtr)
+        return diag::err_asm_empty_symbolic_operand_name;
+      
       std::string SymbolicName(CurPtr, NameEnd);
-      CurPtr = NameEnd+1;
       
       int N = getNamedOperand(SymbolicName);
-      assert(N != -1 && "FIXME: Catch in Sema.");
+      if (N == -1) {
+        // Verify that an operand with that name exists.
+        DiagOffs = CurPtr-StrStart;
+        return diag::err_asm_unknown_symbolic_operand_name;
+      }
       Pieces.push_back(AsmStringPiece(N, Modifier));
+      
+      CurPtr = NameEnd+1;
       continue;
     }
     
index d429b94f40195e0921c62955258f12ecb67b63cf..32f32c669186b814da08c96cd91a920d421aafaf 100644 (file)
@@ -1,8 +1,6 @@
 // RUN: clang %s -arch=i386 -verify -fsyntax-only
 
-void
-f()
-{
+void f() {
   int i;
 
   asm ("foo\n" : : "a" (i + 2));
@@ -17,9 +15,7 @@ f()
   asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
 }
 
-void
-clobbers()
-{
+void clobbers() {
   asm ("nop" : : : "ax", "#ax", "%ax");
   asm ("nop" : : : "eax", "rax", "ah", "al");
   asm ("nop" : : : "0", "%0", "#0");
@@ -59,7 +55,13 @@ void test6(long i) {
   asm("nop" : : "er"(i));
 }
 
-void test7() {
+void asm_string_tests() {
   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}}
+
+  asm ("%[somename]" :: [somename] "i"(4)); // ok
+  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}}
 }