Allow register variables in naked functions.
authorNikola Smiljanic <popizdeh@gmail.com>
Tue, 13 Sep 2016 07:02:02 +0000 (07:02 +0000)
committerNikola Smiljanic <popizdeh@gmail.com>
Tue, 13 Sep 2016 07:02:02 +0000 (07:02 +0000)
llvm-svn: 281298

clang/lib/Sema/SemaDecl.cpp
clang/test/Sema/attr-naked.c

index 773d00b..0c2540b 100644 (file)
@@ -11818,6 +11818,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
 
     if (FD && FD->hasAttr<NakedAttr>()) {
       for (const Stmt *S : Body->children()) {
+        // Allow local register variables without initializer as they don't
+        // require prologue.
+        bool RegisterVariables = false;
+        if (auto *DS = dyn_cast<DeclStmt>(S)) {
+          for (const auto *Decl : DS->decls()) {
+            if (const auto *Var = dyn_cast<VarDecl>(Decl)) {
+              RegisterVariables =
+                  Var->hasAttr<AsmLabelAttr>() && !Var->hasInit();
+              if (!RegisterVariables)
+                break;
+            }
+          }
+        }
+        if (RegisterVariables)
+          continue;
         if (!isa<AsmStmt>(S) && !isa<NullStmt>(S)) {
           Diag(S->getLocStart(), diag::err_non_asm_stmt_in_naked_function);
           Diag(FD->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
index 6b1344a..c9a3f1d 100644 (file)
@@ -48,3 +48,21 @@ __attribute__((naked)) void t9(int z) { // expected-note{{attribute is here}}
                "r"(z) // expected-error{{parameter references not allowed in naked functions}}
            );
 }
+
+__attribute__((naked)) void t10() {  // expected-note{{attribute is here}}
+  int a; // expected-error{{non-ASM statement in naked function is not supported}}
+}
+
+__attribute__((naked)) void t11() {  // expected-note{{attribute is here}}
+  register int a asm("eax") = x; // expected-error{{non-ASM statement in naked function is not supported}}
+}
+
+__attribute__((naked)) void t12() {  // expected-note{{attribute is here}}
+  register int a asm("eax"), b asm("ebx") = x; // expected-error{{non-ASM statement in naked function is not supported}}
+}
+
+__attribute__((naked)) void t13() {
+  register int a asm("eax");
+  register int b asm("ebx"), c asm("ecx");
+}
+