Track down return statements in the handlers of a function-try-block of constructors. Meh ...

llvm-svn: 70256
This commit is contained in:
Sebastian Redl 2009-04-27 21:33:24 +00:00
parent 0bc1293584
commit 4c018663b2
6 changed files with 60 additions and 1 deletions

View File

@ -1204,6 +1204,8 @@ def err_throw_incomplete : Error<
"cannot throw object of incomplete type %0">; "cannot throw object of incomplete type %0">;
def err_throw_incomplete_ptr : Error< def err_throw_incomplete_ptr : Error<
"cannot throw pointer to object of incomplete type %0">; "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< def err_invalid_use_of_function_type : Error<
"a function type is not allowed here">; "a function type is not allowed here">;

View File

@ -60,6 +60,7 @@ namespace clang {
class ArrayType; class ArrayType;
class LabelStmt; class LabelStmt;
class SwitchStmt; class SwitchStmt;
class CXXTryStmt;
class ExtVectorType; class ExtVectorType;
class TypedefDecl; class TypedefDecl;
class TemplateDecl; class TemplateDecl;
@ -1225,6 +1226,7 @@ public:
virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc, virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
StmtArg TryBlock, StmtArg TryBlock,
MultiStmtArg Handlers); MultiStmtArg Handlers);
void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Expression Parsing Callbacks: SemaExpr.cpp. // Expression Parsing Callbacks: SemaExpr.cpp.

View File

@ -3054,6 +3054,11 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
if (CurFunctionNeedsScopeChecking) if (CurFunctionNeedsScopeChecking)
DiagnoseInvalidJumps(Body); 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; return D;
} }

View File

@ -2664,3 +2664,24 @@ void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
} }
Fn->setDeleted(); 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);
}
}

View File

@ -68,3 +68,32 @@ l5:
goto l2; // expected-error {{illegal goto into protected scope}} goto l2; // expected-error {{illegal goto into protected scope}}
goto l1; 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}}
}
}
}

View File

@ -1664,7 +1664,7 @@ welcome!</p>
<td class="na" align="center">N/A</td> <td class="na" align="center">N/A</td>
<td class="advanced" align="center"></td> <td class="advanced" align="center"></td>
<td></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>
<tr> <tr>
<td>&nbsp;&nbsp;15.4 [except.spec]</td> <td>&nbsp;&nbsp;15.4 [except.spec]</td>