Hi rnk,
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.
It is probably still possible to shoot oneself in the foot since other
arbitrary expressions are allowed there :/
http://reviews.llvm.org/D5640
Files:
lib/Sema/SemaStmtAsm.cpp
test/Sema/attr-naked.c
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -75,6 +75,27 @@
return false;
}
+static bool CheckNakedParmReference(Expr *E, Sema &S) {
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
+ if (Func->hasAttr<NakedAttr>()) {
+ 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))
+ if (CheckNakedParmReference(E, S))
+ return true;
+
+ return false;
+}
+
StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
bool IsVolatile, unsigned NumOutputs,
unsigned NumInputs, IdentifierInfo **Names,
@@ -117,6 +138,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 +185,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 +450,8 @@
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();
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}}
+ );
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits