r186105 - ObjectiveC arc[qoi]: When due to change of certain methods'
Fariborz Jahanian
fjahanian at apple.com
Thu Jul 11 09:48:07 PDT 2013
Author: fjahanian
Date: Thu Jul 11 11:48:06 2013
New Revision: 186105
URL: http://llvm.org/viewvc/llvm-project?rev=186105&view=rev
Log:
ObjectiveC arc[qoi]: When due to change of certain methods'
result type, a diagnostic being issued, issue a 'note'
mentioning reason behind the unexpected warning.
// rdar://14121570.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Sema/Initialization.h
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/test/SemaObjC/related-result-type-inference.m
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=186105&r1=186104&r2=186105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 11 11:48:06 2013
@@ -4683,6 +4683,8 @@ def note_parameter_named_here : Note<
"passing argument to parameter %0 here">;
def note_parameter_here : Note<
"passing argument to parameter here">;
+def note_method_return_type_change : Note<
+ "compiler has implicitly changed method %0 return type">;
// C++ casts
// These messages adhere to the TryCast pattern: %0 is an int specifying the
Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=186105&r1=186104&r2=186105&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Thu Jul 11 11:48:06 2013
@@ -35,6 +35,7 @@ class ParmVarDecl;
class Sema;
class TypeLoc;
class VarDecl;
+class ObjCMethodDecl;
/// \brief Describes an entity that is being initialized.
class InitializedEntity {
@@ -78,7 +79,10 @@ public:
EK_LambdaCapture,
/// \brief The entity being initialized is the initializer for a compound
/// literal.
- EK_CompoundLiteralInit
+ EK_CompoundLiteralInit,
+ /// \brief The entity being implicitly initialized back to the formal
+ /// result type.
+ EK_RelatedResult
};
private:
@@ -116,6 +120,10 @@ private:
/// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
/// FieldDecl, respectively.
DeclaratorDecl *VariableOrMember;
+
+ /// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
+ /// result type was implicitly changed to accomodate ARC semantics.
+ ObjCMethodDecl *MethodDecl;
/// \brief When Kind == EK_Parameter, the ParmVarDecl, with the
/// low bit indicating whether the parameter is "consumed".
@@ -254,6 +262,15 @@ public:
Result.TypeInfo = TypeInfo;
return Result;
}
+
+ /// \brief Create the initialization entity for a related result.
+ static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD,
+ QualType Type) {
+ InitializedEntity Result(EK_RelatedResult, SourceLocation(), Type);
+ Result.MethodDecl = MD;
+ return Result;
+ }
+
/// \brief Create the initialization entity for a base class subobject.
static InitializedEntity InitializeBase(ASTContext &Context,
@@ -326,6 +343,9 @@ public:
/// \brief Retrieve the variable, parameter, or field being
/// initialized.
DeclaratorDecl *getDecl() const;
+
+ /// \brief Retrieve the ObjectiveC method being initialized.
+ ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
/// \brief Determine whether this initialization allows the named return
/// value optimization, which also applies to thrown objects.
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=186105&r1=186104&r2=186105&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jul 11 11:48:06 2013
@@ -2495,6 +2495,7 @@ DeclarationName InitializedEntity::getNa
case EK_ComplexElement:
case EK_BlockElement:
case EK_CompoundLiteralInit:
+ case EK_RelatedResult:
return DeclarationName();
}
@@ -2522,6 +2523,7 @@ DeclaratorDecl *InitializedEntity::getDe
case EK_BlockElement:
case EK_LambdaCapture:
case EK_CompoundLiteralInit:
+ case EK_RelatedResult:
return 0;
}
@@ -2547,6 +2549,7 @@ bool InitializedEntity::allowsNRVO() con
case EK_ComplexElement:
case EK_BlockElement:
case EK_LambdaCapture:
+ case EK_RelatedResult:
break;
}
@@ -2568,6 +2571,7 @@ unsigned InitializedEntity::dumpImpl(raw
case EK_New: OS << "New"; break;
case EK_Temporary: OS << "Temporary"; break;
case EK_CompoundLiteralInit: OS << "CompoundLiteral";break;
+ case EK_RelatedResult: OS << "RelatedResult"; break;
case EK_Base: OS << "Base"; break;
case EK_Delegating: OS << "Delegating"; break;
case EK_ArrayElement: OS << "ArrayElement " << Index; break;
@@ -4632,6 +4636,7 @@ getAssignmentAction(const InitializedEnt
return Sema::AA_Passing;
case InitializedEntity::EK_Result:
+ case InitializedEntity::EK_RelatedResult:
return Sema::AA_Returning;
case InitializedEntity::EK_Temporary:
@@ -4672,6 +4677,7 @@ static bool shouldBindAsTemporary(const
case InitializedEntity::EK_Parameter:
case InitializedEntity::EK_Temporary:
+ case InitializedEntity::EK_RelatedResult:
return true;
}
@@ -4699,6 +4705,7 @@ static bool shouldDestroyTemporary(const
case InitializedEntity::EK_ArrayElement:
case InitializedEntity::EK_Exception:
case InitializedEntity::EK_CompoundLiteralInit:
+ case InitializedEntity::EK_RelatedResult:
return true;
}
@@ -4781,6 +4788,7 @@ static SourceLocation getInitializationL
case InitializedEntity::EK_ComplexElement:
case InitializedEntity::EK_BlockElement:
case InitializedEntity::EK_CompoundLiteralInit:
+ case InitializedEntity::EK_RelatedResult:
return Initializer->getLocStart();
}
llvm_unreachable("missed an InitializedEntity kind?");
@@ -5001,6 +5009,11 @@ void InitializationSequence::PrintInitLo
else
S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here);
}
+ else if (Entity.getKind() == InitializedEntity::EK_RelatedResult &&
+ Entity.getMethodDecl())
+ S.Diag(Entity.getMethodDecl()->getLocation(),
+ diag::note_method_return_type_change)
+ << Entity.getMethodDecl()->getDeclName();
}
static bool isReferenceBinding(const InitializationSequence::Step &s) {
@@ -5016,6 +5029,7 @@ static bool isExplicitTemporary(const In
switch (Entity.getKind()) {
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_CompoundLiteralInit:
+ case InitializedEntity::EK_RelatedResult:
break;
default:
return false;
@@ -5186,6 +5200,7 @@ InitializedEntityOutlivesFullExpression(
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_LambdaCapture:
case InitializedEntity::EK_CompoundLiteralInit:
+ case InitializedEntity::EK_RelatedResult:
// The entity being initialized might not outlive the full-expression.
return false;
}
@@ -5232,6 +5247,7 @@ getDeclForTemporaryLifetimeExtension(con
case InitializedEntity::EK_Temporary:
case InitializedEntity::EK_CompoundLiteralInit:
+ case InitializedEntity::EK_RelatedResult:
// We don't yet know the storage duration of the surrounding temporary.
// Assume it's got full-expression duration for now, it will patch up our
// storage duration if that's not correct.
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=186105&r1=186104&r2=186105&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jul 11 11:48:06 2013
@@ -2710,11 +2710,10 @@ Sema::ActOnReturnStmt(SourceLocation Ret
// If we have a related result type, we need to implicitly
// convert back to the formal result type. We can't pretend to
// initialize the result again --- we might end double-retaining
- // --- so instead we initialize a notional temporary; this can
- // lead to less-than-great diagnostics, but this stage is much
- // less likely to fail than the previous stage.
+ // --- so instead we initialize a notional temporary.
if (!RelatedRetType.isNull()) {
- Entity = InitializedEntity::InitializeTemporary(FnRetType);
+ Entity = InitializedEntity::InitializeRelatedResult(getCurMethodDecl(),
+ FnRetType);
Res = PerformCopyInitialization(Entity, ReturnLoc, RetValExp);
if (Res.isInvalid()) {
// FIXME: Clean up temporaries here anyway?
Modified: cfe/trunk/test/SemaObjC/related-result-type-inference.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/related-result-type-inference.m?rev=186105&r1=186104&r2=186105&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/related-result-type-inference.m (original)
+++ cfe/trunk/test/SemaObjC/related-result-type-inference.m Thu Jul 11 11:48:06 2013
@@ -173,9 +173,9 @@ void test_inference() {
@interface Fail @end
@protocol X @end
@implementation Fail
-- (id<X>) initWithX
+- (id<X>) initWithX // expected-note {{compiler has implicitly changed method 'initWithX' return type}}
{
- return (id)self; // expected-warning {{casting 'Fail *' to incompatible type 'id<X>'}}
+ return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}}
}
@end
@@ -184,3 +184,19 @@ void test_inference() {
@interface WeirdNSString : NSString
- (id)initWithCString:(const char*)string, void *blah;
@end
+
+
+// rdar://14121570
+ at protocol PMFilterManager
+ at end
+
+ at interface UIViewController : NSObject
+ at end
+
+ at implementation UIViewController
++ (UIViewController<PMFilterManager> *)newFilterViewControllerForType // expected-note {{compiler has implicitly changed method 'newFilterViewControllerForType' return type}}
+{
+ UIViewController<PMFilterManager> *filterVC;
+ return filterVC; // expected-warning {{incompatible pointer types returning 'UIViewController *' from a function with result type 'UIViewController<PMFilterManager> *'}}
+}
+ at end
More information about the cfe-commits
mailing list