From: Abramo Bagnara Date: Tue, 11 Jan 2011 15:16:52 +0000 (+0000) Subject: Added warning about invalid register specification for local variables. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2b57aefea762f526405937b3c01901f8e1047edb;p=clang Added warning about invalid register specification for local variables. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123236 91177308-0d34-0410-b5e6-96231b3b80d8 --- 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(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}} }