diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 10f0be6e67..e09243372e 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Sema.h" +#include "SemaInit.h" #include "clang/AST/APValue.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" @@ -1027,11 +1028,23 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { return ActOnBlockReturnStmt(ReturnLoc, RetValExp); QualType FnRetType; + TypeLoc FnRetTypeLoc; if (const FunctionDecl *FD = getCurFunctionDecl()) { FnRetType = FD->getResultType(); if (FD->hasAttr<NoReturnAttr>()) Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << getCurFunctionOrMethodDecl()->getDeclName(); + +#if 0 + // FIXME: Useful, once we're sure it has all of the information we + // need. + if (TypeSourceInfo *TInfo = FD->getTypeSourceInfo()) { + TypeLoc TL = TInfo->getTypeLoc(); + if (FunctionTypeLoc *FTL = dyn_cast<FunctionTypeLoc>(&TL)) + FnRetTypeLoc = FTL->getResultLoc(); + } +#endif + } else if (ObjCMethodDecl *MD = getCurMethodDecl()) FnRetType = MD->getResultType(); else // If we don't have a function/method context, bail. @@ -1092,17 +1105,40 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) { bool Elidable = getLangOptions().CPlusPlus0x ? IsReturnCopyElidable(Context, FnRetType, RetValExp) : false; + // FIXME: Elidable + (void)Elidable; + + // If we somehow didn't get a + + // FIXME: Should we allocate the TypeSourceInfo and attach it to + // the declaration? Alternatively, we could require that all + // function and method declarations have TypeSourceInfos, so that + // this is never required. FIXME: Also, the allocated TInfo goes + // into the bump pointer, so it cannot actually be freed. + TypeSourceInfo *AllocatedTInfo = 0; + if (!FnRetTypeLoc) { + const FunctionDecl *FD = getCurFunctionDecl(); + SourceLocation Loc = FD? FD->getLocation() + : getCurMethodDecl()->getLocation(); + AllocatedTInfo = Context.getTrivialTypeSourceInfo(FnRetType, Loc); + FnRetTypeLoc = AllocatedTInfo->getTypeLoc(); + } // In C++ the return statement is handled via a copy initialization. // the C version of which boils down to CheckSingleAssignmentConstraints. - // FIXME: Leaks RetValExp on error. - if (PerformCopyInitialization(RetValExp, FnRetType, AA_Returning, Elidable)){ - // We should still clean up our temporaries, even when we're failing! - RetValExp = MaybeCreateCXXExprWithTemporaries(RetValExp); + rex = PerformCopyInitialization( + InitializedEntity::InitializeResult(ReturnLoc, + FnRetTypeLoc), + SourceLocation(), + Owned(RetValExp)); + if (rex.isInvalid()) { + // FIXME: Cleanup temporaries here, anyway? return StmtError(); } - - if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); + + RetValExp = rex.takeAs<Expr>(); + if (RetValExp) + CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc); } if (RetValExp) |