From: Chris Lattner Date: Wed, 11 Mar 2009 00:06:36 +0000 (+0000) Subject: checking for symbolic operands as well as % at end of string. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=eab8cfbf4b2e85b66cea6e0fea3b7f8fd2685722;p=clang checking for symbolic operands as well as % at end of string. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66614 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticASTKinds.def b/include/clang/Basic/DiagnosticASTKinds.def index e18278ae8b..0ec49d8508 100644 --- a/include/clang/Basic/DiagnosticASTKinds.def +++ b/include/clang/Basic/DiagnosticASTKinds.def @@ -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 diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 8062884d7e..4156af6ef9 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -229,8 +229,11 @@ unsigned AsmStmt::AnalyzeAsmString(llvm::SmallVectorImpl&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&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; } diff --git a/test/Sema/asm.c b/test/Sema/asm.c index d429b94f40..32f32c6691 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -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}} }