On Feb 22, 2012, at 2:50 AM, Sebastian Redl wrote: > Author: cornedbee > Date: Wed Feb 22 04:50:08 2012 > New Revision: 151155 > > URL: http://llvm.org/viewvc/llvm-project?rev=151155&view=rev > Log: > Fix parsing and processing initializer lists in return statements and as > direct member initializers.
Thanks! > Modified: > cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > cfe/trunk/lib/Parse/ParseStmt.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaStmt.cpp > cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp > cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp > cfe/trunk/test/SemaCXX/cxx0x-return-init-list.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Feb 22 04:50:08 > 2012 > @@ -223,10 +223,8 @@ > def warn_cxx98_compat_inline_namespace : Warning< > "inline namespaces are incompatible with C++98">, > InGroup<CXX98Compat>, DefaultIgnore; > -def err_generalized_initializer_lists : Error< > - "generalized initializer lists are a C++11 extension unsupported in > Clang">; > def ext_generalized_initializer_lists : ExtWarn< > - "generalized initializer lists are a C++11 extension unsupported in > Clang">, > + "generalized initializer lists are a C++11 extension">, > InGroup<CXX11>; > def warn_cxx98_compat_generalized_initializer_lists : Warning< > "generalized initializer lists are incompatible with C++98">, > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Feb 22 04:50:08 > 2012 > @@ -5057,6 +5057,9 @@ > DefaultError, InGroup<ReturnType>; > def ext_return_has_void_expr : Extension< > "void %select{function|method}1 %0 should not return void expression">; > +def err_return_init_list : Error< > + "%select{void function|void method|constructor|destructor}1 %0 " > + "must not return a value">; > def warn_noreturn_function_has_return_expr : Warning< > "function %0 declared 'noreturn' should not return">, > InGroup<DiagGroup<"invalid-noreturn">>; > > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Feb 22 04:50:08 2012 > @@ -2012,7 +2012,7 @@ > if (Init.isInvalid()) > SkipUntil(tok::comma, true, true); > else if (ThisDecl) > - Actions.AddInitializerToDecl(ThisDecl, Init.get(), false, > + Actions.AddInitializerToDecl(ThisDecl, Init.get(), > EqualLoc.isInvalid(), > DS.getTypeSpecType() == > DeclSpec::TST_auto); > } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) { > // No initializer. > @@ -2087,15 +2087,15 @@ > /// > /// pure-specifier: > /// '= 0' > -/// > +/// > /// brace-or-equal-initializer: > /// '=' initializer-expression > -/// braced-init-list [TODO] > -/// > +/// braced-init-list > +/// > /// initializer-clause: > /// assignment-expression > -/// braced-init-list [TODO] > -/// > +/// braced-init-list > +/// > /// defaulted/deleted function-definition: > > > > /// '=' 'default' > /// '=' 'delete' > @@ -2137,9 +2137,8 @@ > return ExprResult(); > } > > - return ParseInitializer(); > - } else > - return ExprError(Diag(Tok, diag::err_generalized_initializer_lists)); > + } > + return ParseInitializer(); > } > > /// ParseCXXMemberSpecification - Parse the class definition. > > Modified: cfe/trunk/lib/Parse/ParseStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseStmt.cpp (original) > +++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Feb 22 04:50:08 2012 > @@ -1597,9 +1597,6 @@ > return StmtError(); > } > > - // FIXME: This is a hack to allow something like C++0x's generalized > - // initializer lists, but only enough of this feature to allow Clang to > - // parse libstdc++ 4.5's headers. > if (Tok.is(tok::l_brace) && getLang().CPlusPlus) { > R = ParseInitializer(); > if (R.isUsable()) > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Feb 22 04:50:08 2012 > @@ -1640,12 +1640,17 @@ > 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; > > Modified: cfe/trunk/lib/Sema/SemaStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) > +++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Feb 22 04:50:08 2012 > @@ -1961,7 +1961,26 @@ > 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; I presume that you also want to drop the expression up in ActOnCapScopeReturnStmt (for blocks and lambdas), where we also have an InitListExpr check? > Modified: cfe/trunk/test/SemaCXX/cxx0x-return-init-list.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-return-init-list.cpp?rev=151155&r1=151154&r2=151155&view=diff > ============================================================================== > --- cfe/trunk/test/SemaCXX/cxx0x-return-init-list.cpp (original) > +++ cfe/trunk/test/SemaCXX/cxx0x-return-init-list.cpp Wed Feb 22 04:50:08 2012 > @@ -1,17 +1,15 @@ > // RUN: %clang_cc1 -fsyntax-only -verify %s > > -// This test checks for a teeny tiny subset of the functionality in > -// the C++11 generalized initializer lists feature, which happens to > -// be used in libstdc++ 4.5. We accept only this syntax so that Clang > -// can handle the libstdc++ 4.5 headers. > +// Test that a very basic variation of generalized initializer returns (that > +// required for libstdc++ 4.5) is supposed in C++98. s/supposed/supported. - Doug _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
