]> granicus.if.org Git - clang/commitdiff
Even a return statement of an expression with a dependent type in a void
authorNick Lewycky <nicholas@mxc.ca>
Wed, 1 Jun 2011 07:44:31 +0000 (07:44 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Wed, 1 Jun 2011 07:44:31 +0000 (07:44 +0000)
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

lib/Sema/SemaStmt.cpp
test/SemaCXX/return.cpp

index 186136b7939bd73b1800a5bea475fc1992798e1f..00a35e1cd045f0cc7b37ad3dd756e0cc8a726ead 100644 (file)
@@ -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);
index af7f50ce44b3e77c835d2b2f66c54df36b424958..f83b55a6ab8ddb5ea5ca2e2a8a57d77819e46f04 100644 (file)
@@ -53,3 +53,14 @@ namespace PR9328 {
 class foo  {
   operator int * const ();
 };
+
+namespace PR10057 {
+  struct S {
+    ~S();
+  };
+
+  template <class VarType>
+  void Test(const VarType& value) {
+    return S() = value;
+  }
+}