<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>Fixed in r177330, thanks for the report and the investigation!</div><div><br></div><div>-Argyrios</div><br><div><div>On Feb 26, 2013, at 7:16 PM, Tom Honermann <<a href="mailto:thonermann@coverity.com">thonermann@coverity.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-size-adjust: auto; -webkit-text-stroke-width: 0px;">The following code causes Clang (3.2 on Linux) to fail an assertion test when serializing an AST to an AST file.<br><br>template<typename T><br>void f() {<br> enum E {<br>   enumerator<br> };<br><br> T t = enumerator;<br>}<br><br>template void f<int>();<br><br>$ clang -c t.cpp<br><no error, object file is generated successfully><br><br>$ clang -emit-ast t.cpp<br>clang: /nfs/thonermann/clang-3.2/llvm-3.2/include/llvm/Bitcode/BitstreamWriter.h:398: void llvm::BitstreamWriter::EmitRecordWithAbbrevImpl(unsigned int, llvm::SmallVectorImpl<T>&, llvm::StringRef) [with uintty = long unsigned int]: Assertion `RecordIdx == Vals.size() && "Not all record operands emitted!"' failed.<br>clang: error: unable to execute command: Segmentation fault (core dumped)<br>clang: error: clang frontend command failed due to signal (use -v to see invocation)<br>clang version 3.2 (tags/RELEASE_32/final)<br>Target: x86_64-unknown-linux-gnu<br>Thread model: posix<br>clang: note: diagnostic msg: PLEASE submit a bug report to<span class="Apple-converted-space"> </span><a href="http://llvm.org/bugs/">http://llvm.org/bugs/</a><span class="Apple-converted-space"> </span>and include the crash backtrace, preprocessed source, and associated run script.<br>clang: note: diagnostic msg:<br>********************<br><br>PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:<br>Preprocessed source(s) and associated run script(s) are located at:<br>clang: note: diagnostic msg: /tmp/t-dqKSIG.cpp<br>clang: note: diagnostic msg: /tmp/t-dqKSIG.sh<br>clang: note: diagnostic msg:<br><br>********************<br><br>/tmp/t-dqKSIG.cpp contains the sample code above.<br>/tmp/t-dqKSIG.sh contains:<br>/path/to/clang -cc1 -triple x86_64-unknown-linux-gnu -emit-pch -disable-free -main-file-name t.cpp -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-linker-version 2.22 -momit-leaf-frame-pointer -fdeprecated-macro -ferror-limit 19 -fmessage-length 197 -mstackrealign -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -x c++ t-dqKSIG.cpp<br><br>This assertion failure (with a different test case) was previously reported here:<br> <a href="http://llvm.org/bugs/show_bug.cgi?id=13020">http://llvm.org/bugs/show_bug.cgi?id=13020</a><br> Bug 13020 - Clang 3.1 assertion failures reading and writing AST files<br><br>The assertion failure occurs at line 398 below:<br><br>include/llvm/Bitcode/BitstreamWriter.h:<br>25 class BitstreamWriter {<br>...<br>313   template<typename uintty><br>314   void EmitRecordWithAbbrevImpl(unsigned Abbrev, SmallVectorImpl<uintty> &Vals,<br>315                                 StringRef Blob) {<br>...<br>398     assert(RecordIdx == Vals.size() && "Not all record operands emitted!");<br>399     assert(BlobData == 0 &&<br>400            "Blob data specified for record that doesn't use it!");<br>401   }<br><br>The problem is that ASTDeclWriter::VisitEnumDecl() in lib/Serialization/ASTWriterDecl.cpp incorrectly determines that the abbreviated form of the EnumDecl bit stream can be used when serializing the enum member declaration of the f<int> specialization and ends up passing more operands than are expected for the abbreviation.<br><br>The problematic code is here:<br><br>lib/Serialization/ASTWriterDecl.cpp:<br>224 void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {<br>...<br>235   if (MemberSpecializationInfo *MemberInfo = D->getMemberSpecializationInfo()) {<br>236     Writer.AddDeclRef(MemberInfo->getInstantiatedFrom(), Record);<br>237     Record.push_back(MemberInfo->getTemplateSpecializationKind());<br>238 Writer.AddSourceLocation(MemberInfo->getPointOfInstantiation(), Record);<br>239   } else {<br>240     Writer.AddDeclRef(0, Record);<br>241   }<br>242<br>243   if (!D->hasAttrs() &&<br>244       !D->isImplicit() &&<br>245       !D->isUsed(false) &&<br>246       !D->hasExtInfo() &&<br>247       D->getFirstDeclaration() == D->getMostRecentDecl() &&<br>248       !D->isInvalidDecl() &&<br>249       !D->isReferenced() &&<br>250       !D->isTopLevelDeclInObjCContainer() &&<br>251       D->getAccess() == AS_none &&<br>252       !D->isModulePrivate() &&<br>253       !CXXRecordDecl::classofKind(D->getKind()) &&<br>254       !D->getIntegerTypeSourceInfo() &&<br>255       D->getDeclName().getNameKind() == DeclarationName::Identifier &&<br>256       !D->getMemberSpecializationInfo())<br>257     AbbrevToUse = Writer.getDeclEnumAbbrev();<br>258<br>259   Code = serialization::DECL_ENUM;<br>260 }<br><br>Lines 235-241 will queue a conditional number of record operands depending on whether the declaration has member specialization info. The abbreviated bit stream expects just one (matching the else body). Adding a check for '!D->getMemberSpecializationInfo()' to the if conditions at lines 243-256 above appears to correct this problem:<br><br>@@ -252,7 +252,8 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {<br>      !D->isModulePrivate() &&<br>      !CXXRecordDecl::classofKind(D->getKind()) &&<br>      !D->getIntegerTypeSourceInfo() &&<br>-      D->getDeclName().getNameKind() == DeclarationName::Identifier)<br>+      D->getDeclName().getNameKind() == DeclarationName::Identifier &&<br>+      !D->getMemberSpecializationInfo())<br>    AbbrevToUse = Writer.getDeclEnumAbbrev();<br><br>For reference, here is the corresponding code to build the enum declaration abbreviation that matches the else body at line 240 above.<br><br>lib/Serialization/ASTWriterDecl.cpp:<br>1300 void ASTWriter::WriteDeclsBlockAbbrevs() {<br>....<br>1372   // Abbreviation for DECL_ENUM<br>1373   Abv = new BitCodeAbbrev();<br>....<br>1413   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6));   // InstantiatedMembEnum<br>....<br>1650 }<br><br>Tom.<br><br>_______________________________________________<br>cfe-dev mailing list<br><a href="mailto:cfe-dev@cs.uiuc.edu">cfe-dev@cs.uiuc.edu</a><br><a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a></div></blockquote></div><br></body></html>