[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