<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>Hi Yunzhong,</div><br><div><div>On May 30, 2013, at 10:29 AM, Yunzhong Gao <<a href="mailto:Yunzhong_Gao@playstation.sony.com">Yunzhong_Gao@playstation.sony.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;">ygao added you to the CC list for the revision "[PATCH] fixing clang crash when reading an anonymous field initializer from a PCH file".<br><br>Hi,<br><br>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:<br><br>```<br>// RUN: clang -cc1 -x c++ -std=c++11 -emit-pch -o header.pch source.h<br>// RUN: clang -cc1 -x c++ -std=c++11 -include-pch header.pch -fsyntax-only -emit-llvm -o - source.cpp<br>//<br><br>// begin: source.h<br>struct v_t { };<br><br>struct m_t<br>{<br> struct { v_t v; }; // anonymous struct<br> m_t() { }<br>};<br>// end source.h<br><br>// begin source.cpp<br>struct foo<br>{<br> m_t *m;<br> void init(void);<br>};<br><br>void foo::init()<br>{<br> m = new m_t;<br>}<br>// end source.cpp<br>```<br><br>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.<br><br>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.<br><br>Could someone review and commit the patch for me?<br></div></blockquote><div><br></div><div>I committed a bit simpler fix in r182974.</div><div>The new constructors are not necessary because indirect members are not accompanied by indices.</div><div><br></div><div>Thanks!</div><br><blockquote type="cite"><div style="letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><br>Thanks, Gao.<br><br><a href="http://llvm-reviews.chandlerc.com/D890">http://llvm-reviews.chandlerc.com/D890</a><br><br>Files:<br> test/PCH/cxx-anonymous-struct.cpp<br> test/PCH/cxx-anonymous-struct.h<br> include/clang/AST/DeclCXX.h<br> lib/AST/DeclCXX.cpp<br> lib/Serialization/ASTReader.cpp<br><br>Index: test/PCH/cxx-anonymous-struct.cpp<br>===================================================================<br>--- test/PCH/cxx-anonymous-struct.cpp<br>+++ test/PCH/cxx-anonymous-struct.cpp<br>@@ -0,0 +1,19 @@<br>+// Test this without pch.<br>+// RUN: %clang_cc1 -x c++ -std=c++11 -include %S/cxx-anonymous-struct.h -fsyntax-only -emit-llvm -o - %s<br>+<br>+// Test with pch.<br>+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t %S/cxx-anonymous-struct.h<br>+// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t -fsyntax-only -emit-llvm -o - %s<br>+<br>+// Clang used to crash with anonymous struct in PCH files<br>+<br>+struct foo<br>+{<br>+ m_t *m;<br>+ void init(void);<br>+};<br>+<br>+void foo::init()<br>+{<br>+ m = new m_t;<br>+}<br>Index: test/PCH/cxx-anonymous-struct.h<br>===================================================================<br>--- test/PCH/cxx-anonymous-struct.h<br>+++ test/PCH/cxx-anonymous-struct.h<br>@@ -0,0 +1,9 @@<br>+// Header file for PCH test cxx-anonymous-struct.cpp<br>+<br>+struct v_t { };<br>+<br>+struct m_t<br>+{<br>+ struct { v_t v; }; // anonymous struct<br>+ m_t() { }<br>+};<br>Index: include/clang/AST/DeclCXX.h<br>===================================================================<br>--- include/clang/AST/DeclCXX.h<br>+++ include/clang/AST/DeclCXX.h<br>@@ -1787,6 +1787,10 @@<br> SourceLocation MemberLoc, SourceLocation L, Expr *Init,<br> SourceLocation R, VarDecl **Indices, unsigned NumIndices);<br><br>+ CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,<br>+ SourceLocation MemberLoc, SourceLocation L, Expr *Init,<br>+ SourceLocation R, VarDecl **Indices, unsigned NumIndices);<br>+<br>public:<br> /// CXXCtorInitializer - Creates a new base-class initializer.<br> explicit<br>@@ -1818,6 +1822,14 @@<br> Expr *Init, SourceLocation R,<br> VarDecl **Indices, unsigned NumIndices);<br><br>+ /// \brief Creates a new anonymous field initializer that optionally contains<br>+ /// array indices used to describe an elementwise initialization.<br>+ static CXXCtorInitializer *Create(ASTContext &Context,<br>+ IndirectFieldDecl *Member,<br>+ SourceLocation MemberLoc, SourceLocation L,<br>+ Expr *Init, SourceLocation R,<br>+ VarDecl **Indices, unsigned NumIndices);<br>+<br> /// isBaseInitializer - Returns true when this initializer is<br> /// initializing a base class.<br> bool isBaseInitializer() const {<br>Index: lib/AST/DeclCXX.cpp<br>===================================================================<br>--- lib/AST/DeclCXX.cpp<br>+++ lib/AST/DeclCXX.cpp<br>@@ -1553,6 +1553,21 @@<br> memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));<br>}<br><br>+CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,<br>+ IndirectFieldDecl *Member,<br>+ SourceLocation MemberLoc,<br>+ SourceLocation L, Expr *Init,<br>+ SourceLocation R,<br>+ VarDecl **Indices,<br>+ unsigned NumIndices)<br>+ : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),<span class="Apple-converted-space"> </span><br>+ LParenLoc(L), RParenLoc(R), IsVirtual(false),<br>+ IsWritten(false), SourceOrderOrNumArrayIndices(NumIndices)<br>+{<br>+ VarDecl **MyIndices = reinterpret_cast<VarDecl **> (this + 1);<br>+ memcpy(MyIndices, Indices, NumIndices * sizeof(VarDecl *));<br>+}<br>+<br>CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,<br> FieldDecl *Member,<span class="Apple-converted-space"> </span><br> SourceLocation MemberLoc,<br>@@ -1567,6 +1582,20 @@<br> Indices, NumIndices);<br>}<br><br>+CXXCtorInitializer *CXXCtorInitializer::Create(ASTContext &Context,<br>+ IndirectFieldDecl *Member,<span class="Apple-converted-space"> </span><br>+ SourceLocation MemberLoc,<br>+ SourceLocation L, Expr *Init,<br>+ SourceLocation R,<br>+ VarDecl **Indices,<br>+ unsigned NumIndices) {<br>+ void *Mem = Context.Allocate(sizeof(CXXCtorInitializer) +<br>+ sizeof(VarDecl *) * NumIndices,<br>+ llvm::alignOf<CXXCtorInitializer>());<br>+ return new (Mem) CXXCtorInitializer(Context, Member, MemberLoc, L, Init, R,<br>+ Indices, NumIndices);<br>+}<br>+<br>TypeLoc CXXCtorInitializer::getBaseClassLoc() const {<br> if (isBaseInitializer())<br> return Initializee.get<TypeSourceInfo*>()->getTypeLoc();<br>Index: lib/Serialization/ASTReader.cpp<br>===================================================================<br>--- lib/Serialization/ASTReader.cpp<br>+++ lib/Serialization/ASTReader.cpp<br>@@ -6993,9 +6993,16 @@<br> MemberOrEllipsisLoc, LParenLoc,<br> Init, RParenLoc);<br> } else {<br>- BOMInit = CXXCtorInitializer::Create(Context, Member, MemberOrEllipsisLoc,<br>- LParenLoc, Init, RParenLoc,<br>- Indices.data(), Indices.size());<br>+ if (Member)<br>+ BOMInit = CXXCtorInitializer::Create(Context, Member,<br>+ MemberOrEllipsisLoc,<br>+ LParenLoc, Init, RParenLoc,<br>+ Indices.data(), Indices.size());<br>+ else<br>+ BOMInit = CXXCtorInitializer::Create(Context, IndirectMember,<br>+ MemberOrEllipsisLoc,<br>+ LParenLoc, Init, RParenLoc,<br>+ Indices.data(), Indices.size());<br> }<br><br> if (IsWritten)<br><span><Mail Attachment></span>_______________________________________________<br>cfe-commits mailing list<br><a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br></div></blockquote></div><br></body></html>