From 842e46e606b13e29b4136a455ad5d77249a7f9f4 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 26 Oct 2016 02:31:56 +0000 Subject: [PATCH] [modules] Fix assert if multiple update records provide a definition for a class template specialization and that specialization has attributes. llvm-svn: 285160 --- clang/lib/Serialization/ASTReaderDecl.cpp | 5 ++++- clang/test/Modules/Inputs/templates-left.h | 2 ++ clang/test/Modules/Inputs/templates-right.h | 2 ++ clang/test/Modules/Inputs/templates-top.h | 5 +++++ clang/test/Modules/templates.mm | 7 ++++++- 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 94097cd..07df754 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -3930,7 +3930,10 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile, if (Record[Idx++]) { AttrVec Attrs; Reader.ReadAttributes(F, Attrs, Record, Idx); - D->setAttrsImpl(Attrs, Reader.getContext()); + // If the declaration already has attributes, we assume that some other + // AST file already loaded them. + if (!D->hasAttrs()) + D->setAttrsImpl(Attrs, Reader.getContext()); } break; } diff --git a/clang/test/Modules/Inputs/templates-left.h b/clang/test/Modules/Inputs/templates-left.h index cbe8943..4f7abee 100644 --- a/clang/test/Modules/Inputs/templates-left.h +++ b/clang/test/Modules/Inputs/templates-left.h @@ -70,3 +70,5 @@ namespace EmitDefaultedSpecialMembers { inline int *getStaticDataMemberLeft() { return WithUndefinedStaticDataMember::undefined; } + +inline WithAttributes make_with_attributes_left() { return WithAttributes(); } diff --git a/clang/test/Modules/Inputs/templates-right.h b/clang/test/Modules/Inputs/templates-right.h index 32487c6..bb3f7c3 100644 --- a/clang/test/Modules/Inputs/templates-right.h +++ b/clang/test/Modules/Inputs/templates-right.h @@ -51,3 +51,5 @@ void outOfLineInlineUseRightH(void (OutOfLineInline::*)() = &OutOfLineInlin inline int *getStaticDataMemberRight() { return WithUndefinedStaticDataMember::undefined; } + +inline WithAttributes make_with_attributes_right() { return WithAttributes(); } diff --git a/clang/test/Modules/Inputs/templates-top.h b/clang/test/Modules/Inputs/templates-top.h index a082683..207d705 100644 --- a/clang/test/Modules/Inputs/templates-top.h +++ b/clang/test/Modules/Inputs/templates-top.h @@ -58,3 +58,8 @@ namespace EmitDefaultedSpecialMembers { template struct WithUndefinedStaticDataMember { static T undefined; }; + +template struct __attribute__((packed, aligned(2))) WithAttributes { + T value; +}; +WithAttributes *get_with_attributes(); diff --git a/clang/test/Modules/templates.mm b/clang/test/Modules/templates.mm index cd80e24..79e975a 100644 --- a/clang/test/Modules/templates.mm +++ b/clang/test/Modules/templates.mm @@ -116,4 +116,9 @@ void testStaticDataMember() { (void) getStaticDataMemberRight(); } - +void testWithAttributes() { + auto a = make_with_attributes_left(); + auto b = make_with_attributes_right(); + static_assert(alignof(decltype(a)) == 2, ""); + static_assert(alignof(decltype(b)) == 2, ""); +} -- 2.7.4