forked from OSchip/llvm-project
reject invalid escape characters in extended-asm strings with a nice diagnostic.
llvm-svn: 66605
This commit is contained in:
parent
d580dc0a4b
commit
a41b847401
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue