summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-10-08 01:58:02 +0000
committerHans Wennborg <hans@hanshq.net>2014-10-08 01:58:02 +0000
commite9d240af44d3aa49c4b355afae920f0619480ff4 (patch)
tree919decf7bd31f19dd550ca36a7fe22a5a274b7b9 /clang/lib
parent896044822e2b10ea83af2b40db81b5924398e768 (diff)
downloadbcm5719-llvm-e9d240af44d3aa49c4b355afae920f0619480ff4.tar.gz
bcm5719-llvm-e9d240af44d3aa49c4b355afae920f0619480ff4.zip
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 llvm-svn: 219272
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp47
1 files changed, 36 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index dc50e87b589..7f79a05b46d 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -75,6 +75,32 @@ static bool isOperandMentioned(unsigned OpNo,
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(SourceLocation AsmLoc, bool IsSimple,
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(SourceLocation AsmLoc, bool IsSimple,
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::LookupInlineAsmIdentifier(CXXScopeSpec &SS,
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();
OpenPOWER on IntegriCloud