warn, as gcc does, if __attribute__((malloc)) applied to function returning non-pointer type
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78542 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 39bbe4e..cc44738 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -605,6 +605,8 @@
"'%0' attribute invalid on this declaration, requires typedef or value">;
def warn_attribute_nonnull_no_pointers : Warning<
"'nonnull' attribute applied to function with no pointer arguments">;
+def warn_attribute_malloc_pointer_only : Warning<
+ "'malloc' attribute only applies to functions returning pointer type">;
def warn_transparent_union_nonpointer : Warning<
"'transparent_union' attribute support incomplete; only supported for "
"pointer unions">;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 2f86fe1..9d1b084 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -437,6 +437,13 @@
return;
}
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+ if (!FD->getResultType()->isPointerType()) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
+ return;
+ }
+ }
+
d->addAttr(::new (S.Context) MallocAttr());
}
diff --git a/test/Sema/attr-malloc.c b/test/Sema/attr-malloc.c
index 8603cc0..5b59bd5 100644
--- a/test/Sema/attr-malloc.c
+++ b/test/Sema/attr-malloc.c
@@ -5,6 +5,12 @@
int no_vars __attribute((malloc)); // expected-warning {{only applies to function types}}
+void returns_void (void) __attribute((malloc)); // expected-warning {{functions returning pointer type}}
+int returns_int (void) __attribute((malloc)); // expected-warning {{functions returning pointer type}}
+int * returns_intptr(void) __attribute((malloc));
+typedef int * iptr;
+iptr returns_iptr (void) __attribute((malloc));
+
__attribute((malloc))
void * xalloc(unsigned n) { return malloc(n); }
// RUN: grep 'define noalias .* @xalloc(' %t &&