Index: lib/Sema/TypeLocBuilder.cpp =================================================================== --- lib/Sema/TypeLocBuilder.cpp +++ lib/Sema/TypeLocBuilder.cpp @@ -115,11 +115,28 @@ NumBytesAtAlign4 += LocalSize; } } else if (LocalAlignment == 8) { - if (!NumBytesAtAlign8 && NumBytesAtAlign4 % 8 != 0) { - // No existing padding and misaligned members; add in 4 bytes padding - memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); - Index -= 4; + // If the new index is not aligned on an 8-byte boundary, adjust the + // current index. + bool AdjustIndex = (Index - LocalSize) % 8; + + if (AdjustIndex) { + bool CurrentlyHasPadding = NumBytesAtAlign8 && NumBytesAtAlign4 % 8; + + if (NumBytesAtAlign4 == 0) + // No 4-byte elements were inserted since the last 8-byte aligned + // element was inserted. Just adjust Index. + Index -= 4; + else if (CurrentlyHasPadding) { + // Remove 4-byte padding. + memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4); + Index += 4; + } else { + // Insert 4-byte padding. + memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); + Index -= 4; + } } + // Forget about any padding. NumBytesAtAlign4 = 0; NumBytesAtAlign8 += LocalSize; Index: test/SemaObjCXX/typeloc-data-alignment.mm =================================================================== --- /dev/null +++ test/SemaObjCXX/typeloc-data-alignment.mm @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +// Make sure this doesn't crash. + +@protocol P +@end +template +id

foo(T) { + int i; + foo(i); +}