Don't allow non-ASM statements in naked functions
Naked functions don't have prologues or epilogues, so doing
codegen for anything other than inline assembly would be completely
hit or miss.
Differential Revision: http://reviews.llvm.org/D5183
llvm-svn: 217199
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e26374c..cda5aa0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6991,6 +6991,9 @@
def err_filter_expression_integral : Error<
"filter expression type should be an integral value not %0">;
+def err_non_asm_stmt_in_naked_function : Error<
+ "non-ASM statement in naked function is not supported">;
+
// OpenCL warnings and errors.
def err_invalid_astype_of_different_size : Error<
"invalid reinterpretation: sizes of %0 and %1 must match">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9f49e68..f5ba0ea 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10376,6 +10376,17 @@
!CheckConstexprFunctionBody(FD, Body)))
FD->setInvalidDecl();
+ if (FD && FD->hasAttr<NakedAttr>()) {
+ for (const Stmt *S : Body->children()) {
+ if (!isa<AsmStmt>(S)) {
+ Diag(S->getLocStart(), diag::err_non_asm_stmt_in_naked_function);
+ Diag(FD->getAttr<NakedAttr>()->getLocation(), diag::note_attribute);
+ FD->setInvalidDecl();
+ break;
+ }
+ }
+ }
+
assert(ExprCleanupObjects.empty() && "Leftover temporaries in function");
assert(!ExprNeedsCleanups && "Unaccounted cleanups in function");
assert(MaybeODRUseExprs.empty() &&
diff --git a/clang/test/Sema/attr-naked.c b/clang/test/Sema/attr-naked.c
index 55c6b32..c1ad52c 100644
--- a/clang/test/Sema/attr-naked.c
+++ b/clang/test/Sema/attr-naked.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -triple i686-pc-linux
int a __attribute__((naked)); // expected-warning {{'naked' attribute only applies to functions}}
@@ -10,3 +10,11 @@
void t2() __attribute__((naked(2))); // expected-error {{'naked' attribute takes no arguments}}
+__attribute__((naked)) int t3() { // expected-note{{attribute is here}}
+ return 42; // expected-error{{non-ASM statement in naked function is not supported}}
+}
+
+__attribute__((naked)) int t4() {
+ asm("movl $42, %eax");
+ asm("retl");
+}