]> granicus.if.org Git - clang/commitdiff
In ARC, when applying an ownership to a non-objc pointer, instead of ignoring it
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 4 Nov 2011 20:37:24 +0000 (20:37 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Fri, 4 Nov 2011 20:37:24 +0000 (20:37 +0000)
create an attributed type with same type as the original type.

We effectively retain the source info that an ownership attribute was present but the attribute
is ignored by not modifying the type that it was applied to.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143736 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaType.cpp

index 09d47e8e1798dc4b57b9240f3c4283940c9c18de..219a9e8a3085a614b50c4c46e41f07fa10e9fe66 100644 (file)
@@ -3258,8 +3258,21 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
 static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
                                        AttributeList &attr,
                                        QualType &type) {
-  if (!type->isObjCRetainableType() && !type->isDependentType())
-    return false;
+  bool NonObjCPointer = false;
+
+  if (!type->isDependentType()) {
+    if (const PointerType *ptr = type->getAs<PointerType>()) {
+      QualType pointee = ptr->getPointeeType();
+      if (pointee->isObjCRetainableType() || pointee->isPointerType())
+        return false;
+      // It is important not to lose the source info that there was an attribute
+      // applied to non-objc pointer. We will create an attributed type but
+      // its type will be the same as the original type.
+      NonObjCPointer = true;
+    } else if (!type->isObjCRetainableType()) {
+      return false;
+    }
+  }
 
   Sema &S = state.getSema();
   SourceLocation AttrLoc = attr.getLoc();
@@ -3300,10 +3313,25 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state,
   if (!S.getLangOptions().ObjCAutoRefCount)
     return true;
 
+  if (NonObjCPointer) {
+    StringRef name = attr.getName()->getName();
+    switch (lifetime) {
+    case Qualifiers::OCL_None:
+    case Qualifiers::OCL_ExplicitNone:
+      break;
+    case Qualifiers::OCL_Strong: name = "__strong"; break;
+    case Qualifiers::OCL_Weak: name = "__weak"; break;
+    case Qualifiers::OCL_Autoreleasing: name = "__autoreleasing"; break;
+    }
+    S.Diag(AttrLoc, diag::warn_objc_object_attribute_wrong_type)
+      << name << type;
+  }
+
   Qualifiers qs;
   qs.setObjCLifetime(lifetime);
   QualType origType = type;
-  type = S.Context.getQualifiedType(type, qs);
+  if (!NonObjCPointer)
+    type = S.Context.getQualifiedType(type, qs);
 
   // If we have a valid source location for the attribute, use an
   // AttributedType instead.