diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-04-27 21:33:24 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-04-27 21:33:24 +0000 |
commit | 4c018663b22cb439de81b6bbce13fe132ae06acb (patch) | |
tree | 9136431ad2b281c9b5567fdb430ed597d4f658b4 /clang/lib | |
parent | 0bc1293584cc02a83f57762098a9622f541f3b84 (diff) | |
download | bcm5719-llvm-4c018663b22cb439de81b6bbce13fe132ae06acb.tar.gz bcm5719-llvm-4c018663b22cb439de81b6bbce13fe132ae06acb.zip |
Track down return statements in the handlers of a function-try-block of constructors. Meh ...
llvm-svn: 70256
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 21 |
3 files changed, 28 insertions, 0 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 637804ce092..faaeb7989e5 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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. diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 482c304603b..7549c9c69cf 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.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; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 87a518b5583..71d2f80cfc4 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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); + } +} |