]> granicus.if.org Git - clang/commitdiff
Fix a crash when overloading id with objc_object*.
authorFariborz Jahanian <fjahanian@apple.com>
Wed, 8 Sep 2010 20:08:18 +0000 (20:08 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Wed, 8 Sep 2010 20:08:18 +0000 (20:08 +0000)
Radar 8400356.

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

include/clang/AST/Type.h
lib/AST/Type.cpp
lib/Sema/SemaType.cpp
test/SemaObjC/legacy-objc-types.m [new file with mode: 0644]
test/SemaObjCXX/legacy-objc-types.mm [new file with mode: 0644]

index 92e62a58d42ce6696b83ebb8c3b5ea0319273f3b..e643843a20dcba81a09f508ce120b17f48b0bca6 100644 (file)
@@ -932,7 +932,9 @@ public:
   bool isObjCQualifiedClassType() const;        // Class<foo>
   bool isObjCObjectOrInterfaceType() const;
   bool isObjCIdType() const;                    // id
+  bool isLegacyObjCIdType(ASTContext &) const;  // struct_object *
   bool isObjCClassType() const;                 // Class
+  bool isLegacyObjCClassType(ASTContext &) const; // struct_class *
   bool isObjCSelType() const;                 // Class
   bool isObjCBuiltinType() const;               // 'id' or 'Class'
   bool isTemplateTypeParmType() const;          // C++ template type parameter
index 8e6aa23618c5ee9fbdaf9da553096ac72984d3c6..114c9ac7df9fb31678f2e0aefe47f5e9543e6801 100644 (file)
@@ -470,6 +470,24 @@ bool Type::isIntegralOrEnumerationType() const {
   return false;  
 }
 
+bool Type::isLegacyObjCIdType(ASTContext &Ctx) const {
+  if (const PointerType *PTTo = getAs<PointerType>()) {
+    QualType PointeeTy = PTTo->getPointeeType();
+    if (const RecordType *RTy = PointeeTy->getAs<RecordType>())
+      return RTy->getDecl()->getIdentifier() == &Ctx.Idents.get("objc_object");
+  }
+  return false;
+}
+
+bool Type::isLegacyObjCClassType(ASTContext &Ctx) const {
+  if (const PointerType *PTTo = getAs<PointerType>()) {
+    QualType PointeeTy = PTTo->getPointeeType();
+    if (const RecordType *RTy = PointeeTy->getAs<RecordType>())
+      return RTy->getDecl()->getIdentifier() == &Ctx.Idents.get("objc_class");
+  }
+  return false;
+}
+
 bool Type::isEnumeralType() const {
   if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
     return TT->getDecl()->isEnum();
index aa30b5c2da302995c96a7a17dc8e9d8000069502..06d8b3d4f6b893853ff1f98473e61b0bab9ca960 100644 (file)
@@ -1274,8 +1274,12 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
               if (BTy->getKind() == BuiltinType::Float)
                 ArgTy = Context.DoubleTy;
             }
+          } else if (getLangOptions().ObjC1) {
+            if (ArgTy->isLegacyObjCIdType(Context))
+              ArgTy = Context.getObjCIdType();
+            else if (ArgTy->isLegacyObjCClassType(Context))
+              ArgTy = Context.getObjCClassType();
           }
-
           ArgTys.push_back(ArgTy);
         }
 
diff --git a/test/SemaObjC/legacy-objc-types.m b/test/SemaObjC/legacy-objc-types.m
new file mode 100644 (file)
index 0000000..dbe32e6
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar:// 8400356
+
+struct objc_object;
+
+void f(id ptr) { } // expected-note {{previous definition is here}}
+void f(struct objc_object* ptr) { }    // expected-error {{redefinition of 'f'}}
+
+struct objc_class;
+
+void g(Class ptr) {} // expected-note {{previous definition is here}}
+void g(struct objc_class* ptr) { }     // expected-error {{redefinition of 'g'}}
+
+void h(Class ptr, struct objc_object* ptr1) {} // expected-note {{previous definition is here}}
+void h(struct objc_class* ptr, id ptr1) {}     // expected-error {{redefinition of 'h'}}
+
+void i(Class ptr, struct objc_object* ptr1);
+void i(struct objc_class* ptr, id ptr1) {}
+void i(struct objc_class* ptr, struct objc_object* ptr1);
+
diff --git a/test/SemaObjCXX/legacy-objc-types.mm b/test/SemaObjCXX/legacy-objc-types.mm
new file mode 100644 (file)
index 0000000..56ee97f
--- /dev/null
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// rdar:// 8400356
+
+struct objc_object;
+
+void f(id ptr) { } // expected-note {{previous definition is here}}
+void f(objc_object* ptr) { }   // expected-error {{redefinition of 'f'}}
+
+struct objc_class;
+
+void g(Class ptr) {} // expected-note {{previous definition is here}}
+void g(objc_class* ptr) { }    // expected-error {{redefinition of 'g'}}
+
+void h(Class ptr, objc_object* ptr1) {} // expected-note {{previous definition is here}}
+void h(objc_class* ptr, id ptr1) {}    // expected-error {{redefinition of 'h'}}
+
+void i(Class ptr, objc_object* ptr1);
+void i(objc_class* ptr, id ptr1) {}
+void i(objc_class* ptr, objc_object* ptr1);
+