r228120 - Sema: Add support for __declspec(restrict)

David Majnemer david.majnemer at gmail.com
Tue Feb 3 23:23:21 PST 2015


Author: majnemer
Date: Wed Feb  4 01:23:21 2015
New Revision: 228120

URL: http://llvm.org/viewvc/llvm-project?rev=228120&view=rev
Log:
Sema: Add support for __declspec(restrict)

__declspec(restrict) and __attribute(malloc) are both handled
identically by clang: they are allowed to the noalias LLVM attribute.

Seeing as how noalias models the C99 notion of 'restrict', rename the
internal clang attribute to Restrict from Malloc.

Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Parser/MicrosoftExtensions.c
    cfe/trunk/test/Sema/attr-malloc.c
    cfe/trunk/test/SemaObjC/attr-malloc.m

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Feb  4 01:23:21 2015
@@ -790,9 +790,9 @@ def IBOutletCollection : InheritableAttr
   let Documentation = [Undocumented];
 }
 
-def Malloc : InheritableAttr {
-  let Spellings = [GCC<"malloc">];
-//  let Subjects = [Function];
+def Restrict : InheritableAttr {
+  let Spellings = [Declspec<"restrict">, GCC<"malloc">];
+  let Subjects = SubjectList<[Function]>;
   let Documentation = [Undocumented];
 }
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Feb  4 01:23:21 2015
@@ -2649,9 +2649,6 @@ def warn_attribute_nonnull_no_pointers :
 def warn_attribute_nonnull_parm_no_args : Warning<
   "'nonnull' attribute when used on parameters takes no arguments">,
   InGroup<IgnoredAttributes>;
-def warn_attribute_malloc_pointer_only : Warning<
-  "'malloc' attribute only applies to functions returning a pointer type">,
-  InGroup<IgnoredAttributes>;
 def warn_attribute_sentinel_named_arguments : Warning<
   "'sentinel' attribute requires named arguments">,
   InGroup<IgnoredAttributes>;

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Feb  4 01:23:21 2015
@@ -4498,7 +4498,7 @@ public:
   void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
                                        QualType Param1,
                                        QualType Param2 = QualType(),
-                                       bool addMallocAttr = false);
+                                       bool addRestrictAttr = false);
 
   bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
                                 DeclarationName Name, FunctionDecl* &Operator,

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Feb  4 01:23:21 2015
@@ -1402,7 +1402,7 @@ void CodeGenModule::ConstructAttributeLi
       FuncAttrs.addAttribute(llvm::Attribute::ReadOnly);
       FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
     }
-    if (TargetDecl->hasAttr<MallocAttr>())
+    if (TargetDecl->hasAttr<RestrictAttr>())
       RetAttrs.addAttribute(llvm::Attribute::NoAlias);
     if (TargetDecl->hasAttr<ReturnsNonNullAttr>())
       RetAttrs.addAttribute(llvm::Attribute::NonNull);

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Feb  4 01:23:21 2015
@@ -1548,18 +1548,16 @@ static void handleTLSModelAttr(Sema &S,
                           Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    QualType RetTy = FD->getReturnType();
-    if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
-      D->addAttr(::new (S.Context)
-                 MallocAttr(Attr.getRange(), S.Context,
-                            Attr.getAttributeSpellingListIndex()));
-      return;
-    }
+static void handleRestrictAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  QualType ResultType = getFunctionOrMethodResultType(D);
+  if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
+    D->addAttr(::new (S.Context) RestrictAttr(
+        Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex()));
+    return;
   }
 
-  S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
+  S.Diag(Attr.getLoc(), diag::warn_attribute_return_pointers_only)
+      << Attr.getName() << getFunctionOrMethodResultSourceRange(D);
 }
 
 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -4453,8 +4451,8 @@ static void ProcessDeclAttribute(Sema &S
   case AttributeList::AT_CUDALaunchBounds:
     handleLaunchBoundsAttr(S, D, Attr);
     break;
-  case AttributeList::AT_Malloc:
-    handleMallocAttr(S, D, Attr);
+  case AttributeList::AT_Restrict:
+    handleRestrictAttr(S, D, Attr);
     break;
   case AttributeList::AT_MayAlias:
     handleSimpleAttribute<MayAliasAttr>(S, D, Attr);

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Feb  4 01:23:21 2015
@@ -2054,7 +2054,7 @@ void Sema::DeclareGlobalNewDelete() {
 void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
                                            QualType Return,
                                            QualType Param1, QualType Param2,
-                                           bool AddMallocAttr) {
+                                           bool AddRestrictAttr) {
   DeclContext *GlobalCtx = Context.getTranslationUnitDecl();
   unsigned NumParams = Param2.isNull() ? 1 : 2;
 
@@ -2077,8 +2077,9 @@ void Sema::DeclareGlobalAllocationFuncti
         // FIXME: Do we need to check for default arguments here?
         if (InitialParam1Type == Param1 &&
             (NumParams == 1 || InitialParam2Type == Param2)) {
-          if (AddMallocAttr && !Func->hasAttr<MallocAttr>())
-            Func->addAttr(MallocAttr::CreateImplicit(Context));
+          if (AddRestrictAttr && !Func->hasAttr<RestrictAttr>())
+            Func->addAttr(RestrictAttr::CreateImplicit(
+                Context, RestrictAttr::GNU_malloc));
           // Make the function visible to name lookup, even if we found it in
           // an unimported module. It either is an implicitly-declared global
           // allocation function, or is suppressing that function.
@@ -2121,8 +2122,9 @@ void Sema::DeclareGlobalAllocationFuncti
   Alloc->addAttr(VisibilityAttr::CreateImplicit(Context,
                                                 VisibilityAttr::Default));
 
-  if (AddMallocAttr)
-    Alloc->addAttr(MallocAttr::CreateImplicit(Context));
+  if (AddRestrictAttr)
+    Alloc->addAttr(
+        RestrictAttr::CreateImplicit(Context, RestrictAttr::GNU_malloc));
 
   ParmVarDecl *ParamDecls[2];
   for (unsigned I = 0; I != NumParams; ++I) {

Modified: cfe/trunk/test/Parser/MicrosoftExtensions.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.c?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/test/Parser/MicrosoftExtensions.c (original)
+++ cfe/trunk/test/Parser/MicrosoftExtensions.c Wed Feb  4 01:23:21 2015
@@ -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}} expected-warning{{__declspec attribute 'restrict' is not supported}} */
+__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}} */
 typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR;
 
 void * __ptr64 PtrToPtr64(const void *p) {

Modified: cfe/trunk/test/Sema/attr-malloc.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-malloc.c?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-malloc.c (original)
+++ cfe/trunk/test/Sema/attr-malloc.c Wed Feb  4 01:23:21 2015
@@ -6,16 +6,16 @@
 // Declare malloc here explicitly so we don't depend on system headers.
 void * malloc(size_t) __attribute((malloc));
 
-int no_vars __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
+int no_vars __attribute((malloc)); // expected-warning {{attribute only applies to functions}}
 
-void  returns_void  (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
-int   returns_int   (void) __attribute((malloc)); // expected-warning {{functions returning a pointer type}}
+void  returns_void  (void) __attribute((malloc)); // expected-warning {{attribute only applies to return values that are pointers}}
+int   returns_int   (void) __attribute((malloc)); // expected-warning {{attribute only applies to return values that are pointers}}
 int * returns_intptr(void) __attribute((malloc)); // no-warning
 typedef int * iptr;
 iptr  returns_iptr  (void) __attribute((malloc)); // no-warning
 
-__attribute((malloc)) void *(*f)(); //  expected-warning{{'malloc' attribute only applies to functions returning a pointer type}}
-__attribute((malloc)) int (*g)(); // expected-warning{{'malloc' attribute only applies to functions returning a pointer type}}
+__attribute((malloc)) void *(*f)(); //  expected-warning{{attribute only applies to functions}}
+__attribute((malloc)) int (*g)(); // expected-warning{{attribute only applies to functions}}
 
 __attribute((malloc))
 void * xalloc(unsigned n) { return malloc(n); } // no-warning

Modified: cfe/trunk/test/SemaObjC/attr-malloc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-malloc.m?rev=228120&r1=228119&r2=228120&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/attr-malloc.m (original)
+++ cfe/trunk/test/SemaObjC/attr-malloc.m Wed Feb  4 01:23:21 2015
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -verify -fsyntax-only -fblocks %s
 
 @interface TestAttrMallocOnMethods {}
-- (id) test1 __attribute((malloc)); //  expected-warning {{functions returning a pointer type}}
-- (int) test2 __attribute((malloc)); //  expected-warning {{functions returning a pointer type}}
+- (id) test1 __attribute((malloc)); //  expected-warning {{attribute only applies to functions}}
+- (int) test2 __attribute((malloc)); //  expected-warning {{attribute only applies to functions}}
 @end
 
 id bar(void) __attribute((malloc)); // no-warning
@@ -10,7 +10,7 @@ id bar(void) __attribute((malloc)); // n
 typedef void (^bptr)(void);
 bptr baz(void) __attribute((malloc)); // no-warning
 
-__attribute((malloc)) id (*f)(); //  expected-warning {{functions returning a pointer type}}
-__attribute((malloc)) bptr (*g)(); //  expected-warning {{functions returning a pointer type}}
-__attribute((malloc)) void *(^h)(); //  expected-warning {{functions returning a pointer type}}
+__attribute((malloc)) id (*f)(); //  expected-warning {{attribute only applies to functions}}
+__attribute((malloc)) bptr (*g)(); //  expected-warning {{attribute only applies to functions}}
+__attribute((malloc)) void *(^h)(); //  expected-warning {{attribute only applies to functions}}
 





More information about the cfe-commits mailing list