[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