--- Merging r74056 into '.':
U    gcc/llvm-convert.cpp

Fix an array over-read problem that would sometimes manifest as a crash (when overreading
a string would point to invalid data.  The issue here is that TREE_STRING_LENGTH returns
the length in bytes of a string, not in characters.  This is different for a wide string.

In cases when this didn't crash, this bug would not manifest as a codegen problem, because
the code right below the overread would trim the length of the generated vector to the 
right length.

This fixes rdar://6961178

llvm-svn: 74061
diff --git a/llvm-gcc-4.2/gcc/llvm-convert.cpp b/llvm-gcc-4.2/gcc/llvm-convert.cpp
index 9a378e8..fcd1d2b 100644
--- a/llvm-gcc-4.2/gcc/llvm-convert.cpp
+++ b/llvm-gcc-4.2/gcc/llvm-convert.cpp
@@ -6544,13 +6544,17 @@
     for (unsigned i = 0; i != Len; ++i)
       Elts.push_back(ConstantInt::get(Type::Int8Ty, InStr[i]));
   } else if (ElTy == Type::Int16Ty) {
+    assert((Len&1) == 0 &&
+           "Length in bytes should be a multiple of element size");
     const unsigned short *InStr =
       (const unsigned short *)TREE_STRING_POINTER(exp);
-    for (unsigned i = 0; i != Len; ++i)
+    for (unsigned i = 0; i != Len/2; ++i)
       Elts.push_back(ConstantInt::get(Type::Int16Ty, InStr[i]));
   } else if (ElTy == Type::Int32Ty) {
+    assert((Len&3) == 0 &&
+           "Length in bytes should be a multiple of element size");
     const unsigned *InStr = (const unsigned *)TREE_STRING_POINTER(exp);
-    for (unsigned i = 0; i != Len; ++i)
+    for (unsigned i = 0; i != Len/4; ++i)
       Elts.push_back(ConstantInt::get(Type::Int32Ty, InStr[i]));
   } else {
     assert(0 && "Unknown character type!");