From: Nick Lewycky Date: Wed, 1 Jun 2011 07:44:31 +0000 (+0000) Subject: Even a return statement of an expression with a dependent type in a void X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8d7946151cd15c0e7c34250c122d59b2f5027999;p=clang Even a return statement of an expression with a dependent type in a void function might need to clean up its temporaries. Fixes PR10057. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132390 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 186136b793..00a35e1cd0 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/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(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(CurDecl) + << RetValExp->getSourceRange(); + } } CheckImplicitConversions(RetValExp, ReturnLoc); diff --git a/test/SemaCXX/return.cpp b/test/SemaCXX/return.cpp index af7f50ce44..f83b55a6ab 100644 --- a/test/SemaCXX/return.cpp +++ b/test/SemaCXX/return.cpp @@ -53,3 +53,14 @@ namespace PR9328 { class foo { operator int * const (); }; + +namespace PR10057 { + struct S { + ~S(); + }; + + template + void Test(const VarType& value) { + return S() = value; + } +}