[PATCH] [PATCH] fixing clang crash when reading an anonymous field initializer from a PCH file

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu May 30 17:01:21 PDT 2013


Hi Yunzhong,

On May 30, 2013, at 10:29 AM, Yunzhong Gao <Yunzhong_Gao at playstation.sony.com> wrote:

> ygao added you to the CC list for the revision "[PATCH] fixing clang crash when reading an anonymous field initializer from a PCH file".
> 
> Hi,
> 
> This patch attempts to fix a clang crash when it tries to read in an anonymous field initializer from a PCH file. Here is a test case:
> 
> ```
> // RUN: clang -cc1 -x c++ -std=c++11 -emit-pch -o header.pch source.h
> // RUN: clang -cc1 -x c++ -std=c++11 -include-pch header.pch -fsyntax-only -emit-llvm -o - source.cpp
> //
> 
> // begin: source.h
> struct v_t { };
> 
> struct m_t
> {
>    struct { v_t v; }; // anonymous struct
>    m_t() { }
> };
> // end source.h
> 
> // begin source.cpp
> struct foo
> {
>    m_t *m;
>    void init(void);
> };
> 
> void foo::init()
> {
>    m = new m_t;
> }
> // end source.cpp
> ```
> 
> The cause of the problem is that there is no routine to create anonymous field initializers from a PCH file. The fix is to add the missing methods.
> 
> Changes in DeclCXX.h and DeclCXX.cpp implement the missing constructors and member functions for anonymous fields. Changes in ASTReader.cpp use the new function to create the initializer. Also adding a new test cxx-anonymous-struct.cpp.
> 
> Could someone review and commit the patch for me?

I committed a bit simpler fix in r182974.
The new constructors are not necessary because indirect members are not accompanied by indices.

Thanks!

> 
> Thanks, Gao.
> 
> http://llvm-reviews.chandlerc.com/D890
> 
> Files:
>  test/PCH/cxx-anonymous-struct.cpp
>  test/PCH/cxx-anonymous-struct.h
>  include/clang/AST/DeclCXX.h
>  lib/AST/DeclCXX.cpp
>  lib/Serialization/ASTReader.cpp
> 
> Index: test/PCH/cxx-anonymous-struct.cpp
> ===================================================================
> --- test/PCH/cxx-anonymous-struct.cpp
> +++ test/PCH/cxx-anonymous-struct.cpp
> @@ -0,0 +1,19 @@
> +// Test this without pch.
> +// RUN: %clang_cc1 -x c++ -std=c++11 -include %S/cxx-anonymous-struct.h -fsyntax-only -emit-llvm -o - %s
> +
> +// Test with pch.
> +// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t %S/cxx-anonymous-struct.h
> +// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s
> +
> +// Clang used to crash with anonymous struct in PCH files
> +
> +struct foo
> +{
> +    m_t *m;
> +    void init(void);
> +};
> +
> +void foo::init()
> +{
> +    m = new m_t;
> +}
> Index: test/PCH/cxx-anonymous-struct.h
> ===================================================================
> --- test/PCH/cxx-anonymous-struct.h
> +++ test/PCH/cxx-anonymous-struct.h
> @@ -0,0 +1,9 @@
> +// Header file for PCH test cxx-anonymous-struct.cpp
> +
> +struct v_t { };
> +
> +struct m_t
> +{
> +    struct { v_t v; }; // anonymous struct
> +    m_t() { }
> +};
> Index: include/clang/AST/DeclCXX.h
> ===================================================================
> --- include/clang/AST/DeclCXX.h
> +++ include/clang/AST/DeclCXX.h
> @@ -1787,6 +1787,10 @@
>                      SourceLocation MemberLoc, SourceLocation L, Expr *Init,
>                      SourceLocation R, VarDecl **Indices, unsigned NumIndices);
> 
> +  CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
> +                     SourceLocation MemberLoc, SourceLocation L, Expr *Init,
> +                     SourceLocation R, VarDecl **Indices, unsigned NumIndices);
> +
> public:
>   /// CXXCtorInitializer - Creates a new base-class initializer.
>   explicit
> @@ -1818,6 +1822,14 @@
>                                     Expr *Init, SourceLocation R,
>                                     VarDecl **Indices, unsigned NumIndices);
> 
> +  /// \brief Creates a new anonymous field initializer that optionally contains
> +  /// array indices used to describe an elementwise initialization.
> +  static CXXCtorInitializer *Create(ASTContext &Context,
> +                                    IndirectFieldDecl *Member,
> +                                    SourceLocation MemberLoc, SourceLocation L,
> +                                    Expr *Init, SourceLocation R,
> +                                    VarDecl **Indices, unsigned NumIndices);
> +
>   /// isBaseInitializer - Returns true when this initializer is
>   /// initializing a base class.
>   bool isBaseInitializer() const {
> Index: lib/AST/DeclCXX.cpp
> ===================================================================
> --- lib/AST/DeclCXX.cpp
> +++ lib/AST/DeclCXX.cpp
> @@ -1553,6 +1553,21 @@
>   memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
> }
> 
> +CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
> +                                       IndirectFieldDecl *Member,
> +                                       SourceLocation MemberLoc,
> +                                       SourceLocation L, Expr *Init,
> +                                       SourceLocation R,
> +                                       VarDecl **Indices,
> +                                       unsigned NumIndices)
> +  : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init), 
> +    LParenLoc(L), RParenLoc(R), IsVirtual(false),
> +    IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)
> +{
> +  VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);
> +  memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));
> +}
> +
> CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
>                                                FieldDecl *Member, 
>                                                SourceLocation MemberLoc,
> @@ -1567,6 +1582,20 @@
>                                       Indices, NumIndices);
> }
> 
> +CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,
> +                                               IndirectFieldDecl *Member, 
> +                                               SourceLocation MemberLoc,
> +                                               SourceLocation L, Expr *Init,
> +                                               SourceLocation R,
> +                                               VarDecl **Indices,
> +                                               unsigned NumIndices) {
> +  void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +
> +                               sizeof(VarDecl *) * NumIndices,
> +                               llvm::alignOf<CXXCtorInitializer>());
> +  return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,
> +                                      Indices, NumIndices);
> +}
> +
> TypeLoc CXXCtorInitializer::getBaseClassLoc() const {
>   if (isBaseInitializer())
>     return Initializee.get<TypeSourceInfo*>()->getTypeLoc();
> Index: lib/Serialization/ASTReader.cpp
> ===================================================================
> --- lib/Serialization/ASTReader.cpp
> +++ lib/Serialization/ASTReader.cpp
> @@ -6993,9 +6993,16 @@
>                                                MemberOrEllipsisLoc, LParenLoc,
>                                                Init, RParenLoc);
>       } else {
> -        BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,
> -                                             LParenLoc, Init, RParenLoc,
> -                                             Indices.data(), Indices.size());
> +        if (Member)
> +          BOMInit = CXXCtorInitializer::Create(Context, Member,
> +                                               MemberOrEllipsisLoc,
> +                                               LParenLoc, Init, RParenLoc,
> +                                               Indices.data(), Indices.size());
> +        else
> +          BOMInit = CXXCtorInitializer::Create(Context, IndirectMember,
> +                                               MemberOrEllipsisLoc,
> +                                               LParenLoc, Init, RParenLoc,
> +                                               Indices.data(), Indices.size());
>       }
> 
>       if (IsWritten)
> <Mail Attachment>_______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130530/32a6bf91/attachment.html>


More information about the cfe-commits mailing list