summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticASTKinds.def8
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.def3
-rw-r--r--clang/lib/AST/Stmt.cpp38
-rw-r--r--clang/test/Sema/asm.c11
4 files changed, 36 insertions, 24 deletions
diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.def b/clang/include/clang/Basic/DiagnosticASTKinds.def
index c57ee6538e9..e18278ae8bd 100644
--- a/clang/include/clang/Basic/DiagnosticASTKinds.def
+++ b/clang/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/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
index 74e5b58e96a..f822abb2143 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
+++ b/clang/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/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 6b583ee577a..6fa40330889 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/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<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;
}
}
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index 3acb58a015a..d429b94f401 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -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}}
+}
OpenPOWER on IntegriCloud