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