aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/SemaDecl.cpp22
-rw-r--r--test/Sema/asm.c12
3 files changed, 31 insertions, 5 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5b5bf84b7b..8c3a57622b 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3029,6 +3029,8 @@ let CategoryName = "Inline Assembly Issue" in {
def err_asm_tying_incompatible_types : Error<
"unsupported inline asm: input with type %0 matching output with type %1">;
def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">;
+ def warn_asm_label_on_auto_decl : Warning<
+ "ignored asm label '%0' on automatic variable">;
def err_invalid_asm_cast_lvalue : Error<
"invalid use of a cast in a inline asm context requiring an l-value: "
"remove the cast or build with -fheinous-gnu-extensions">;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 28ae8d23c7..4d67ff22ac 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2997,10 +2997,24 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
llvm::StringRef Label = SE->getString();
- if (S->getFnParent() != 0 &&
- !Context.Target.isValidGCCRegisterName(Label))
- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
- NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
+ if (S->getFnParent() != 0) {
+ switch (SC) {
+ case SC_None:
+ case SC_Auto:
+ Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
+ break;
+ case SC_Register:
+ if (!Context.Target.isValidGCCRegisterName(Label))
+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
+ break;
+ case SC_Static:
+ case SC_Extern:
+ case SC_PrivateExtern:
+ break;
+ }
+ }
+
+ NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
Context, Label));
}
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index af6754a68b..7f0f396b9d 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -92,6 +92,16 @@ void test9(int i) {
asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}}
}
+register int g asm("dx"); // expected-error{{global register variables are not supported}}
+
void test10(void){
- register unsigned long long bar asm("foo"); // expected-error {{unknown register name 'foo' in asm}}
+ static int g asm ("g_asm") = 0;
+ extern int gg asm ("gg_asm");
+ __private_extern__ int ggg asm ("ggg_asm");
+
+ int a asm ("a_asm"); // expected-warning{{ignored asm label 'a_asm' on automatic variable}}
+ auto int aa asm ("aa_asm"); // expected-warning{{ignored asm label 'aa_asm' on automatic variable}}
+
+ register int r asm ("cx");
+ register int rr asm ("rr_asm"); // expected-error{{unknown register name 'rr_asm' in asm}}
}