зеркало из https://github.com/microsoft/clang.git
Track down return statements in the handlers of a function-try-block of constructors. Meh ...
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70256 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2bf1eb09f0
Коммит
13e8854b18
|
@ -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">;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> 15.4 [except.spec]</td>
|
||||
|
|
Загрузка…
Ссылка в новой задаче