diff --git a/include/clang/Basic/DiagnosticSemaKinds.def b/include/clang/Basic/DiagnosticSemaKinds.def index 1b9cd916b8..05c46563bb 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.def +++ b/include/clang/Basic/DiagnosticSemaKinds.def @@ -103,7 +103,9 @@ DIAG(err_builtin_definition, ERROR, DIAG(ext_typedef_without_a_name, EXTWARN, "typedef requires a name") DIAG(err_statically_allocated_object, ERROR, - "statically allocated Objective-C object %0") + "Objective-C type cannot be statically allocated") +DIAG(err_object_cannot_be_by_value, ERROR, + "Objective-C type cannot be %0 by value") DIAG(warn_enum_value_overflow, WARNING, "overflow in enumeration value") DIAG(warn_pragma_pack_invalid_alignment, WARNING, @@ -174,8 +176,6 @@ DIAG(err_duplicate_method_decl, ERROR, "duplicate declaration of method %0") DIAG(error_missing_method_context, ERROR, "missing context for method declaration") -DIAG(err_object_as_method_param, ERROR, - "can not use an object as parameter to a method") DIAG(err_objc_property_attr_mutually_exclusive, ERROR, "property attributes '%0' and '%1' are mutually exclusive") DIAG(err_objc_property_requires_object, ERROR, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index c7f37fc286..dfa1e03177 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1470,8 +1470,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC, CheckExtraCXXDefaultArguments(D); if (R.getTypePtr()->isObjCInterfaceType()) { - Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object) - << D.getIdentifier(); + Diag(D.getIdentifierLoc(), diag::err_statically_allocated_object); InvalidDecl = true; } @@ -2761,6 +2760,13 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { << D.getCXXScopeSpec().getRange(); New->setInvalidDecl(); } + // Parameter declarators cannot be interface types. All ObjC objects are + // passed by reference. + if (parmDeclType->isObjCInterfaceType()) { + Diag(D.getIdentifierLoc(), diag::err_object_cannot_be_by_value) + << "passed"; + New->setInvalidDecl(); + } // Add the parameter declaration into this scope. S->AddDecl(New); @@ -3671,8 +3677,7 @@ void Sema::ActOnFields(Scope* S, } /// A field cannot be an Objective-c object if (FDTy->isObjCInterfaceType()) { - Diag(FD->getLocation(), diag::err_statically_allocated_object) - << FD->getDeclName(); + Diag(FD->getLocation(), diag::err_statically_allocated_object); FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); continue; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 967094af77..660f745228 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1344,9 +1344,17 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( } QualType resultDeclType; - if (ReturnType) + if (ReturnType) { resultDeclType = QualType::getFromOpaquePtr(ReturnType); - else // get the type for "id". + + // Methods cannot return interface types. All ObjC objects are + // passed by reference. + if (resultDeclType->isObjCInterfaceType()) { + Diag(MethodLoc, diag::err_object_cannot_be_by_value) + << "returned"; + return 0; + } + } else // get the type for "id". resultDeclType = Context.getObjCIdType(); ObjCMethodDecl* ObjCMethod = @@ -1375,7 +1383,9 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( argType = Context.getPointerType(argType); else if (argType->isObjCInterfaceType()) { // FIXME! provide more precise location for the parameter - Diag(MethodLoc, diag::err_object_as_method_param); + Diag(MethodLoc, diag::err_object_cannot_be_by_value) + << "passed"; + ObjCMethod->setInvalidDecl(); return 0; } } else diff --git a/test/Parser/objc-init.m b/test/Parser/objc-init.m index 085db72568..f45d3236b5 100644 --- a/test/Parser/objc-init.m +++ b/test/Parser/objc-init.m @@ -14,8 +14,8 @@ void test1() { id objects[] = {[NSNumber METH]}; } -void test2(NSNumber x) { - id objects[] = {[x METH]}; // expected-error {{bad receiver type}} +void test2(NSNumber x) { // expected-error {{Objective-C type cannot be passed by value}} + id objects[] = {[x METH]}; } void test3(NSNumber *x) { diff --git a/test/SemaObjC/invalid-objc-decls-1.m b/test/SemaObjC/invalid-objc-decls-1.m index fa18079d07..9db5f79fb6 100644 --- a/test/SemaObjC/invalid-objc-decls-1.m +++ b/test/SemaObjC/invalid-objc-decls-1.m @@ -1,29 +1,33 @@ // RUN: clang -fsyntax-only -verify %s @interface Super @end -Super s1; // expected-error{{statically allocated Objective-C object 's1'}} +Super s1; // expected-error{{Objective-C type cannot be statically allocated}} -extern Super e1; // expected-error{{statically allocated Objective-C object 'e1'}} +extern Super e1; // expected-error{{Objective-C type cannot be statically allocated}} struct S { - Super s1; // expected-error{{statically allocated Objective-C object 's1'}} + Super s1; // expected-error{{Objective-C type cannot be statically allocated}} }; @protocol P1 @end @interface INTF { - Super ivar1; // expected-error{{statically allocated Objective-C object 'ivar1'}} + Super ivar1; // expected-error{{Objective-C type cannot be statically allocated}} } @end +struct whatever { + Super objField; // expected-error{{Objective-C type cannot be statically allocated}} +}; + @interface MyIntf { - Super ivar1; // expected-error{{statically allocated Objective-C object 'ivar1'}} + Super ivar1; // expected-error{{Objective-C type cannot be statically allocated}} } @end -Super foo(Super parm1) { - Super p1; // expected-error{{statically allocated Objective-C object 'p1'}} +Super foo(Super parm1) { // expected-error{{Objective-C type cannot be passed by value}} + Super p1; // expected-error{{Objective-C type cannot be statically allocated}} return p1; } diff --git a/test/SemaObjC/method-bad-param.m b/test/SemaObjC/method-bad-param.m index 34f71e76a5..2e36a15264 100644 --- a/test/SemaObjC/method-bad-param.m +++ b/test/SemaObjC/method-bad-param.m @@ -7,11 +7,15 @@ @end @interface bar --(void) my_method:(foo) my_param; // expected-error {{can not use an object as parameter to a method}} +-(void) my_method:(foo) my_param; // expected-error {{Objective-C type cannot be passed by value}} +- (foo)cccccc:(long)ddddd; // expected-error {{Objective-C type cannot be returned by value}} @end @implementation bar --(void) my_method:(foo) my_param // expected-error {{can not use an object as parameter to a method}} +-(void) my_method:(foo) my_param // expected-error {{Objective-C type cannot be passed by value}} +{ +} +- (foo)cccccc:(long)ddddd // expected-error {{Objective-C type cannot be returned by value}} { } @end