From f816682dc82cced0bc9ad79f0aa33125b4210aea Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Wed, 21 Feb 2018 02:02:39 +0000 Subject: [PATCH] Clean up use of C allocation functions If the value returned by `malloc`, `calloc` or `realloc` is not checked for null pointer, this change replaces them for `safe_malloc`, `safe_calloc` or `safe_realloc`, which are defined in the namespace `llvm`. These function report fatal error on out of memory. In the plain C files, assertion statements are added to ensure that memory is successfully allocated. The aim of this change is to get better diagnostics of OOM on Windows. Differential Revision: https://reviews.llvm.org/D43017 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325661 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/ParsedTemplate.h | 3 +-- lib/AST/NestedNameSpecifier.cpp | 2 +- lib/Frontend/CacheTokens.cpp | 3 ++- lib/Frontend/Rewrite/HTMLPrint.cpp | 7 +++---- lib/Lex/MacroArgs.cpp | 3 ++- tools/c-index-test/c-index-test.c | 14 ++++++++++++++ tools/libclang/BuildSystem.cpp | 5 +++-- tools/libclang/CIndex.cpp | 3 ++- tools/libclang/CXString.cpp | 2 +- 9 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index 01a4ab3f37..e980e4d37b 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -199,8 +199,7 @@ namespace clang { SourceLocation LAngleLoc, SourceLocation RAngleLoc, ArrayRef TemplateArgs, SmallVectorImpl &CleanupList) { - - TemplateIdAnnotation *TemplateId = new (std::malloc( + TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc( totalSizeToAlloc(TemplateArgs.size()))) TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name, OperatorKind, OpaqueTemplateName, TemplateKind, diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index 889f8308a9..f46552e337 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -466,7 +466,7 @@ static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize, unsigned NewCapacity = std::max( (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2), (unsigned)(BufferSize + (End - Start))); - char *NewBuffer = static_cast(malloc(NewCapacity)); + char *NewBuffer = static_cast(llvm::safe_malloc(NewCapacity)); if (BufferCapacity) { memcpy(NewBuffer, Buffer, BufferSize); free(Buffer); diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp index 72e8f68dc0..851ea25e9b 100644 --- a/lib/Frontend/CacheTokens.cpp +++ b/lib/Frontend/CacheTokens.cpp @@ -662,7 +662,8 @@ std::pair PTHWriter::EmitIdentifierTable() { // (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs // Note that we use 'calloc', so all the bytes are 0. - PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey)); + PTHIdKey *IIDMap = static_cast( + llvm::safe_calloc(idcount, sizeof(PTHIdKey))); // Create the hashtable. llvm::OnDiskChainedHashTableGenerator IIOffMap; diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp index 11e431de0a..34ee9673cc 100644 --- a/lib/Frontend/Rewrite/HTMLPrint.cpp +++ b/lib/Frontend/Rewrite/HTMLPrint.cpp @@ -86,8 +86,7 @@ void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) { // Emit the HTML. const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID); - char *Buffer = (char*)malloc(RewriteBuf.size()); - std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); - Out->write(Buffer, RewriteBuf.size()); - free(Buffer); + std::unique_ptr Buffer(new char[RewriteBuf.size()]); + std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer.get()); + Out->write(Buffer.get(), RewriteBuf.size()); } diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp index 5c0f0623c3..df3f8a4877 100644 --- a/lib/Lex/MacroArgs.cpp +++ b/lib/Lex/MacroArgs.cpp @@ -49,7 +49,8 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI, if (!ResultEnt) { // Allocate memory for a MacroArgs object with the lexer tokens at the end, // and construct the MacroArgs object. - Result = new (std::malloc(totalSizeToAlloc(UnexpArgTokens.size()))) + Result = new ( + llvm::safe_malloc(totalSizeToAlloc(UnexpArgTokens.size()))) MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams()); } else { Result = *ResultEnt; diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index c134d4e5c5..31bdf8a6fd 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -232,6 +232,7 @@ static int parse_remapped_files_with_opt(const char *opt_name, *unsaved_files = (struct CXUnsavedFile *)malloc(sizeof(struct CXUnsavedFile) * *num_unsaved_files); + assert(*unsaved_files); for (i = 0; i != *num_unsaved_files; ++i) { struct CXUnsavedFile *unsaved = *unsaved_files + i; const char *arg_string = argv[arg_indices[i]] + prefix_len; @@ -267,6 +268,7 @@ static int parse_remapped_files_with_opt(const char *opt_name, /* Read the contents of the file we're remapping to. */ contents = (char *)malloc(unsaved->Length + 1); + assert(contents); if (fread(contents, 1, unsaved->Length, to_file) != unsaved->Length) { fprintf(stderr, "error: unexpected %s reading 'to' file %s\n", (feof(to_file) ? "EOF" : "error"), sep + 1); @@ -286,6 +288,7 @@ static int parse_remapped_files_with_opt(const char *opt_name, /* Copy the file name that we're remapping from. */ filename_len = sep - arg_string; filename = (char *)malloc(filename_len + 1); + assert(filename); memcpy(filename, arg_string, filename_len); filename[filename_len] = 0; unsaved->Filename = filename; @@ -340,6 +343,7 @@ static int parse_remapped_files_with_try(int try_idx, = (struct CXUnsavedFile *)realloc(unsaved_files_no_try_idx, sizeof(struct CXUnsavedFile) * *num_unsaved_files); + assert(*unsaved_files); memcpy(*unsaved_files + num_unsaved_files_no_try_idx, unsaved_files_try_idx, sizeof(struct CXUnsavedFile) * num_unsaved_files_try_idx); @@ -2169,6 +2173,7 @@ int parse_file_line_column(const char *input, char **filename, unsigned *line, /* Copy the file name. */ *filename = (char*)malloc(last_colon - input + 1); + assert(*filename); memcpy(*filename, input, last_colon - input); (*filename)[last_colon - input] = 0; return 0; @@ -2578,6 +2583,7 @@ static int inspect_cursor_at(int argc, const char **argv, assert(NumLocations > 0 && "Unable to count locations?"); Locations = (CursorSourceLocation *)malloc( NumLocations * sizeof(CursorSourceLocation)); + assert(Locations); for (Loc = 0; Loc < NumLocations; ++Loc) { const char *input = argv[Loc + 1] + strlen(locations_flag); if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename, @@ -2871,6 +2877,7 @@ static int find_file_refs_at(int argc, const char **argv) { assert(NumLocations > 0 && "Unable to count locations?"); Locations = (CursorSourceLocation *)malloc( NumLocations * sizeof(CursorSourceLocation)); + assert(Locations); for (Loc = 0; Loc < NumLocations; ++Loc) { const char *input = argv[Loc + 1] + strlen("-file-refs-at="); if ((errorCode = parse_file_line_column(input, &Locations[Loc].filename, @@ -2978,6 +2985,7 @@ static int find_file_includes_in(int argc, const char **argv) { /* Parse the locations. */ assert(NumFilenames > 0 && "Unable to count filenames?"); Filenames = (const char **)malloc(NumFilenames * sizeof(const char *)); + assert(Filenames); for (I = 0; I < NumFilenames; ++I) { const char *input = argv[I + 1] + strlen("-file-includes-in="); /* Copy the file name. */ @@ -3061,7 +3069,9 @@ typedef struct { static ImportedASTFilesData *importedASTs_create() { ImportedASTFilesData *p; p = malloc(sizeof(ImportedASTFilesData)); + assert(p); p->filenames = malloc(MAX_IMPORTED_ASTFILES * sizeof(const char *)); + assert(p->filenames); p->num_files = 0; return p; } @@ -3194,6 +3204,7 @@ static CXIdxClientContainer makeClientContainer(CXClientData *client_data, node = (IndexDataStringList *)malloc(sizeof(IndexDataStringList) + strlen(name) + digitCount(line) + digitCount(column) + 2); + assert(node); newStr = node->data; sprintf(newStr, "%s:%d:%d", name, line, column); @@ -3795,6 +3806,7 @@ static int index_compile_db(int argc, const char **argv) { len = strlen(database); tmp = (char *) malloc(len+1); + assert(tmp); memcpy(tmp, database, len+1); buildDir = dirname(tmp); @@ -3976,6 +3988,7 @@ int perform_token_annotation(int argc, const char **argv) { } cursors = (CXCursor *)malloc(num_tokens * sizeof(CXCursor)); + assert(cursors); clang_annotateTokens(TU, tokens, num_tokens, cursors); if (checkForErrors(TU) != 0) { @@ -4050,6 +4063,7 @@ perform_test_compilation_db(const char *database, int argc, const char **argv) { len = strlen(database); tmp = (char *) malloc(len+1); + assert(tmp); memcpy(tmp, database, len+1); buildDir = dirname(tmp); diff --git a/tools/libclang/BuildSystem.cpp b/tools/libclang/BuildSystem.cpp index 99aa5b6f2f..79fa69c40b 100644 --- a/tools/libclang/BuildSystem.cpp +++ b/tools/libclang/BuildSystem.cpp @@ -17,6 +17,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Chrono.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" @@ -78,7 +79,7 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned, unwrap(VFO)->write(OS); StringRef Data = OS.str(); - *out_buffer_ptr = (char*)malloc(Data.size()); + *out_buffer_ptr = static_cast(llvm::safe_malloc(Data.size())); *out_buffer_size = Data.size(); memcpy(*out_buffer_ptr, Data.data(), Data.size()); return CXError_Success; @@ -140,7 +141,7 @@ clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned, OS << "}\n"; StringRef Data = OS.str(); - *out_buffer_ptr = (char*)malloc(Data.size()); + *out_buffer_ptr = static_cast(llvm::safe_malloc(Data.size())); *out_buffer_size = Data.size(); memcpy(*out_buffer_ptr, Data.data(), Data.size()); return CXError_Success; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 7a8df9d7f8..791b475975 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -6666,7 +6666,8 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, if (CXTokens.empty()) return; - *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); + *Tokens = static_cast( + llvm::safe_malloc(sizeof(CXToken) * CXTokens.size())); memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); *NumTokens = CXTokens.size(); } diff --git a/tools/libclang/CXString.cpp b/tools/libclang/CXString.cpp index 4486031792..cef4e53a42 100644 --- a/tools/libclang/CXString.cpp +++ b/tools/libclang/CXString.cpp @@ -96,7 +96,7 @@ CXString createRef(StringRef String) { CXString createDup(StringRef String) { CXString Result; - char *Spelling = static_cast(malloc(String.size() + 1)); + char *Spelling = static_cast(llvm::safe_malloc(String.size() + 1)); memmove(Spelling, String.data(), String.size()); Spelling[String.size()] = 0; Result.data = Spelling; -- 2.40.0