]> granicus.if.org Git - clang/commitdiff
reject invalid escape characters in extended-asm strings with a nice diagnostic.
authorChris Lattner <sabre@nondot.org>
Tue, 10 Mar 2009 23:51:40 +0000 (23:51 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 10 Mar 2009 23:51:40 +0000 (23:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66605 91177308-0d34-0410-b5e6-96231b3b80d8

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

index c57ee6538e97fd878125fbbb7da238245331506a..e18278ae8bdfb9b8e6ed8adead5e7b021bc8442d 100644 (file)
@@ -12,7 +12,11 @@ __ASTSTART      = DIAG_START_AST,
 #undef ASTSTART
 #endif
 
-DIAG(note_comma_in_ice, NOTE,
-     "C does not permit evaluated commas in an integer constant expression")
+//DIAG(note_comma_in_ice, NOTE,
+//     "C does not permit evaluated commas in an integer constant expression")
 DIAG(note_expr_divide_by_zero, NOTE,
     "division by zero")
+
+// inline asm related.
+DIAG(err_asm_invalid_escape, ERROR,
+    "invalid %% escape in inline assembly string")
index 74e5b58e96ae04db7c2f88447cd8607b81b0bf61..f822abb21439fd343ba1913008cfcd05b7cf162c 100644 (file)
@@ -1179,6 +1179,8 @@ DIAG(ext_typecheck_expression_not_constant_but_accepted, EXTENSION,
      "expression is not a constant, but is accepted as one by GNU extensions")
 DIAG(warn_unused_expr, WARNING,
      "expression result unused")
+     
+// inline asm.
 DIAG(err_asm_wide_character, ERROR,
     "wide string is invalid in 'asm'")
 DIAG(err_asm_invalid_lvalue_in_output, ERROR,
@@ -1193,6 +1195,7 @@ DIAG(err_asm_invalid_type_in_input, ERROR,
      "invalid type %0 in asm input for constraint '%1'")
 DIAG(err_asm_unknown_register_name, ERROR,
     "unknown register name '%0' in asm")
+    
 DIAG(err_invalid_conversion_between_vectors, ERROR,
     "invalid conversion between vector type %0 and %1 of different size")
 DIAG(err_invalid_conversion_between_vector_and_integer, ERROR,
index 6b583ee577a44439261bd4d13bb21f617fdb1509..6fa4033088958f0f081a3dedc21fbafc9d517bc9 100644 (file)
@@ -16,6 +16,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
 using namespace clang;
 
 static struct StmtClassNameTable {
@@ -186,23 +187,24 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
                                    ASTContext &C, unsigned &DiagOffs) const {
   const char *StrStart = getAsmString()->getStrData();
   const char *StrEnd = StrStart + getAsmString()->getByteLength();
+  const char *CurPtr = StrStart;
   
   // "Simple" inline asms have no constraints or operands, just convert the asm
   // string to escape $'s.
   if (isSimple()) {
     std::string Result;
-    for (; StrStart != StrEnd; ++StrStart) {
-      switch (*StrStart) {
+    for (; CurPtr != StrEnd; ++CurPtr) {
+      switch (*CurPtr) {
       case '$':
         Result += "$$";
         break;
       default:
-        Result += *StrStart;
+        Result += *CurPtr;
         break;
       }
     }
     Pieces.push_back(AsmStringPiece(Result));
-    return false;
+    return 0;
   }
 
   // CurStringPiece - The current string that we are building up as we scan the
@@ -211,13 +213,13 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
   
   while (1) {
     // Done with the string?
-    if (StrStart == StrEnd) {
+    if (CurPtr == StrEnd) {
       if (!CurStringPiece.empty())
         Pieces.push_back(AsmStringPiece(CurStringPiece));
-      return false;
+      return 0;
     }
     
-    char CurChar = *StrStart++;
+    char CurChar = *CurPtr++;
     if (CurChar == '$') {
       CurStringPiece += "$$";
       continue;
@@ -228,9 +230,9 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     
     // Escaped "%" character in asm string.
     // FIXME: This should be caught during Sema.
-    assert(StrStart != StrEnd && "Trailing '%' in asm string.");
+    assert(CurPtr != StrEnd && "Trailing '%' in asm string.");
     
-    char EscapedChar = *StrStart++;
+    char EscapedChar = *CurPtr++;
     if (EscapedChar == '%') {  // %% -> %
       // Escaped percentage sign.
       CurStringPiece += '%';
@@ -253,15 +255,15 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     char Modifier = '\0';
     if (isalpha(EscapedChar)) {
       Modifier = EscapedChar;
-      EscapedChar = *StrStart++;
+      EscapedChar = *CurPtr++;
     }
     
     if (isdigit(EscapedChar)) {
       // %n - Assembler operand n
       char *End;
-      unsigned long N = strtoul(StrStart-1, &End, 10);
-      assert(End != StrStart-1 && "We know that EscapedChar is a digit!");
-      StrStart = 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();
@@ -273,12 +275,12 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
     
     // Handle %[foo], a symbolic operand reference.
     if (EscapedChar == '[') {
-      const char *NameEnd = (const char*)memchr(StrStart, ']', StrEnd-StrStart);
+      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");
-      std::string SymbolicName(StrStart, NameEnd);
-      StrStart = NameEnd+1;
+      std::string SymbolicName(CurPtr, NameEnd);
+      CurPtr = NameEnd+1;
       
       int N = getNamedOperand(SymbolicName);
       assert(N != -1 && "FIXME: Catch in Sema.");
@@ -286,8 +288,8 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl<AsmStringPiece>&Pieces,
       continue;
     }
     
-    assert(0 && "FIXME: Reject");
-    return true;
+    DiagOffs = CurPtr-StrStart;
+    return diag::err_asm_invalid_escape;
   }
 }
 
index 3acb58a015a24f0be56dcfb06dc3bea9bd396f58..d429b94f40195e0921c62955258f12ecb67b63cf 100644 (file)
@@ -50,13 +50,16 @@ void test4(const volatile void *addr)
 }
 
 // <rdar://problem/6512595>
-void test5()
-{
+void test5() {
   asm("nop" : : "X" (8)); 
 }
 
 // PR3385
-void test6(long i)
-{
+void test6(long i) {
   asm("nop" : : "er"(i));
 }
+
+void test7() {
+  asm("%!");   // simple asm string, %! is not an error.   
+  asm("%!" : );   // expected-error {{invalid % escape in inline assembly string}}
+}