]> granicus.if.org Git - clang/commitdiff
Tweak format string checking to work with %@ and ObjC toll-free bridging. <rdar...
authorTed Kremenek <kremenek@apple.com>
Mon, 6 Feb 2012 21:45:29 +0000 (21:45 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 6 Feb 2012 21:45:29 +0000 (21:45 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149907 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/FormatString.cpp
test/SemaObjC/format-strings-objc.m

index 30bfe4bf884ddddf566746365c09acfe2306faf7..1c911c45c3b5af4d5e97276cad65d84d1ef3d23f 100644 (file)
@@ -336,9 +336,23 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
       return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
         argTy->isNullPtrType();
 
-    case ObjCPointerTy:
-      return argTy->getAs<ObjCObjectPointerType>() ||
-             argTy->getAs<BlockPointerType>();
+    case ObjCPointerTy: {
+      if (argTy->getAs<ObjCObjectPointerType>() ||
+          argTy->getAs<BlockPointerType>())
+        return true;
+      
+      // Handle implicit toll-free bridging.
+      if (const PointerType *PT = argTy->getAs<PointerType>()) {
+        // Things such as CFTypeRef are really just opaque pointers
+        // to C structs representing CF types that can often be bridged
+        // to Objective-C objects.  Since the compiler doesn't know which
+        // structs can be toll-free bridged, we just accept them all.
+        QualType pointee = PT->getPointeeType();
+        if (pointee->getAsStructureType() || pointee->isVoidType())
+          return true;
+      }
+      return false;      
+    }
   }
 
   llvm_unreachable("Invalid ArgTypeResult Kind!");
index a4d6eebbacaeb6cedd906b2465037232e094dc25..675729ca1e95d50908ab881e154e531ae307ccd3 100644 (file)
@@ -146,3 +146,8 @@ void test_percent_C() {
   const wchar_t wchar_data = L'a';
   NSLog(@"%C", wchar_data);  // expected-warning{{format specifies type 'unsigned short' but the argument has type 'wchar_t'}}
 }
+
+// Test that %@ works with toll-free bridging (<rdar://problem/10814120>).
+void test_toll_free_bridging(CFStringRef x) {
+  NSLog(@"%@", x); // no-warning
+}