aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp48
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)