summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-20 22:51:52 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-20 22:51:52 +0000
commit1bf0f8ede6f8f2b01ae1bccb1cd7519b19465119 (patch)
tree929b8c0863e1444e32ef18f1e91fc92626fa707f
parente4d22d59d1db39262790b6afd3521a65be2d7288 (diff)
downloadbcm5719-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.td6
-rw-r--r--clang/include/clang/Basic/AttrDocs.td10
-rw-r--r--clang/lib/CodeGen/CGCall.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/test/CodeGen/ms-declspecs.c5
-rw-r--r--clang/test/Parser/MicrosoftExtensions.c2
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) {
OpenPOWER on IntegriCloud