From: Chris Lattner Date: Tue, 10 Mar 2009 23:51:40 +0000 (+0000) Subject: reject invalid escape characters in extended-asm strings with a nice diagnostic. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3182db1c8e456c4cd2180fac9d77d331b2c0621f;p=clang reject invalid escape characters in extended-asm strings with a nice diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66605 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticASTKinds.def b/include/clang/Basic/DiagnosticASTKinds.def index c57ee6538e..e18278ae8b 100644 --- a/include/clang/Basic/DiagnosticASTKinds.def +++ b/include/clang/Basic/DiagnosticASTKinds.def @@ -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") diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index 74e5b58e96..f822abb214 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -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, diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 6b583ee577..6fa4033088 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -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&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&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&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&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&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&Pieces, continue; } - assert(0 && "FIXME: Reject"); - return true; + DiagOffs = CurPtr-StrStart; + return diag::err_asm_invalid_escape; } } diff --git a/test/Sema/asm.c b/test/Sema/asm.c index 3acb58a015..d429b94f40 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -50,13 +50,16 @@ void test4(const volatile void *addr) } // -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}} +}