From b4456eb59f4c1ff0cec951c0bde60e62f082a5fb Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 21 Oct 2015 18:06:38 +0000 Subject: [PATCH] Some minor ARC diagnostic improvements. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@250917 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Type.h | 6 +++++- include/clang/Basic/DiagnosticSemaKinds.td | 14 +++++++++----- lib/Sema/JumpDiagnostics.cpp | 7 +++++-- test/ARCMT/checking.m | 2 +- test/SemaObjC/arc-property-lifetime.m | 4 ++-- test/SemaObjC/arc.m | 12 +++++++++++- test/SemaObjCXX/arc-type-conversion.mm | 4 ++-- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index c548fd3d04..d080535ba7 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -441,7 +441,8 @@ public: /// /// One set of Objective-C lifetime qualifiers compatibly includes the other /// if the lifetime qualifiers match, or if both are non-__weak and the - /// including set also contains the 'const' qualifier. + /// including set also contains the 'const' qualifier, or both are non-__weak + /// and one is None (which can only happen in non-ARC modes). bool compatiblyIncludesObjCLifetime(Qualifiers other) const { if (getObjCLifetime() == other.getObjCLifetime()) return true; @@ -449,6 +450,9 @@ public: if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) return false; + if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) + return true; + return hasConst(); } diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f5903b896d..fe6d5a6c56 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4423,8 +4423,10 @@ def note_protected_by_seh_finally : Note< "jump bypasses initialization of __finally block">; def note_protected_by___block : Note< "jump bypasses setup of __block variable">; -def note_protected_by_objc_ownership : Note< - "jump bypasses initialization of retaining variable">; +def note_protected_by_objc_strong_init : Note< + "jump bypasses initialization of __strong variable">; +def note_protected_by_objc_weak_init : Note< + "jump bypasses initialization of __weak variable">; def note_enters_block_captures_cxx_obj : Note< "jump enters lifetime of block which captures a destructible C++ object">; def note_enters_block_captures_strong : Note< @@ -4461,8 +4463,10 @@ def note_exits_seh_finally : Note< "jump exits __finally block">; def note_exits_objc_autoreleasepool : Note< "jump exits autoreleasepool block">; -def note_exits_objc_ownership : Note< - "jump exits scope of retaining variable">; +def note_exits_objc_strong : Note< + "jump exits scope of __strong variable">; +def note_exits_objc_weak : Note< + "jump exits scope of __weak variable">; def note_exits_block_captures_cxx_obj : Note< "jump exits lifetime of block which captures a destructible C++ object">; def note_exits_block_captures_strong : Note< @@ -4665,7 +4669,7 @@ def err_arc_strong_property_ownership : Error< "existing instance variable %1 for strong property %0 may not be " "%select{|__unsafe_unretained||__weak}2">; def err_arc_assign_property_ownership : Error< - "existing instance variable %1 for property %0 with %select{unsafe_unretained| assign}2 " + "existing instance variable %1 for property %0 with %select{unsafe_unretained|assign}2 " "attribute must be __unsafe_unretained">; def err_arc_inconsistent_property_ownership : Error< "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be " diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp index 775fe85740..c394d24d5f 100644 --- a/lib/Sema/JumpDiagnostics.cpp +++ b/lib/Sema/JumpDiagnostics.cpp @@ -147,9 +147,12 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) { if (VD->hasLocalStorage()) { switch (VD->getType().isDestructedType()) { case QualType::DK_objc_strong_lifetime: + return ScopePair(diag::note_protected_by_objc_strong_init, + diag::note_exits_objc_strong); + case QualType::DK_objc_weak_lifetime: - return ScopePair(diag::note_protected_by_objc_ownership, - diag::note_exits_objc_ownership); + return ScopePair(diag::note_protected_by_objc_weak_init, + diag::note_exits_objc_weak); case QualType::DK_cxx_destructor: OutDiag = diag::note_exits_dtor; diff --git a/test/ARCMT/checking.m b/test/ARCMT/checking.m index 11a57538d7..0ce894cb42 100644 --- a/test/ARCMT/checking.m +++ b/test/ARCMT/checking.m @@ -180,7 +180,7 @@ void test6(unsigned cond) { switch (cond) { case 0: ; - id x; // expected-note {{jump bypasses initialization of retaining variable}} + id x; // expected-note {{jump bypasses initialization of __strong variable}} case 1: // expected-error {{cannot jump}} x = 0; diff --git a/test/SemaObjC/arc-property-lifetime.m b/test/SemaObjC/arc-property-lifetime.m index 4874ff3a35..cfa32d1028 100644 --- a/test/SemaObjC/arc-property-lifetime.m +++ b/test/SemaObjC/arc-property-lifetime.m @@ -70,7 +70,7 @@ // rdar://9341593 @interface Gorf { id __unsafe_unretained x; - id y; // expected-error {{existing instance variable 'y' for property 'y' with assign attribute must be __unsafe_unretained}} + id y; // expected-error {{existing instance variable 'y' for property 'y' with assign attribute must be __unsafe_unretained}} } @property(assign) id __unsafe_unretained x; @property(assign) id y; // expected-note {{property declared here}} @@ -180,7 +180,7 @@ void foo(Baz *f) { @end @interface Foo2 { - id _prop; // expected-error {{existing instance variable '_prop' for property 'prop' with assign attribute must be __unsafe_unretained}} + id _prop; // expected-error {{existing instance variable '_prop' for property 'prop' with assign attribute must be __unsafe_unretained}} } @property (nonatomic, assign) id prop; // expected-note {{property declared here}} @end diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m index 4b03a94be3..c723812212 100644 --- a/test/SemaObjC/arc.m +++ b/test/SemaObjC/arc.m @@ -127,7 +127,17 @@ void test6(unsigned cond) { switch (cond) { case 0: ; - id x; // expected-note {{jump bypasses initialization of retaining variable}} + id x; // expected-note {{jump bypasses initialization of __strong variable}} + + case 1: // expected-error {{cannot jump}} + break; + } +} +void test6a(unsigned cond) { + switch (cond) { + case 0: + ; + __weak id x; // expected-note {{jump bypasses initialization of __weak variable}} case 1: // expected-error {{cannot jump}} break; diff --git a/test/SemaObjCXX/arc-type-conversion.mm b/test/SemaObjCXX/arc-type-conversion.mm index fd42513d5f..8544726e25 100644 --- a/test/SemaObjCXX/arc-type-conversion.mm +++ b/test/SemaObjCXX/arc-type-conversion.mm @@ -6,8 +6,8 @@ void * cvt(id arg) // expected-note{{candidate function not viable: cannot conve void* voidp_val; (void)(int*)arg; // expected-error {{cast of an Objective-C pointer to 'int *' is disallowed with ARC}} (void)(id)arg; - (void)(__autoreleasing id*)arg; // expected-error{{C-style cast from 'id' to '__autoreleasing id *' casts away qualifiers}} - (void)(id*)arg; // expected-error{{C-style cast from 'id' to '__strong id *' casts away qualifiers}} + (void)(__autoreleasing id*)arg; // expected-error{{cast of an Objective-C pointer to '__autoreleasing id *' is disallowed with ARC}} + (void)(id*)arg; // expected-error{{cast of an Objective-C pointer to '__strong id *' is disallowed with ARC}} (void)(__autoreleasing id**)voidp_val; (void)(void*)voidp_val; -- 2.50.1