r219272 - Disallow using function parameters in extended asm inputs or outputs in naked functions (PR21178)

Hans Wennborg hans at hanshq.net
Tue Oct 7 18:58:02 PDT 2014


Author: hans
Date: Tue Oct  7 20:58:02 2014
New Revision: 219272

URL: http://llvm.org/viewvc/llvm-project?rev=219272&view=rev
Log:
Disallow using function parameters in extended asm inputs or outputs in naked functions (PR21178)

Clang won't emit any prologues for such functions, so it would assert trying to
codegen the parameter references.

This patch makes Clang check the extended asm inputs and outputs for
references to function parameters.

Differential Revision: http://reviews.llvm.org/D5640

Modified:
    cfe/trunk/lib/Sema/SemaStmtAsm.cpp
    cfe/trunk/test/Sema/attr-naked.c

Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=219272&r1=219271&r2=219272&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Tue Oct  7 20:58:02 2014
@@ -75,6 +75,32 @@ static bool isOperandMentioned(unsigned
   return false;
 }
 
+static bool CheckNakedParmReference(Expr *E, Sema &S) {
+  FunctionDecl *Func = dyn_cast<FunctionDecl>(S.CurContext);
+  if (!Func)
+    return false;
+  if (!Func->hasAttr<NakedAttr>())
+    return false;
+
+  SmallVector<Expr*, 4> WorkList;
+  WorkList.push_back(E);
+  while (WorkList.size()) {
+    Expr *E = WorkList.pop_back_val();
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+      if (isa<ParmVarDecl>(DRE->getDecl())) {
+        S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref);
+        S.Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
+        return true;
+      }
+    }
+    for (Stmt *Child : E->children()) {
+      if (Expr *E = dyn_cast_or_null<Expr>(Child))
+        WorkList.push_back(E);
+    }
+  }
+  return false;
+}
+
 StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
                                  bool IsVolatile, unsigned NumOutputs,
                                  unsigned NumInputs, IdentifierInfo **Names,
@@ -117,6 +143,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL
                             diag::err_asm_invalid_lvalue_in_output)
                        << OutputExpr->getSourceRange());
 
+    // Referring to parameters is not allowed in naked functions.
+    if (CheckNakedParmReference(OutputExpr, *this))
+      return StmtError();
+
     if (RequireCompleteType(OutputExpr->getLocStart(), Exprs[i]->getType(),
                             diag::err_dereference_incomplete_type))
       return StmtError();
@@ -160,6 +190,10 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL
 
     Expr *InputExpr = Exprs[i];
 
+    // Referring to parameters is not allowed in naked functions.
+    if (CheckNakedParmReference(InputExpr, *this))
+      return StmtError();
+
     // Only allow void types for memory constraints.
     if (Info.allowsMemory() && !Info.allowsRegister()) {
       if (CheckAsmLValue(InputExpr, *this))
@@ -421,17 +455,8 @@ ExprResult Sema::LookupInlineAsmIdentifi
   if (!Result.isUsable()) return Result;
 
   // Referring to parameters is not allowed in naked functions.
-  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Result.get())) {
-    if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
-      if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
-        if (Func->hasAttr<NakedAttr>()) {
-          Diag(Id.getLocStart(), diag::err_asm_naked_parm_ref);
-          Diag(Func->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
-          return ExprError();
-        }
-      }
-    }
-  }
+  if (CheckNakedParmReference(Result.get(), *this))
+    return ExprError();
 
   QualType T = Result.get()->getType();
 

Modified: cfe/trunk/test/Sema/attr-naked.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-naked.c?rev=219272&r1=219271&r2=219272&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-naked.c (original)
+++ cfe/trunk/test/Sema/attr-naked.c Tue Oct  7 20:58:02 2014
@@ -32,3 +32,19 @@ __attribute__((naked)) void t7() {
   asm("movl $42, %eax");
   ;
 }
+
+extern int x, y;
+
+__attribute__((naked)) void t8(int z) { // expected-note{{attribute is here}}
+  __asm__ ("movl $42, %1"
+           : "=r"(x),
+             "=r"(z) // expected-error{{parameter references not allowed in naked functions}}
+           );
+}
+
+__attribute__((naked)) void t9(int z) { // expected-note{{attribute is here}}
+  __asm__ ("movl %eax, %1"
+           : : "r"(x),
+               "r"(z) // expected-error{{parameter references not allowed in naked functions}}
+           );
+}





More information about the cfe-commits mailing list