]> granicus.if.org Git - clang/commitdiff
map previously ignored __attribute((malloc)) to noalias attribute of llvm function...
authorRyan Flynn <pizza@parseerror.com>
Sun, 9 Aug 2009 20:07:29 +0000 (20:07 +0000)
committerRyan Flynn <pizza@parseerror.com>
Sun, 9 Aug 2009 20:07:29 +0000 (20:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78541 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Attr.h
include/clang/Parse/AttributeList.h
lib/CodeGen/CGCall.cpp
lib/Frontend/PCHReaderDecl.cpp
lib/Frontend/PCHWriter.cpp
lib/Parse/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-malloc.c [new file with mode: 0644]

index 581f8af2638c8ee8933b673c2573feb90c7222dc..2f4fa228e5641ce278713d9bdee435d642021457 100644 (file)
@@ -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);
index 50ca88acbce9392c55985b78b86a6c6dedfac710..e699d170cffa2ef20c88a8a3db9c41a70153dc83 100644 (file)
@@ -69,6 +69,7 @@ public:
     AT_format,
     AT_format_arg,
     AT_gnu_inline,
+    AT_malloc,
     AT_mode,
     AT_nodebug,
     AT_noinline,
index 12d4d9ca25235ebf69f72a6e89cf60a9095c60d1..24d82747a4067e5491615c1e5889f228c4e1b447 100644 (file)
@@ -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)
index 95163af111140c3343812bf1c87460eb78a2e132..32a1e384cc7d7dd563ba2a92108fe64c76b8fca9 100644 (file)
@@ -480,6 +480,7 @@ Attr *PCHReader::ReadAttributes() {
       New = ::new (*Context) IBOutletAttr();
       break;
 
+    SIMPLE_ATTR(Malloc);
     SIMPLE_ATTR(NoReturn);
     SIMPLE_ATTR(NoThrow);
     SIMPLE_ATTR(Nodebug);
index 0e570a61abb9c726546e9440ff18d6ba351b3bdf..d9c6b1bb7d8b8b9838b752a7b4513f5e8157e05e 100644 (file)
@@ -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:
index 5ee668a31723c78213caf1977ea7b100b8b477e8..32ffba36dd6002c8a4375bcb904ee07a17e6d548 100644 (file)
@@ -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;
index 6df8120786101cb397d3d0f30e54554606754580..2f86fe1ffe702d79ab9612a0a1ea651632499054 100644 (file)
@@ -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 (file)
index 0000000..8603cc0
--- /dev/null
@@ -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
+