]> granicus.if.org Git - clang/commitdiff
Track down return statements in the handlers of a function-try-block of constructors...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 27 Apr 2009 21:33:24 +0000 (21:33 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 27 Apr 2009 21:33:24 +0000 (21:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70256 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/exceptions.cpp
www/cxx_status.html

index c6f3b0b50b1ee923e3aaa9c9b7c0ee6908b86942..e115703a95e5729b3b211d8c58f28e30498f5eb9 100644 (file)
@@ -1204,6 +1204,8 @@ def err_throw_incomplete : Error<
   "cannot throw object of incomplete type %0">;
 def err_throw_incomplete_ptr : Error<
   "cannot throw pointer to object of incomplete type %0">;
+def err_return_in_constructor_handler : Error<
+  "return in the catch of a function try block of a constructor is illegal">;
 
 def err_invalid_use_of_function_type : Error<
   "a function type is not allowed here">;
index 637804ce0921c76d26875acb2cd31d9020f963c2..faaeb7989e50227dd05c956e3281fee9e855b580 100644 (file)
@@ -60,6 +60,7 @@ namespace clang {
   class ArrayType;
   class LabelStmt;
   class SwitchStmt;
+  class CXXTryStmt;
   class ExtVectorType;
   class TypedefDecl;
   class TemplateDecl;
@@ -1225,6 +1226,7 @@ public:
   virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
                                             StmtArg TryBlock,
                                             MultiStmtArg Handlers);
+  void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
 
   //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks: SemaExpr.cpp.
index 482c304603b824add8ca868b987bf3be62718948..7549c9c69cff5d10aafdc6ff6ae7c2a0f2578b9b 100644 (file)
@@ -3054,6 +3054,11 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
   if (CurFunctionNeedsScopeChecking)
     DiagnoseInvalidJumps(Body);
 
+  // C++ constructors that have function-try-blocks can't have return statements
+  // in the handlers of that block. (C++ [except.handle]p14) Verify this.
+  if (isa<CXXConstructorDecl>(dcl) && isa<CXXTryStmt>(Body))
+    DiagnoseReturnInConstructorExceptionHandler(cast<CXXTryStmt>(Body));
+
   return D;
 }
 
index 87a518b55833743d6f8df777f840846bd93cf4b1..71d2f80cfc44e6cc1f03e978477e3d05c5773970 100644 (file)
@@ -2664,3 +2664,24 @@ void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
   }
   Fn->setDeleted();
 }
+
+static void SearchForReturnInStmt(Sema &Self, Stmt *S) {
+  for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end(); CI != E;
+       ++CI) {
+    Stmt *SubStmt = *CI;
+    if (!SubStmt)
+      continue;
+    if (isa<ReturnStmt>(SubStmt))
+      Self.Diag(SubStmt->getSourceRange().getBegin(),
+           diag::err_return_in_constructor_handler);
+    if (!isa<Expr>(SubStmt))
+      SearchForReturnInStmt(Self, SubStmt);
+  }
+}
+
+void Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) {
+  for (unsigned I = 0, E = TryBlock->getNumHandlers(); I != E; ++I) {
+    CXXCatchStmt *Handler = TryBlock->getHandler(I);
+    SearchForReturnInStmt(*this, Handler);
+  }
+}
index 42973eba70ed794cec460950d5b3d77075ddbdb3..5882b9cb708339bb6f9ea8dcd5c531341d9fa8c1 100644 (file)
@@ -68,3 +68,32 @@ l5:
   goto l2; // expected-error {{illegal goto into protected scope}}
   goto l1;
 }
+
+struct BadReturn {
+  BadReturn() try {
+  } catch(...) {
+    // Try to hide
+    try {
+    } catch(...) {
+      {
+        if (0)
+          return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+      }
+    }
+  }
+  BadReturn(int);
+};
+
+BadReturn::BadReturn(int) try {
+} catch(...) {
+  // Try to hide
+  try {
+  } catch(int) {
+    return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+  } catch(...) {
+    {
+      if (0)
+        return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}
+    }
+  }
+}
index ab8171c4cf3b81dafa26d2ebbe22dc85f05edd66..e8547cd6bb45d035088185b6cb1c17bb19ab5152 100644 (file)
@@ -1664,7 +1664,7 @@ welcome!</p>
   <td class="na" align="center">N/A</td>
   <td class="advanced" align="center"></td>
   <td></td>
-  <td>Not all constraints are checked, such as existence of return statements in function-try-block handlers of constructors</td>
+  <td>Not all constraints are checked</td>
 </tr>
 <tr>
   <td>&nbsp;&nbsp;15.4 [except.spec]</td>