diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-03-30 01:13:43 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-03-30 01:13:43 +0000 |
commit | 410fc7ae89f4818e653ec34fcb1c3db25a281393 (patch) | |
tree | 79cf4313720e94aaf40b2286d90a1415a0c105b6 /clang/lib/Sema | |
parent | f4d006348b811779815471bfeec647889dad45ec (diff) | |
download | bcm5719-llvm-410fc7ae89f4818e653ec34fcb1c3db25a281393.tar.gz bcm5719-llvm-410fc7ae89f4818e653ec34fcb1c3db25a281393.zip |
Make sure we perform the relevant implied conversions correctly for ObjC methods with related result types. PR12384.
llvm-svn: 153716
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 6db66a5eff8..39e8a1a1b92 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1945,24 +1945,21 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { 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 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { 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 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } 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); } |