From 3f3358dc5aa5c4bb4378edd3ee8d2ecee1dea161 Mon Sep 17 00:00:00 2001 From: Weiming Zhao Date: Tue, 3 Feb 2015 22:35:58 +0000 Subject: [PATCH] Diagnose CXX 'this' pointer reference in funcs with naked attr Clang asserts for this pointer reference in asms of naked functions. This patch diagnoses if this pointer reference is used. Differential Revision: http://reviews.llvm.org/D7329 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228052 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaStmtAsm.cpp | 6 ++++++ test/Sema/attr-naked.cpp | 15 +++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 test/Sema/attr-naked.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1283bafd61..9bbdab4918 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -7211,6 +7211,8 @@ def err_filter_expression_integral : Error< def err_non_asm_stmt_in_naked_function : Error< "non-ASM statement in naked function is not supported">; +def err_asm_naked_this_ref : Error< + "'this' pointer references not allowed in naked functions">; def err_asm_naked_parm_ref : Error< "parameter references not allowed in naked functions">; diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 0d32581e8d..1beac366c5 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/TargetInfo.h" @@ -86,6 +87,11 @@ static bool CheckNakedParmReference(Expr *E, Sema &S) { WorkList.push_back(E); while (WorkList.size()) { Expr *E = WorkList.pop_back_val(); + if (isa(E)) { + S.Diag(E->getLocStart(), diag::err_asm_naked_this_ref); + S.Diag(Func->getAttr()->getLocation(), diag::note_attribute); + return true; + } if (DeclRefExpr *DRE = dyn_cast(E)) { if (isa(DRE->getDecl())) { S.Diag(DRE->getLocStart(), diag::err_asm_naked_parm_ref); diff --git a/test/Sema/attr-naked.cpp b/test/Sema/attr-naked.cpp new file mode 100644 index 0000000000..eaa8e223b8 --- /dev/null +++ b/test/Sema/attr-naked.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -verify -fsyntax-only -triple arm-none-linux +class Foo { + void bar(); + static void bar2(); + unsigned v; + static unsigned s; +}; + +void __attribute__((naked)) Foo::bar() { // expected-note{{attribute is here}} + asm("mov r2, %0" : : "r"(v)); // expected-error{{'this' pointer references not allowed in naked functions}} +} + +void __attribute__((naked)) Foo::bar2() { + asm("mov r2, %0" : : "r"(s)); // static member reference is OK +} -- 2.50.1