<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>