aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Flynn <pizza@parseerror.com>2009-08-09 20:07:29 +0000
committerRyan Flynn <pizza@parseerror.com>2009-08-09 20:07:29 +0000
commit76168e289ca4b307259e3bc9b3353f03b05bb6b9 (patch)
tree0200fde8022319a4ea4d63582a4a64d9c5cd6322
parent237957c45774713f81fbd5394b3db4317fef0938 (diff)
map previously ignored __attribute((malloc)) to noalias attribute of llvm function's return
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78541 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Attr.h2
-rw-r--r--include/clang/Parse/AttributeList.h1
-rw-r--r--lib/CodeGen/CGCall.cpp2
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp1
-rw-r--r--lib/Frontend/PCHWriter.cpp1
-rw-r--r--lib/Parse/AttributeList.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp17
-rw-r--r--test/Sema/attr-malloc.c16
8 files changed, 41 insertions, 1 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 581f8af263..2f4fa228e5 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -59,6 +59,7 @@ public:
FormatArg,
GNUInline,
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
+ Malloc,
NoReturn,
NoThrow,
Nodebug,
@@ -288,6 +289,7 @@ public:
static bool classof(const IBOutletAttr *A) { return true; }
};
+DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 50ca88acbc..e699d170cf 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -69,6 +69,7 @@ public:
AT_format,
AT_format_arg,
AT_gnu_inline,
+ AT_malloc,
AT_mode,
AT_nodebug,
AT_noinline,
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 12d4d9ca25..24d82747a4 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -385,6 +385,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
FuncAttrs |= llvm::Attribute::ReadNone;
else if (TargetDecl->hasAttr<PureAttr>())
FuncAttrs |= llvm::Attribute::ReadOnly;
+ if (TargetDecl->hasAttr<MallocAttr>())
+ RetAttrs |= llvm::Attribute::NoAlias;
}
if (CompileOpts.DisableRedZone)
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 95163af111..32a1e384cc 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -480,6 +480,7 @@ Attr *PCHReader::ReadAttributes() {
New = ::new (*Context) IBOutletAttr();
break;
+ SIMPLE_ATTR(Malloc);
SIMPLE_ATTR(NoReturn);
SIMPLE_ATTR(NoThrow);
SIMPLE_ATTR(Nodebug);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 0e570a61ab..d9c6b1bb7d 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1678,6 +1678,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::GNUInline:
case Attr::IBOutletKind:
+ case Attr::Malloc:
case Attr::NoReturn:
case Attr::NoThrow:
case Attr::Nodebug:
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index 5ee668a317..32ffba36dd 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -69,7 +69,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
break;
case 6:
if (!memcmp(Str, "packed", 6)) return AT_packed;
- if (!memcmp(Str, "malloc", 6)) return IgnoredAttribute; // FIXME: noalias.
+ if (!memcmp(Str, "malloc", 6)) return AT_malloc;
if (!memcmp(Str, "format", 6)) return AT_format;
if (!memcmp(Str, "unused", 6)) return AT_unused;
if (!memcmp(Str, "blocks", 6)) return AT_blocks;
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 6df8120786..2f86fe1ffe 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -424,6 +424,22 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
d->addAttr(::new (S.Context) AlwaysInlineAttr());
}
+static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+ // check the attribute arguments.
+ if (Attr.getNumArgs() != 0) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+ return;
+ }
+
+ if (!isFunctionOrMethod(d)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 0 /*function*/;
+ return;
+ }
+
+ d->addAttr(::new (S.Context) MallocAttr());
+}
+
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
// check the attribute arguments.
@@ -1759,6 +1775,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(D, Attr, S); break;
case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
+ case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
diff --git a/test/Sema/attr-malloc.c b/test/Sema/attr-malloc.c
new file mode 100644
index 0000000000..8603cc05a5
--- /dev/null
+++ b/test/Sema/attr-malloc.c
@@ -0,0 +1,16 @@
+// RUN: clang-cc -verify -fsyntax-only %s &&
+// RUN: clang-cc -emit-llvm -o %t %s &&
+
+#include <stdlib.h>
+
+int no_vars __attribute((malloc)); // expected-warning {{only applies to function types}}
+
+__attribute((malloc))
+void * xalloc(unsigned n) { return malloc(n); }
+// RUN: grep 'define noalias .* @xalloc(' %t &&
+
+#define __malloc_like __attribute((__malloc__))
+void * xalloc2(unsigned) __malloc_like;
+void * xalloc2(unsigned n) { return malloc(n); }
+// RUN: grep 'define noalias .* @xalloc2(' %t
+