Skip to content

Commit afb0484

Browse files
authored
Avoid memory leaks when passing arguments to drivers (#283)
Use a new ArgumentList class instead of malloced pointers to pass arguments to drivers. This new class will not own all arguments passed, just those which were created in place (via emplace_back) to avoid unnecessary copying. Signed-off-by: Victor Perez <[email protected]> Signed-off-by: Victor Perez <[email protected]>
1 parent f7d7d25 commit afb0484

File tree

3 files changed

+79
-83
lines changed

3 files changed

+79
-83
lines changed

tools/cgeist/ArgumentList.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//===- ArgumentList.h -------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef MLIR_TOOLS_CGEIST_ARGUMENTLIST_H
10+
#define MLIR_TOOLS_CGEIST_ARGUMENTLIST_H
11+
12+
#include <llvm/ADT/ArrayRef.h>
13+
#include <llvm/Support/raw_ostream.h>
14+
15+
namespace mlirclang {
16+
/// Class to pass options to a compilation tool.
17+
class ArgumentList {
18+
public:
19+
/// Add argument.
20+
///
21+
/// The element stored will not be owned by this.
22+
void push_back(llvm::StringRef Arg) { Args.push_back(Arg.data()); }
23+
24+
/// Add argument and ensure it will be valid before this passer's destruction.
25+
///
26+
/// The element stored will be owned by this.
27+
template <typename... ArgTy> void emplace_back(ArgTy &&...Args) {
28+
// Store as a string
29+
std::string Buffer;
30+
llvm::raw_string_ostream Stream(Buffer);
31+
(Stream << ... << Args);
32+
Storage.push_back(Stream.str());
33+
push_back(Storage.back());
34+
}
35+
36+
/// Return the underling argument list.
37+
///
38+
/// The return value of this operation could be invalidated by subsequent
39+
/// calls to push_back() or emplace_back().
40+
llvm::ArrayRef<const char *> getArguments() const { return Args; }
41+
42+
private:
43+
/// Helper storage.
44+
llvm::SmallVector<std::string> Storage;
45+
/// List of arguments
46+
llvm::SmallVector<const char *> Args;
47+
};
48+
} // end namespace mlirclang
49+
50+
#endif

tools/cgeist/Lib/clang-mlir.cc

Lines changed: 21 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "clang-mlir.h"
10+
#include "../ArgumentList.h"
1011
#include "TypeUtils.h"
1112
#include "mlir/Dialect/Arith/IR/Arith.h"
1213
#include "mlir/Dialect/DLTI/DLTI.h"
@@ -5510,50 +5511,30 @@ static bool parseMLIR(const char *Argv0, std::vector<std::string> filenames,
55105511
const char *binary = Argv0; // CudaLower ? "clang++" : "clang";
55115512
const unique_ptr<Driver> driver(
55125513
new Driver(binary, llvm::sys::getDefaultTargetTriple(), Diags));
5513-
std::vector<const char *> Argv;
5514+
mlirclang::ArgumentList Argv;
55145515
Argv.push_back(binary);
5515-
for (auto a : filenames) {
5516-
char *chars = (char *)malloc(a.length() + 1);
5517-
memcpy(chars, a.data(), a.length());
5518-
chars[a.length()] = 0;
5519-
Argv.push_back(chars);
5516+
for (const auto &filename : filenames) {
5517+
Argv.push_back(filename);
55205518
}
55215519
if (FOpenMP)
55225520
Argv.push_back("-fopenmp");
55235521
if (TargetTripleOpt != "") {
5524-
char *chars = (char *)malloc(TargetTripleOpt.length() + 1);
5525-
memcpy(chars, TargetTripleOpt.data(), TargetTripleOpt.length());
5526-
chars[TargetTripleOpt.length()] = 0;
55275522
Argv.push_back("-target");
5528-
Argv.push_back(chars);
5523+
Argv.push_back(TargetTripleOpt);
55295524
}
55305525
if (McpuOpt != "") {
5531-
auto a = "-mcpu=" + McpuOpt;
5532-
char *chars = (char *)malloc(a.length() + 1);
5533-
memcpy(chars, a.data(), a.length());
5534-
chars[a.length()] = 0;
5535-
Argv.push_back(chars);
5526+
Argv.emplace_back("-mcpu=", McpuOpt);
55365527
}
55375528
if (Standard != "") {
5538-
auto a = "-std=" + Standard;
5539-
char *chars = (char *)malloc(a.length() + 1);
5540-
memcpy(chars, a.data(), a.length());
5541-
chars[a.length()] = 0;
5542-
Argv.push_back(chars);
5529+
Argv.emplace_back("-std=", Standard);
55435530
}
55445531
if (ResourceDir != "") {
55455532
Argv.push_back("-resource-dir");
5546-
char *chars = (char *)malloc(ResourceDir.length() + 1);
5547-
memcpy(chars, ResourceDir.data(), ResourceDir.length());
5548-
chars[ResourceDir.length()] = 0;
5549-
Argv.push_back(chars);
5533+
Argv.push_back(ResourceDir);
55505534
}
55515535
if (SysRoot != "") {
55525536
Argv.push_back("--sysroot");
5553-
char *chars = (char *)malloc(SysRoot.length() + 1);
5554-
memcpy(chars, SysRoot.data(), SysRoot.length());
5555-
chars[SysRoot.length()] = 0;
5556-
Argv.push_back(chars);
5537+
Argv.push_back(SysRoot);
55575538
}
55585539
if (Verbose) {
55595540
Argv.push_back("-v");
@@ -5565,53 +5546,30 @@ static bool parseMLIR(const char *Argv0, std::vector<std::string> filenames,
55655546
Argv.push_back("-nocudalib");
55665547
}
55675548
if (CUDAGPUArch != "") {
5568-
auto a = "--cuda-gpu-arch=" + CUDAGPUArch;
5569-
char *chars = (char *)malloc(a.length() + 1);
5570-
memcpy(chars, a.data(), a.length());
5571-
chars[a.length()] = 0;
5572-
Argv.push_back(chars);
5549+
Argv.emplace_back("--cuda-gpu-arch=", CUDAGPUArch);
55735550
}
55745551
if (CUDAPath != "") {
5575-
auto a = "--cuda-path=" + CUDAPath;
5576-
char *chars = (char *)malloc(a.length() + 1);
5577-
memcpy(chars, a.data(), a.length());
5578-
chars[a.length()] = 0;
5579-
Argv.push_back(chars);
5552+
Argv.emplace_back("--cuda-path=", CUDAPath);
55805553
}
55815554
if (MArch != "") {
5582-
auto a = "-march=" + MArch;
5583-
char *chars = (char *)malloc(a.length() + 1);
5584-
memcpy(chars, a.data(), a.length());
5585-
chars[a.length()] = 0;
5586-
Argv.push_back(chars);
5555+
Argv.emplace_back("-march=", MArch);
55875556
}
5588-
for (auto a : includeDirs) {
5557+
for (const auto &dir : includeDirs) {
55895558
Argv.push_back("-I");
5590-
char *chars = (char *)malloc(a.length() + 1);
5591-
memcpy(chars, a.data(), a.length());
5592-
chars[a.length()] = 0;
5593-
Argv.push_back(chars);
5594-
}
5595-
for (auto a : defines) {
5596-
char *chars = (char *)malloc(a.length() + 3);
5597-
chars[0] = '-';
5598-
chars[1] = 'D';
5599-
memcpy(chars + 2, a.data(), a.length());
5600-
chars[2 + a.length()] = 0;
5601-
Argv.push_back(chars);
5602-
}
5603-
for (auto a : Includes) {
5604-
char *chars = (char *)malloc(a.length() + 1);
5605-
memcpy(chars, a.data(), a.length());
5606-
chars[a.length()] = 0;
5559+
Argv.push_back(dir);
5560+
}
5561+
for (const auto &define : defines) {
5562+
Argv.emplace_back("-D", define);
5563+
}
5564+
for (const auto &Include : Includes) {
56075565
Argv.push_back("-include");
5608-
Argv.push_back(chars);
5566+
Argv.push_back(Include);
56095567
}
56105568

56115569
Argv.push_back("-emit-ast");
56125570

56135571
const unique_ptr<Compilation> compilation(
5614-
driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
5572+
driver->BuildCompilation(Argv.getArguments()));
56155573
JobList &Jobs = compilation->getJobs();
56165574
if (Jobs.size() < 1)
56175575
return false;

tools/cgeist/driver.cc

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
#include "polygeist/Dialect.h"
5555
#include "polygeist/Passes/Passes.h"
5656

57+
#include "ArgumentList.h"
58+
5759
using namespace llvm;
5860

5961
static cl::OptionCategory toolOptions("clang to mlir - tool options");
@@ -263,7 +265,7 @@ int emitBinary(char *Argv0, const char *filename,
263265
const char *binary = Argv0;
264266
const unique_ptr<Driver> driver(new Driver(binary, TargetTriple, Diags));
265267
driver->CC1Main = &ExecuteCC1Tool;
266-
std::vector<const char *> Argv;
268+
mlirclang::ArgumentList Argv;
267269
Argv.push_back(Argv0);
268270
// Argv.push_back("-x");
269271
// Argv.push_back("ir");
@@ -272,27 +274,16 @@ int emitBinary(char *Argv0, const char *filename,
272274
Argv.push_back("-fopenmp");
273275
if (ResourceDir != "") {
274276
Argv.push_back("-resource-dir");
275-
char *chars = (char *)malloc(ResourceDir.length() + 1);
276-
memcpy(chars, ResourceDir.data(), ResourceDir.length());
277-
chars[ResourceDir.length()] = 0;
278-
Argv.push_back(chars);
277+
Argv.push_back(ResourceDir);
279278
}
280279
if (Verbose) {
281280
Argv.push_back("-v");
282281
}
283282
if (CUDAGPUArch != "") {
284-
auto a = "--cuda-gpu-arch=" + CUDAGPUArch;
285-
char *chars = (char *)malloc(a.length() + 1);
286-
memcpy(chars, a.data(), a.length());
287-
chars[a.length()] = 0;
288-
Argv.push_back(chars);
283+
Argv.emplace_back("--cuda-gpu-arch=", CUDAGPUArch);
289284
}
290285
if (CUDAPath != "") {
291-
auto a = "--cuda-path=" + CUDAPath;
292-
char *chars = (char *)malloc(a.length() + 1);
293-
memcpy(chars, a.data(), a.length());
294-
chars[a.length()] = 0;
295-
Argv.push_back(chars);
286+
Argv.emplace_back("--cuda-path=", CUDAPath);
296287
}
297288
if (Opt0) {
298289
Argv.push_back("-O0");
@@ -308,16 +299,13 @@ int emitBinary(char *Argv0, const char *filename,
308299
}
309300
if (Output != "") {
310301
Argv.push_back("-o");
311-
char *chars = (char *)malloc(Output.length() + 1);
312-
memcpy(chars, Output.data(), Output.length());
313-
chars[Output.length()] = 0;
314-
Argv.push_back(chars);
302+
Argv.push_back(Output);
315303
}
316304
for (const auto *arg : LinkArgs)
317305
Argv.push_back(arg);
318306

319307
const unique_ptr<Compilation> compilation(
320-
driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
308+
driver->BuildCompilation(Argv.getArguments()));
321309

322310
if (ResourceDir != "")
323311
driver->ResourceDir = ResourceDir;

0 commit comments

Comments
 (0)