Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ ELF/Symbols.cpp @@ -112,10 +112,16 @@ return std::min(VA, VB); } +static int compareCommons(DefinedCommon* A, DefinedCommon* B) { + if (A->Size < B->Size) + return -compareCommons(B, A); + A->MaxAlignment = std::max(A->MaxAlignment, B->MaxAlignment); + return 1; +} + // Returns 1, 0 or -1 if this symbol should take precedence // over the Other, tie or lose, respectively. template int SymbolBody::compare(SymbolBody *Other) { - typedef typename ELFFile::uintX_t uintX_t; assert(!isLazy() && !Other->isLazy()); std::tuple L(isDefined(), !isShared(), !isWeak()); std::tuple R(Other->isDefined(), !Other->isShared(), @@ -140,24 +146,14 @@ if (L != R) return -1; - if (!std::get<0>(L) || !std::get<1>(L) || !std::get<2>(L)) + if (!isDefined() || isShared() || isWeak()) return 1; - if (isCommon()) { - if (!Other->isCommon()) - return -1; - auto *ThisC = cast(this); - auto *OtherC = cast(Other); - uintX_t Align = std::max(ThisC->MaxAlignment, OtherC->MaxAlignment); - if (ThisC->Size >= OtherC->Size) { - ThisC->MaxAlignment = Align; - return 1; - } - OtherC->MaxAlignment = Align; - return -1; - } - if (Other->isCommon()) - return 1; - return 0; + if (!isCommon() && !Other->isCommon()) + return 0; + if (isCommon() && Other->isCommon()) + return compareCommons(cast(this), + cast(Other)); + return isCommon() ? -1 : 1; } Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,