]> granicus.if.org Git - clang/commitdiff
Merging r243945-243950.
authorHans Wennborg <hans@hanshq.net>
Thu, 6 Aug 2015 15:53:49 +0000 (15:53 +0000)
committerHans Wennborg <hans@hanshq.net>
Thu, 6 Aug 2015 15:53:49 +0000 (15:53 +0000)
------------------------------------------------------------------------
r243945 | chandlerc | 2015-08-03 20:52:52 -0700 (Mon, 03 Aug 2015) | 5 lines

[UB] Fix two cases of UB in copy/pasted code from SmallVector.

We should really stop copying and pasting code around. =/

Found by UBSan.
------------------------------------------------------------------------

------------------------------------------------------------------------
r243946 | chandlerc | 2015-08-03 20:52:56 -0700 (Mon, 03 Aug 2015) | 9 lines

[UB] Fix the two ways that we would try to memcpy from a null buffer in
the nested name specifier code.

First, skip the entire thing when the input is empty.

Next, handle the case where we started off with a null buffer and a zero
capacity to skip copying and freeing.

This was found with UBSan.
------------------------------------------------------------------------

------------------------------------------------------------------------
r243947 | chandlerc | 2015-08-03 20:52:58 -0700 (Mon, 03 Aug 2015) | 4 lines

[UB] When attaching empty strings to the AST, use an empty StringRef
rather than forcing the bump pointer allocator to produce a viable
pointer. This also fixes UB when we would try to memcpy from the null
incoming StringRef.
------------------------------------------------------------------------

------------------------------------------------------------------------
r243948 | chandlerc | 2015-08-03 20:53:00 -0700 (Mon, 03 Aug 2015) | 9 lines

[UB] Another place where we were trying to put string data into
a BumpPtrAllocator. This at least now handles the case where there is no
concatentation without calling memcpy on a null pointer. It might be
interesting to handle the case where everything is empty without
round-tripping through the allocator, but it wasn't clear to me if the
pointer returned is significant in any way, so I've left it in
a conservatively more-correct state.

Again, found with UBSan.
------------------------------------------------------------------------

------------------------------------------------------------------------
r243949 | chandlerc | 2015-08-03 20:53:01 -0700 (Mon, 03 Aug 2015) | 4 lines

[UB] Guard two calls to memcpy in generated attribute code to handle
null StringRef objects as inputs.

Found by UBSan.
------------------------------------------------------------------------

------------------------------------------------------------------------
r243950 | chandlerc | 2015-08-03 20:53:04 -0700 (Mon, 03 Aug 2015) | 8 lines

[UB] Avoid a really broken call to realloc that would later result in
a bad call to memcpy.

When we only have a buffer from one of the two reparse calls, we can
just return that buffer rather than going through the realloc/memcpy
dance.

Found with UBsan.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_37@244223 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTVector.h
include/clang/Analysis/Support/BumpVector.h
lib/AST/NestedNameSpecifier.cpp
lib/AST/Stmt.cpp
lib/CodeGen/CGDebugInfo.h
tools/c-index-test/c-index-test.c
utils/TableGen/ClangAttrEmitter.cpp

index 6ec054582e263452c7b8c10cc8f0bb6c3f5f3ae3..79453bf10871a00619ce4c59f6f5e2206db7e868 100644 (file)
@@ -384,14 +384,15 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
   T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
 
   // Copy the elements over.
-  if (std::is_class<T>::value) {
-    std::uninitialized_copy(Begin, End, NewElts);
-    // Destroy the original elements.
-    destroy_range(Begin, End);
-  }
-  else {
-    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
-    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  if (Begin != End) {
+    if (std::is_class<T>::value) {
+      std::uninitialized_copy(Begin, End, NewElts);
+      // Destroy the original elements.
+      destroy_range(Begin, End);
+    } else {
+      // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+      memcpy(NewElts, Begin, CurSize * sizeof(T));
+    }
   }
 
   // ASTContext never frees any memory.
index 841adf64557dab68d429d07372fdc65468575fa3..3abe32d79cce46030f38217e206f5cad879510b0 100644 (file)
@@ -223,14 +223,15 @@ void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) {
   T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity);
   
   // Copy the elements over.
-  if (std::is_class<T>::value) {
-    std::uninitialized_copy(Begin, End, NewElts);
-    // Destroy the original elements.
-    destroy_range(Begin, End);
-  }
-  else {
-    // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
-    memcpy(NewElts, Begin, CurSize * sizeof(T));
+  if (Begin != End) {
+    if (std::is_class<T>::value) {
+      std::uninitialized_copy(Begin, End, NewElts);
+      // Destroy the original elements.
+      destroy_range(Begin, End);
+    } else {
+      // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+      memcpy(NewElts, Begin, CurSize * sizeof(T));
+    }
   }
 
   // For now, leak 'Begin'.  We can add it back to a freelist in
index 50a00502ca9fcace9f5cc949ac99152517161a60..97425d001de0921ef30f5a4d44bb75b2071789fd 100644 (file)
@@ -435,17 +435,19 @@ TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
 namespace {
   void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
               unsigned &BufferCapacity) {
+    if (Start == End)
+      return;
+
     if (BufferSize + (End - Start) > BufferCapacity) {
       // Reallocate the buffer.
-      unsigned NewCapacity 
-      = std::max((unsigned)(BufferCapacity? BufferCapacity * 2 
-                            : sizeof(void*) * 2),
-                 (unsigned)(BufferSize + (End - Start)));
+      unsigned NewCapacity = std::max(
+          (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
+          (unsigned)(BufferSize + (End - Start)));
       char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
-      memcpy(NewBuffer, Buffer, BufferSize);
-      
-      if (BufferCapacity)
+      if (BufferCapacity) {
+        memcpy(NewBuffer, Buffer, BufferSize);
         free(Buffer);
+      }
       Buffer = NewBuffer;
       BufferCapacity = NewCapacity;
     }
index c0aab4c4db7d336be3e6ee22a8c480fb196e4e23..0cda91919b1fd644220ef8a09a74c28e46c8cd8c 100644 (file)
@@ -724,6 +724,8 @@ MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
 }
 
 static StringRef copyIntoContext(const ASTContext &C, StringRef str) {
+  if (str.empty())
+    return StringRef();
   size_t size = str.size();
   char *buffer = new (C) char[size];
   memcpy(buffer, str.data(), size);
index 4c77a8d289745304291d30eb892d66f6d3151ef2..82680a84d3281cf695e3e95f92a29f053bb64aec 100644 (file)
@@ -484,8 +484,10 @@ private:
   /// are concatenated.
   StringRef internString(StringRef A, StringRef B = StringRef()) {
     char *Data = DebugInfoNames.Allocate<char>(A.size() + B.size());
-    std::memcpy(Data, A.data(), A.size());
-    std::memcpy(Data + A.size(), B.data(), B.size());
+    if (!A.empty())
+      std::memcpy(Data, A.data(), A.size());
+    if (!B.empty())
+      std::memcpy(Data + A.size(), B.data(), B.size());
     return StringRef(Data, A.size() + B.size());
   }
 };
index 980f341824fafc2e3f2a7676907f23d7a134b24a..eeeb832cd873890f3439da8311fd5fb479185a82 100644 (file)
@@ -255,6 +255,17 @@ static int parse_remapped_files_with_try(int try_idx,
   if (ret)
     return ret;
 
+  if (num_unsaved_files_no_try_idx == 0) {
+    *unsaved_files = unsaved_files_try_idx;
+    *num_unsaved_files = num_unsaved_files_try_idx;
+    return 0;
+  }
+  if (num_unsaved_files_try_idx == 0) {
+    *unsaved_files = unsaved_files_no_try_idx;
+    *num_unsaved_files = num_unsaved_files_no_try_idx;
+    return 0;
+  }
+
   *num_unsaved_files = num_unsaved_files_no_try_idx + num_unsaved_files_try_idx;
   *unsaved_files
     = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx,
index 5dc33a000a42af3ca5240a3e9f36f7d1ca10c23c..f2aa4002b99f4ef4cb25351deed5542be4e5543f 100644 (file)
@@ -326,7 +326,8 @@ namespace {
       OS << "    " << getLowerName() << "Length = S.size();\n";
       OS << "    this->" << getLowerName() << " = new (C, 1) char ["
          << getLowerName() << "Length];\n";
-      OS << "    std::memcpy(this->" << getLowerName() << ", S.data(), "
+      OS << "    if (!S.empty())\n";
+      OS << "      std::memcpy(this->" << getLowerName() << ", S.data(), "
          << getLowerName() << "Length);\n";
       OS << "  }";
     }
@@ -337,7 +338,8 @@ namespace {
       OS << "A->get" << getUpperName() << "()";
     }
     void writeCtorBody(raw_ostream &OS) const override {
-      OS << "      std::memcpy(" << getLowerName() << ", " << getUpperName()
+      OS << "      if (!" << getUpperName() << ".empty())\n";
+      OS << "        std::memcpy(" << getLowerName() << ", " << getUpperName()
          << ".data(), " << getLowerName() << "Length);";
     }
     void writeCtorInitializers(raw_ostream &OS) const override {