diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2016-02-18 21:05:09 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2016-02-18 21:05:09 +0000 |
commit | b85dafb9b7bee1e51a4f86d8e7e5af054b96b3f8 (patch) | |
tree | 17a15cce4e4a02b64e47dbf0e3eab2ebed5dc06a | |
parent | f6d27b56caec0848f19c367b5e5b9718eee0263f (diff) | |
download | clang-b85dafb9b7bee1e51a4f86d8e7e5af054b96b3f8.tar.gz |
[Sema] Fix bug in TypeLocBuilder::pushImpl
The code in TypeLocBuilder::pushImpl wasn't correctly handling the case
where an element that has an 8-byte alignment was being pushed.
I plan to follow up with a patch to remove redundancies and simplify the
function.
rdar://problem/23838912
Differential Revision: http://reviews.llvm.org/D16843
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261260 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/TypeLocBuilder.cpp | 36 | ||||
-rw-r--r-- | test/SemaObjCXX/typeloc-data-alignment.mm | 12 |
2 files changed, 44 insertions, 4 deletions
diff --git a/lib/Sema/TypeLocBuilder.cpp b/lib/Sema/TypeLocBuilder.cpp index be995400df..340b7fae78 100644 --- a/lib/Sema/TypeLocBuilder.cpp +++ b/lib/Sema/TypeLocBuilder.cpp @@ -115,11 +115,39 @@ TypeLoc TypeLocBuilder::pushImpl(QualType T, size_t LocalSize, unsigned LocalAli 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 (NumBytesAtAlign8 == 0) { + // We have not seen any 8-byte aligned element yet. We insert a padding + // only if the new Index is not 8-byte-aligned. + if ((Index - LocalSize) % 8 != 0) { + memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); + Index -= 4; + } + } else { + unsigned Padding = NumBytesAtAlign4 % 8; + if (Padding == 0) { + if (LocalSize % 8 == 0) { + // Everything is set: there's no padding and we don't need to add + // any. + } else { + assert(LocalSize % 8 == 4); + // No existing padding; add in 4 bytes padding + memmove(&Buffer[Index - 4], &Buffer[Index], NumBytesAtAlign4); + Index -= 4; + } + } else { + assert(Padding == 4); + if (LocalSize % 8 == 0) { + // Everything is set: there's 4 bytes padding and we don't need + // to add any. + } else { + assert(LocalSize % 8 == 4); + // There are 4 bytes padding, but we don't need any; remove it. + memmove(&Buffer[Index + 4], &Buffer[Index], NumBytesAtAlign4); + Index += 4; + } + } } + // Forget about any padding. NumBytesAtAlign4 = 0; NumBytesAtAlign8 += LocalSize; diff --git a/test/SemaObjCXX/typeloc-data-alignment.mm b/test/SemaObjCXX/typeloc-data-alignment.mm new file mode 100644 index 0000000000..e17a910a60 --- /dev/null +++ b/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 <class T> +id<P> foo(T) { + int i; + foo(i); +} |