From: David Majnemer Date: Mon, 20 Jul 2015 22:51:52 +0000 (+0000) Subject: [MS Compat] Add support for __declspec(noalias) X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f3e8e6409f7fdf07b2d058dcb797b019ec2595a2;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242728 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index fb1eb58dcc..11b3263d70 100644 --- a/include/clang/Basic/Attr.td +++ b/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/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index e4ca0cb477..9d7c7662fa 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/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/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 2dc94d06f3..a61f13fb9a 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/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()) { FuncAttrs.addAttribute(llvm::Attribute::ReadNone); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } else if (TargetDecl->hasAttr()) { FuncAttrs.addAttribute(llvm::Attribute::ReadOnly); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); + } else if (TargetDecl->hasAttr()) { + FuncAttrs.addAttribute(llvm::Attribute::ArgMemOnly); + FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); } if (TargetDecl->hasAttr()) RetAttrs.addAttribute(llvm::Attribute::NoAlias); diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 191dbd05c9..9ec3356d04 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/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(S, D, Attr); + break; case AttributeList::AT_NoCommon: handleSimpleAttribute(S, D, Attr); break; diff --git a/test/CodeGen/ms-declspecs.c b/test/CodeGen/ms-declspecs.c index c32733e65f..d5071ab60c 100644 --- a/test/CodeGen/ms-declspecs.c +++ b/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/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c index a29f6c0b54..e58a7455c0 100644 --- a/test/Parser/MicrosoftExtensions.c +++ b/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) {