[cfe-commits] r151155 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseStmt.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaStmt.cpp test/SemaCXX/cxx0x-initializer-constructor.cpp test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp test/SemaCXX/cxx0x-return-init-list.cpp
Douglas Gregor
dgregor at apple.com
Wed Feb 22 08:16:37 PST 2012
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
More information about the cfe-commits
mailing list