]> granicus.if.org Git - clang/commitdiff
objective-C++: issue diagnostic when ivar type is
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 16 Aug 2012 22:38:41 +0000 (22:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 16 Aug 2012 22:38:41 +0000 (22:38 +0000)
an abstract c++ class. // rdar://12095239

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

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
test/SemaObjCXX/abstract-class-type-ivar.mm [new file with mode: 0644]

index 4733505a00b5d6157d3c139819d8e951ff5844e7..bff9a343184e09ca99648e510229fb7b4f4e356e 100644 (file)
@@ -815,7 +815,7 @@ def err_friend_def_in_local_class : Error<
   "friend function cannot be defined in a local class">;
   
 def err_abstract_type_in_decl : Error<
-  "%select{return|parameter|variable|field}0 type %1 is an abstract class">;
+  "%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">;
 def err_allocation_of_abstract_type : Error<
   "allocating an object of abstract class type %0">;
 def err_throw_abstract_type : Error<
index b320a2452d2d5e6ab1a6556247c4415f634e1371..d1a7017fb0e0404cd831a3f951f0177055d486c3 100644 (file)
@@ -4461,6 +4461,7 @@ public:
     AbstractParamType,
     AbstractVariableType,
     AbstractFieldType,
+    AbstractIvarType,
     AbstractArrayType
   };
 
index d37fbf5378614ff178eb3e2b404213c1016ee518..01b2f2c8397dae7485b4d7ad0c4662ade89a5aa5 100644 (file)
@@ -9913,6 +9913,13 @@ void Sema::ActOnFields(Scope* S,
           }
         }
       }
+      if (isa<ObjCContainerDecl>(EnclosingDecl) &&
+          RequireNonAbstractType(FD->getLocation(), FD->getType(),
+                                 diag::err_abstract_type_in_decl,
+                                 AbstractIvarType)) {
+        // Ivars can not have abstract class types
+        FD->setInvalidDecl();
+      }
       if (Record && FDTTy->getDecl()->hasObjectMember())
         Record->setHasObjectMember(true);
     } else if (FDTy->isObjCObjectType()) {
@@ -9921,8 +9928,7 @@ void Sema::ActOnFields(Scope* S,
         << FixItHint::CreateInsertion(FD->getLocation(), "*");
       QualType T = Context.getObjCObjectPointerType(FD->getType());
       FD->setType(T);
-    } 
-    else if (!getLangOpts().CPlusPlus) {
+    } else if (!getLangOpts().CPlusPlus) {
       if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) {
         // It's an error in ARC if a field has lifetime.
         // We don't want to report this in a system header, though,
diff --git a/test/SemaObjCXX/abstract-class-type-ivar.mm b/test/SemaObjCXX/abstract-class-type-ivar.mm
new file mode 100644 (file)
index 0000000..823e9c1
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://12095239
+
+class CppAbstractBase {
+public:
+    virtual void testA() = 0;
+    virtual void testB() = 0; // expected-note {{unimplemented pure virtual method 'testB' in 'CppConcreteSub}}
+    int a;
+};
+
+class CppConcreteSub : public CppAbstractBase {
+    virtual void testA() { }
+};
+
+@interface Objc  {
+    CppConcreteSub _concrete; // expected-error{{ivar type 'CppConcreteSub' is an abstract class}}
+}
+- (CppAbstractBase*)abstract;
+@end
+@implementation Objc
+- (CppAbstractBase*)abstract {
+    return &_concrete;
+}
+@end
+
+class Cpp {
+public:
+    CppConcreteSub sub; // expected-error {{field type 'CppConcreteSub' is an abstract class}}
+};