diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-07-20 22:51:52 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-07-20 22:51:52 +0000 |
commit | 1bf0f8ede6f8f2b01ae1bccb1cd7519b19465119 (patch) | |
tree | 929b8c0863e1444e32ef18f1e91fc92626fa707f | |
parent | e4d22d59d1db39262790b6afd3521a65be2d7288 (diff) | |
download | bcm5719-llvm-1bf0f8ede6f8f2b01ae1bccb1cd7519b19465119.tar.gz bcm5719-llvm-1bf0f8ede6f8f2b01ae1bccb1cd7519b19465119.zip |
[MS Compat] Add support for __declspec(noalias)
The attribute '__declspec(noalias)' communicates that the function only
accesses memory pointed to by its pointer-typed arguments.
llvm-svn: 242728
-rw-r--r-- | clang/include/clang/Basic/Attr.td | 6 | ||||
-rw-r--r-- | clang/include/clang/Basic/AttrDocs.td | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGen/ms-declspecs.c | 5 | ||||
-rw-r--r-- | clang/test/Parser/MicrosoftExtensions.c | 2 |
6 files changed, 29 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fb1eb58dcc7..11b3263d705 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -867,6 +867,12 @@ def ReturnsTwice : InheritableAttr { let Documentation = [Undocumented]; } +def NoAlias : InheritableAttr { + let Spellings = [Declspec<"noalias">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [NoAliasDocs]; +} + def NoCommon : InheritableAttr { let Spellings = [GCC<"nocommon">]; let Subjects = SubjectList<[Var]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index e4ca0cb4778..9d7c7662fa8 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1583,3 +1583,13 @@ The ``returns_nonnull`` attribute indicates that a particular function (or Objec The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable }]; } + +def NoAliasDocs : Documentation { + let Category = DocCatFunction; + let Heading = "noalias"; + let Content = [{ +The ``noalias`` attribute indicates that the only memory accesses inside +function are loads and stores from objects pointed to by its pointer-typed +arguments, with arbitrary offsets. + }]; +} diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 2dc94d06f32..a61f13fb9ab 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1421,13 +1421,16 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, FuncAttrs.addAttribute(llvm::Attribute::NoReturn); } - // 'const' and 'pure' attribute functions are also nounwind. + // 'const', 'pure' and 'noalias' attributed functions are also nounwind. if (TargetDecl->hasAttr<ConstAttr>()) { FuncAttrs.addAttribute(llvm::Attribute::ReadNone); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } else if (TargetDecl->hasAttr<PureAttr>()) { FuncAttrs.addAttribute(llvm::Attribute::ReadOnly); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); + } else if (TargetDecl->hasAttr<NoAliasAttr>()) { + FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly); + FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } if (TargetDecl->hasAttr<RestrictAttr>()) RetAttrs.addAttribute(llvm::Attribute::NoAlias); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 191dbd05c9b..9ec3356d048 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4723,6 +4723,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_Mode: handleModeAttr(S, D, Attr); break; + case AttributeList::AT_NoAlias: + handleSimpleAttribute<NoAliasAttr>(S, D, Attr); + break; case AttributeList::AT_NoCommon: handleSimpleAttribute<NoCommonAttr>(S, D, Attr); break; diff --git a/clang/test/CodeGen/ms-declspecs.c b/clang/test/CodeGen/ms-declspecs.c index c32733e65ff..d5071ab60c4 100644 --- a/clang/test/CodeGen/ms-declspecs.c +++ b/clang/test/CodeGen/ms-declspecs.c @@ -33,7 +33,12 @@ __declspec(noinline) void t2() {} __declspec(noreturn) void f20_t(void); void f20(void) { f20_t(); } +__declspec(noalias) void noalias_callee(int *x); +// CHECK: call void @noalias_callee({{.*}}) [[NA:#[0-9]+]] +void noalias_caller(int *x) { noalias_callee(x); } + // CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} } // CHECK: attributes [[NUW]] = { nounwind{{.*}} } // CHECK: attributes [[NI]] = { noinline nounwind{{.*}} } // CHECK: attributes [[NR]] = { noreturn } +// CHECK: attributes [[NA]] = { nounwind argmemonly{{.*}} } diff --git a/clang/test/Parser/MicrosoftExtensions.c b/clang/test/Parser/MicrosoftExtensions.c index a29f6c0b549..e58a7455c08 100644 --- a/clang/test/Parser/MicrosoftExtensions.c +++ b/clang/test/Parser/MicrosoftExtensions.c @@ -5,7 +5,7 @@ typedef int (__cdecl *tptr)(void); void (*__fastcall fastpfunc)(void); extern __declspec(dllimport) void __stdcall VarR4FromDec(void); __declspec(deprecated) __declspec(deprecated) char * __cdecl ltoa( long _Val, char * _DstBuf, int _Radix); -__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} expected-warning{{__declspec attribute 'noalias' is not supported}} */ +__declspec(safebuffers) __declspec(noalias) __declspec(restrict) void * __cdecl xxx(void *_Memory); /* expected-warning{{__declspec attribute 'safebuffers' is not supported}} */ typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR; void * __ptr64 PtrToPtr64(const void *p) { |