diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2011-06-01 07:44:31 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2011-06-01 07:44:31 +0000 |
commit | 1be750abc6c5168c85800750d73bf7afac941b61 (patch) | |
tree | 6445018bca0ec3d22e7fb67a1c499c283af8a01a /clang/lib/Sema/SemaStmt.cpp | |
parent | 460132d35ce36d8dc9701035d97f23d13dcb91f7 (diff) | |
download | bcm5719-llvm-1be750abc6c5168c85800750d73bf7afac941b61.tar.gz bcm5719-llvm-1be750abc6c5168c85800750d73bf7afac941b61.zip |
Even a return statement of an expression with a dependent type in a void
function might need to clean up its temporaries. Fixes PR10057.
llvm-svn: 132390
Diffstat (limited to 'clang/lib/Sema/SemaStmt.cpp')
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 186136b7939..00a35e1cd04 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1687,27 +1687,30 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ReturnStmt *Result = 0; if (FnRetType->isVoidType()) { - if (RetValExp && !RetValExp->isTypeDependent()) { - // C99 6.8.6.4p1 (ext_ since GCC warns) - unsigned D = diag::ext_return_has_expr; - if (RetValExp->getType()->isVoidType()) - D = diag::ext_return_has_void_expr; - else { - ExprResult Result = Owned(RetValExp); - Result = IgnoredValueConversions(Result.take()); - if (Result.isInvalid()) - return StmtError(); - RetValExp = Result.take(); - RetValExp = ImpCastExprToType(RetValExp, Context.VoidTy, CK_ToVoid).take(); - } + if (RetValExp) { + if (!RetValExp->isTypeDependent()) { + // C99 6.8.6.4p1 (ext_ since GCC warns) + unsigned D = diag::ext_return_has_expr; + if (RetValExp->getType()->isVoidType()) + D = diag::ext_return_has_void_expr; + else { + ExprResult Result = Owned(RetValExp); + Result = IgnoredValueConversions(Result.take()); + if (Result.isInvalid()) + return StmtError(); + RetValExp = Result.take(); + RetValExp = ImpCastExprToType(RetValExp, + Context.VoidTy, CK_ToVoid).take(); + } - // return (some void expression); is legal in C++. - if (D != diag::ext_return_has_void_expr || - !getLangOptions().CPlusPlus) { - NamedDecl *CurDecl = getCurFunctionOrMethodDecl(); - Diag(ReturnLoc, D) - << CurDecl->getDeclName() << isa<ObjCMethodDecl>(CurDecl) - << RetValExp->getSourceRange(); + // return (some void expression); is legal in C++. + if (D != diag::ext_return_has_void_expr || + !getLangOptions().CPlusPlus) { + NamedDecl *CurDecl = getCurFunctionOrMethodDecl(); + Diag(ReturnLoc, D) + << CurDecl->getDeclName() << isa<ObjCMethodDecl>(CurDecl) + << RetValExp->getSourceRange(); + } } CheckImplicitConversions(RetValExp, ReturnLoc); |