Index: lib/Sema/SemaStmtAsm.cpp =================================================================== --- lib/Sema/SemaStmtAsm.cpp +++ lib/Sema/SemaStmtAsm.cpp @@ -75,6 +75,32 @@ return false; } +static bool CheckNakedParmReference(Expr *E, Sema &S) { + FunctionDecl *Func = dyn_cast(S.CurContext); + if (!Func) + return false; + if (!Func->hasAttr()) + return false; + + SmallVector WorkList; + WorkList.push_back(E); + while (WorkList.size()) { + Expr *E = WorkList.pop_back_val(); + if (DeclRefExpr *DRE = dyn_cast(E)) { + if (isa(DRE->getDecl())) { + S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref); + S.Diag(Func->getAttr()->getLocation(), diag::note_attribute); + return true; + } + } + for (Stmt *Child : E->children()) { + if (Expr *E = dyn_cast_or_null(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 @@ 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 @@ 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 @@ if (!Result.isUsable()) return Result; // Referring to parameters is not allowed in naked functions. - if (DeclRefExpr *DRE = dyn_cast(Result.get())) { - if (ParmVarDecl *Parm = dyn_cast(DRE->getDecl())) { - if (FunctionDecl *Func = dyn_cast(Parm->getDeclContext())) { - if (Func->hasAttr()) { - Diag(Id.getLocStart(), diag::err_asm_naked_parm_ref); - Diag(Func->getAttr()->getLocation(), diag::note_attribute); - return ExprError(); - } - } - } - } + if (CheckNakedParmReference(Result.get(), *this)) + return ExprError(); QualType T = Result.get()->getType(); Index: test/Sema/attr-naked.c =================================================================== --- test/Sema/attr-naked.c +++ test/Sema/attr-naked.c @@ -32,3 +32,19 @@ 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}} + ); +}