[cfe-commits] r153716 - in /cfe/trunk: lib/Sema/SemaStmt.cpp test/CodeGenObjC/arc.m test/SemaObjC/instancetype.m test/SemaObjC/related-result-type-inference.m

jahanian fjahanian at apple.com
Fri Mar 30 09:27:05 PDT 2012


On Mar 29, 2012, at 6:13 PM, Eli Friedman wrote:

> Author: efriedma
> Date: Thu Mar 29 20:13:43 2012
> New Revision: 153716
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=153716&view=rev
> Log:
> Make sure we perform the relevant implied conversions correctly for ObjC methods with related result types. PR12384.
> 
> 
> Modified:
>    cfe/trunk/lib/Sema/SemaStmt.cpp
>    cfe/trunk/test/CodeGenObjC/arc.m
>    cfe/trunk/test/SemaObjC/instancetype.m
>    cfe/trunk/test/SemaObjC/related-result-type-inference.m
> 
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=153716&r1=153715&r2=153716&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Mar 29 20:13:43 2012
> @@ -1945,24 +1945,21 @@
>     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
> 
>   QualType FnRetType;
> -  QualType DeclaredRetType;
> +  QualType RelatedRetType;
>   if (const FunctionDecl *FD = getCurFunctionDecl()) {
>     FnRetType = FD->getResultType();
> -    DeclaredRetType = FnRetType;
>     if (FD->hasAttr<NoReturnAttr>() ||
>         FD->getType()->getAs<FunctionType>()->getNoReturnAttr())
>       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
>         << FD->getDeclName();
>   } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
> -    DeclaredRetType = MD->getResultType();
> +    FnRetType = MD->getResultType();
>     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
>       // In the implementation of a method with a related return type, the
>       // type used to type-check the validity of return statements within the 
>       // method body is a pointer to the type of the class being implemented.
> -      FnRetType = Context.getObjCInterfaceType(MD->getClassInterface());
> -      FnRetType = Context.getObjCObjectPointerType(FnRetType);
> -    } else {
> -      FnRetType = DeclaredRetType;
> +      RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());
> +      RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);
>     }
>   } else // If we don't have a function/method context, bail.
>     return StmtError();
> @@ -2045,6 +2042,21 @@
>     if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
>       // we have a non-void function with an expression, continue checking
> 
> +      if (!RelatedRetType.isNull()) {
> +        // If we have a related result type, perform an extra conversion here.
> +        // FIXME: The diagnostics here don't really describe what is happening.
> +        InitializedEntity Entity =
> +            InitializedEntity::InitializeTemporary(RelatedRetType);
> +        
> +        ExprResult Res = PerformCopyInitialization(Entity, SourceLocation(),
> +                                                   RetValExp);
> +        if (Res.isInvalid()) {
> +          // FIXME: Cleanup temporaries here, anyway?
> +          return StmtError();
> +        }
> +        RetValExp = Res.takeAs<Expr>();
> +      }
> +
>       // C99 6.8.6.4p3(136): The return statement is not an assignment. The
>       // overlap restriction of subclause 6.5.16.1 does not apply to the case of
>       // function return.
> @@ -2068,17 +2080,6 @@
>     }
> 
>     if (RetValExp) {
> -      // If we type-checked an Objective-C method's return type based
> -      // on a related return type, we may need to adjust the return
> -      // type again. Do so now.
> -      if (DeclaredRetType != FnRetType) {
> -        ExprResult result = PerformImplicitConversion(RetValExp,
> -                                                      DeclaredRetType,
> -                                                      AA_Returning);
> -        if (result.isInvalid()) return StmtError();
> -        RetValExp = result.take();
> -      }
> -
>       CheckImplicitConversions(RetValExp, ReturnLoc);
>       RetValExp = MaybeCreateExprWithCleanups(RetValExp);
>     }
> 
> Modified: cfe/trunk/test/CodeGenObjC/arc.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc.m?rev=153716&r1=153715&r2=153716&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenObjC/arc.m (original)
> +++ cfe/trunk/test/CodeGenObjC/arc.m Thu Mar 29 20:13:43 2012
> @@ -640,9 +640,7 @@
> // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
> // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
> -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
> -// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
> -// CHECK-NEXT: [[RET:%.*]] = bitcast
> +// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
> // CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]]
> // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
> @@ -706,9 +704,7 @@
> // Return statement.
> // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]]
> // CHECK-NEXT: [[CALL:%.*]] = bitcast
> -// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind
> -// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]]
> -// CHECK-NEXT: [[RET:%.*]] = bitcast
> +// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind
> // CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
> 
> // Cleanup.
> @@ -762,9 +758,7 @@
> // Return statement.
> // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
> -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
> -// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
> -// CHECK-NEXT: [[RET:%.*]] = bitcast
> +// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
> // CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
> 
> // Cleanup.
> @@ -819,9 +813,7 @@
> // Return.
> // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]]
> // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
> -// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
> -// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
> -// CHECK-NEXT: [[RET:%.*]] = bitcast
> +// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
> // CHECK-NEXT: store i32 1
> 
> // Cleanup.
> 
> Modified: cfe/trunk/test/SemaObjC/instancetype.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/instancetype.m?rev=153716&r1=153715&r2=153716&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaObjC/instancetype.m (original)
> +++ cfe/trunk/test/SemaObjC/instancetype.m Thu Mar 29 20:13:43 2012
> @@ -143,7 +143,7 @@
> 
> @implementation Subclass4
> + (id)alloc {
> -  return self; // expected-warning{{incompatible pointer types returning 'Class' from a function with result type 'Subclass4 *'}}
> +  return self; // expected-warning{{incompatible pointer types casting 'Class' to type 'Subclass4 *'}}
> }
> 
> - (Subclass3 *)init { return 0; } // don't complain: we lost the related return type
> @@ -166,12 +166,12 @@
> @implementation Subclass2
> - (instancetype)initSubclass2 {
>   Subclass1 *sc1 = [[Subclass1 alloc] init];
> -  return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
> +  return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}
> }
> - (void)methodOnSubclass2 {}
> - (id)self {
>   Subclass1 *sc1 = [[Subclass1 alloc] init];
> -  return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
> +  return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}

Side-effect of these changes is causing new warning which is far less clear than the one it replaces. It will be matter of time before
we hear from users complaining.

- Fariborz





More information about the cfe-commits mailing list