зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
237957c457
Коммит
76168e289c
|
@ -59,6 +59,7 @@ public:
|
||||||
FormatArg,
|
FormatArg,
|
||||||
GNUInline,
|
GNUInline,
|
||||||
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
|
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
|
||||||
|
Malloc,
|
||||||
NoReturn,
|
NoReturn,
|
||||||
NoThrow,
|
NoThrow,
|
||||||
Nodebug,
|
Nodebug,
|
||||||
|
@ -288,6 +289,7 @@ public:
|
||||||
static bool classof(const IBOutletAttr *A) { return true; }
|
static bool classof(const IBOutletAttr *A) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
DEF_SIMPLE_ATTR(Malloc);
|
||||||
DEF_SIMPLE_ATTR(NoReturn);
|
DEF_SIMPLE_ATTR(NoReturn);
|
||||||
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
|
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
|
||||||
DEF_SIMPLE_ATTR(Deprecated);
|
DEF_SIMPLE_ATTR(Deprecated);
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
AT_format,
|
AT_format,
|
||||||
AT_format_arg,
|
AT_format_arg,
|
||||||
AT_gnu_inline,
|
AT_gnu_inline,
|
||||||
|
AT_malloc,
|
||||||
AT_mode,
|
AT_mode,
|
||||||
AT_nodebug,
|
AT_nodebug,
|
||||||
AT_noinline,
|
AT_noinline,
|
||||||
|
|
|
@ -385,6 +385,8 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
||||||
FuncAttrs |= llvm::Attribute::ReadNone;
|
FuncAttrs |= llvm::Attribute::ReadNone;
|
||||||
else if (TargetDecl->hasAttr<PureAttr>())
|
else if (TargetDecl->hasAttr<PureAttr>())
|
||||||
FuncAttrs |= llvm::Attribute::ReadOnly;
|
FuncAttrs |= llvm::Attribute::ReadOnly;
|
||||||
|
if (TargetDecl->hasAttr<MallocAttr>())
|
||||||
|
RetAttrs |= llvm::Attribute::NoAlias;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CompileOpts.DisableRedZone)
|
if (CompileOpts.DisableRedZone)
|
||||||
|
|
|
@ -480,6 +480,7 @@ Attr *PCHReader::ReadAttributes() {
|
||||||
New = ::new (*Context) IBOutletAttr();
|
New = ::new (*Context) IBOutletAttr();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
SIMPLE_ATTR(Malloc);
|
||||||
SIMPLE_ATTR(NoReturn);
|
SIMPLE_ATTR(NoReturn);
|
||||||
SIMPLE_ATTR(NoThrow);
|
SIMPLE_ATTR(NoThrow);
|
||||||
SIMPLE_ATTR(Nodebug);
|
SIMPLE_ATTR(Nodebug);
|
||||||
|
|
|
@ -1678,6 +1678,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
||||||
|
|
||||||
case Attr::GNUInline:
|
case Attr::GNUInline:
|
||||||
case Attr::IBOutletKind:
|
case Attr::IBOutletKind:
|
||||||
|
case Attr::Malloc:
|
||||||
case Attr::NoReturn:
|
case Attr::NoReturn:
|
||||||
case Attr::NoThrow:
|
case Attr::NoThrow:
|
||||||
case Attr::Nodebug:
|
case Attr::Nodebug:
|
||||||
|
|
|
@ -69,7 +69,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if (!memcmp(Str, "packed", 6)) return AT_packed;
|
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, "format", 6)) return AT_format;
|
||||||
if (!memcmp(Str, "unused", 6)) return AT_unused;
|
if (!memcmp(Str, "unused", 6)) return AT_unused;
|
||||||
if (!memcmp(Str, "blocks", 6)) return AT_blocks;
|
if (!memcmp(Str, "blocks", 6)) return AT_blocks;
|
||||||
|
|
|
@ -424,6 +424,22 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
|
||||||
d->addAttr(::new (S.Context) AlwaysInlineAttr());
|
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,
|
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
|
||||||
Sema &S) {
|
Sema &S) {
|
||||||
// check the attribute arguments.
|
// 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_format_arg: HandleFormatArgAttr (D, Attr, S); break;
|
||||||
case AttributeList::AT_gnu_inline: HandleGNUInlineAttr(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_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_nonnull: HandleNonNullAttr (D, Attr, S); break;
|
||||||
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
||||||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче