diff options
| author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-22 10:50:08 +0000 |
|---|---|---|
| committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2012-02-22 10:50:08 +0000 |
| commit | eef474ce1bc865d3192bc335f966ad5ae9efd5a1 (patch) | |
| tree | 131677639806223d4b2a1db272e06411bed33065 /clang/lib/Sema | |
| parent | c9dd94685283938a2d9227a0fa448f08d7b19ab4 (diff) | |
| download | bcm5719-llvm-eef474ce1bc865d3192bc335f966ad5ae9efd5a1.tar.gz bcm5719-llvm-eef474ce1bc865d3192bc335f966ad5ae9efd5a1.zip | |
Fix parsing and processing initializer lists in return statements and as direct member initializers.
llvm-svn: 151155
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 13 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 27 |
2 files changed, 33 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 22fb8cb7a83..c5215c016c5 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1640,12 +1640,17 @@ Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation EqualLoc, ExprResult Init = InitExpr; if (!FD->getType()->isDependentType() && !InitExpr->isTypeDependent()) { if (isa<InitListExpr>(InitExpr) && isStdInitializerList(FD->getType(), 0)) { - Diag(FD->getLocation(), diag::warn_dangling_std_initializer_list) + Diag(FD->getLocation(), diag::warn_dangling_std_initializer_list) << /*at end of ctor*/1 << InitExpr->getSourceRange(); } - // FIXME: if there is no EqualLoc, this is list-initialization. - Init = PerformCopyInitialization( - InitializedEntity::InitializeMember(FD), EqualLoc, InitExpr); + Expr **Inits = &InitExpr; + unsigned NumInits = 1; + InitializedEntity Entity = InitializedEntity::InitializeMember(FD); + InitializationKind Kind = EqualLoc.isInvalid() + ? InitializationKind::CreateDirectList(InitExpr->getLocStart()) + : InitializationKind::CreateCopy(InitExpr->getLocStart(), EqualLoc); + InitializationSequence Seq(*this, Entity, Kind, Inits, NumInits); + Init = Seq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); if (Init.isInvalid()) { FD->setInvalidDecl(); return; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index afbabacc73b..a2dda0201ba 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1961,7 +1961,26 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ReturnStmt *Result = 0; if (FnRetType->isVoidType()) { if (RetValExp) { - if (!RetValExp->isTypeDependent()) { + if (isa<InitListExpr>(RetValExp)) { + // We simply never allow init lists as the return value of void + // functions. This is compatible because this was never allowed before, + // so there's no legacy code to deal with. + NamedDecl *CurDecl = getCurFunctionOrMethodDecl(); + int FunctionKind = 0; + if (isa<ObjCMethodDecl>(CurDecl)) + FunctionKind = 1; + else if (isa<CXXConstructorDecl>(CurDecl)) + FunctionKind = 2; + else if (isa<CXXDestructorDecl>(CurDecl)) + FunctionKind = 3; + + Diag(ReturnLoc, diag::err_return_init_list) + << CurDecl->getDeclName() << FunctionKind + << RetValExp->getSourceRange(); + + // Drop the expression. + RetValExp = 0; + } else if (!RetValExp->isTypeDependent()) { // C99 6.8.6.4p1 (ext_ since GCC warns) unsigned D = diag::ext_return_has_expr; if (RetValExp->getType()->isVoidType()) @@ -1995,8 +2014,10 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } } - CheckImplicitConversions(RetValExp, ReturnLoc); - RetValExp = MaybeCreateExprWithCleanups(RetValExp); + if (RetValExp) { + CheckImplicitConversions(RetValExp, ReturnLoc); + RetValExp = MaybeCreateExprWithCleanups(RetValExp); + } } Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0); |

