Skip to content

Commit d528a8e

Browse files
shiltianjharryma
authored andcommitted
[nfc][clang-offload-bundler] Don't leak on exit(1) (llvm#119178)
`exit(1)` does not calls C++ destructors, however, it calls `at_exit()` handlers, including lsan. Usually lsan can see pointers of local allocations on the stack or in registers, but those can be discarded by `noreturn` `exit` call. Fixes leak triggered by f7685af. (cherry picked from commit d5fe633)
1 parent 5b8bee9 commit d528a8e

File tree

1 file changed

+48
-48
lines changed

1 file changed

+48
-48
lines changed

clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -196,13 +196,14 @@ int main(int argc, const char **argv) {
196196

197197
auto reportError = [argv](Error E) {
198198
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0]));
199-
exit(1);
199+
return 1;
200200
};
201201

202202
auto doWork = [&](std::function<llvm::Error()> Work) {
203203
if (llvm::Error Err = Work()) {
204-
reportError(std::move(Err));
204+
return reportError(std::move(Err));
205205
}
206+
return 0;
206207
};
207208

208209
auto warningOS = [argv]() -> raw_ostream & {
@@ -223,14 +224,14 @@ int main(int argc, const char **argv) {
223224
if (!Objcopy)
224225
Objcopy = sys::findProgramByName("llvm-objcopy");
225226
if (!Objcopy)
226-
reportError(createStringError(Objcopy.getError(),
227-
"unable to find 'llvm-objcopy' in path"));
227+
return reportError(createStringError(
228+
Objcopy.getError(), "unable to find 'llvm-objcopy' in path"));
228229
else
229230
BundlerConfig.ObjcopyPath = *Objcopy;
230231

231232
if (InputFileNames.getNumOccurrences() != 0 &&
232233
InputFileNamesDeprecatedOpt.getNumOccurrences() != 0) {
233-
reportError(createStringError(
234+
return reportError(createStringError(
234235
errc::invalid_argument,
235236
"-inputs and -input cannot be used together, use only -input instead"));
236237
}
@@ -246,9 +247,9 @@ int main(int argc, const char **argv) {
246247

247248
if (OutputFileNames.getNumOccurrences() != 0 &&
248249
OutputFileNamesDeprecatedOpt.getNumOccurrences() != 0) {
249-
reportError(createStringError(errc::invalid_argument,
250-
"-outputs and -output cannot be used "
251-
"together, use only -output instead"));
250+
return reportError(createStringError(errc::invalid_argument,
251+
"-outputs and -output cannot be used "
252+
"together, use only -output instead"));
252253
}
253254

254255
if (OutputFileNamesDeprecatedOpt.size()) {
@@ -262,77 +263,77 @@ int main(int argc, const char **argv) {
262263

263264
if (ListBundleIDs) {
264265
if (Unbundle) {
265-
reportError(
266+
return reportError(
266267
createStringError(errc::invalid_argument,
267268
"-unbundle and -list cannot be used together"));
268269
}
269270
if (InputFileNames.size() != 1) {
270-
reportError(createStringError(errc::invalid_argument,
271-
"only one input file supported for -list"));
271+
return reportError(createStringError(
272+
errc::invalid_argument, "only one input file supported for -list"));
272273
}
273274
if (OutputFileNames.size()) {
274-
reportError(createStringError(errc::invalid_argument,
275-
"-outputs option is invalid for -list"));
275+
return reportError(createStringError(
276+
errc::invalid_argument, "-outputs option is invalid for -list"));
276277
}
277278
if (TargetNames.size()) {
278-
reportError(createStringError(errc::invalid_argument,
279-
"-targets option is invalid for -list"));
279+
return reportError(createStringError(
280+
errc::invalid_argument, "-targets option is invalid for -list"));
280281
}
281282

282-
doWork([&]() { return OffloadBundler::ListBundleIDsInFile(
283-
InputFileNames.front(),
284-
BundlerConfig); });
285-
return 0;
283+
return doWork([&]() {
284+
return OffloadBundler::ListBundleIDsInFile(InputFileNames.front(),
285+
BundlerConfig);
286+
});
286287
}
287288

288289
if (BundlerConfig.CheckInputArchive) {
289290
if (!Unbundle) {
290-
reportError(createStringError(errc::invalid_argument,
291-
"-check-input-archive cannot be used while "
292-
"bundling"));
291+
return reportError(createStringError(
292+
errc::invalid_argument, "-check-input-archive cannot be used while "
293+
"bundling"));
293294
}
294295
if (Unbundle && BundlerConfig.FilesType != "a") {
295-
reportError(createStringError(errc::invalid_argument,
296-
"-check-input-archive can only be used for "
297-
"unbundling archives (-type=a)"));
296+
return reportError(createStringError(
297+
errc::invalid_argument, "-check-input-archive can only be used for "
298+
"unbundling archives (-type=a)"));
298299
}
299300
}
300301

301302
if (OutputFileNames.size() == 0) {
302-
reportError(
303+
return reportError(
303304
createStringError(errc::invalid_argument, "no output file specified!"));
304305
}
305306

306307
if (TargetNames.getNumOccurrences() == 0) {
307-
reportError(createStringError(
308+
return reportError(createStringError(
308309
errc::invalid_argument,
309310
"for the --targets option: must be specified at least once!"));
310311
}
311312

312313
if (Unbundle) {
313314
if (InputFileNames.size() != 1) {
314-
reportError(createStringError(
315+
return reportError(createStringError(
315316
errc::invalid_argument,
316317
"only one input file supported in unbundling mode"));
317318
}
318319
if (OutputFileNames.size() != TargetNames.size()) {
319-
reportError(createStringError(errc::invalid_argument,
320-
"number of output files and targets should "
321-
"match in unbundling mode"));
320+
return reportError(createStringError(
321+
errc::invalid_argument, "number of output files and targets should "
322+
"match in unbundling mode"));
322323
}
323324
} else {
324325
if (BundlerConfig.FilesType == "a") {
325-
reportError(createStringError(errc::invalid_argument,
326-
"Archive files are only supported "
327-
"for unbundling"));
326+
return reportError(createStringError(errc::invalid_argument,
327+
"Archive files are only supported "
328+
"for unbundling"));
328329
}
329330
if (OutputFileNames.size() != 1) {
330-
reportError(createStringError(
331-
errc::invalid_argument,
332-
"only one output file supported in bundling mode"));
331+
return reportError(
332+
createStringError(errc::invalid_argument,
333+
"only one output file supported in bundling mode"));
333334
}
334335
if (InputFileNames.size() != TargetNames.size()) {
335-
reportError(createStringError(
336+
return reportError(createStringError(
336337
errc::invalid_argument,
337338
"number of input files and targets should match in bundling mode"));
338339
}
@@ -349,9 +350,9 @@ int main(int argc, const char **argv) {
349350
// Standardize target names to include env field
350351
std::vector<std::string> StandardizedTargetNames;
351352
for (StringRef Target : TargetNames) {
352-
if (ParsedTargets.contains(Target)) {
353-
reportError(createStringError(errc::invalid_argument,
354-
"Duplicate targets are not allowed"));
353+
if (!ParsedTargets.insert(Target).second) {
354+
return reportError(createStringError(
355+
errc::invalid_argument, "Duplicate targets are not allowed"));
355356
}
356357
ParsedTargets.insert(Target);
357358

@@ -369,7 +370,7 @@ int main(int argc, const char **argv) {
369370
Msg << ", unknown offloading kind '" << OffloadInfo.OffloadKind << "'";
370371
if (!TripleIsValid)
371372
Msg << ", unknown target triple '" << OffloadInfo.Triple.str() << "'";
372-
reportError(createStringError(errc::invalid_argument, Msg.str()));
373+
return reportError(createStringError(errc::invalid_argument, Msg.str()));
373374
}
374375

375376
TargetIDs[OffloadInfo.OffloadKind.str() + "-" + OffloadInfo.Triple.str()]
@@ -396,7 +397,7 @@ int main(int argc, const char **argv) {
396397
Msg << "Cannot bundle inputs with conflicting targets: '"
397398
<< TargetID.first + "-" + ConflictingTID->first << "' and '"
398399
<< TargetID.first + "-" + ConflictingTID->second << "'";
399-
reportError(createStringError(errc::invalid_argument, Msg.str()));
400+
return reportError(createStringError(errc::invalid_argument, Msg.str()));
400401
}
401402
}
402403

@@ -409,14 +410,14 @@ int main(int argc, const char **argv) {
409410
// treat missing host triple as error if we do unbundling.
410411
if ((Unbundle && HostTargetNum > 1) ||
411412
(!Unbundle && HostTargetNum != 1 && !BundlerConfig.AllowNoHost)) {
412-
reportError(createStringError(errc::invalid_argument,
413-
"expecting exactly one host target but got " +
414-
Twine(HostTargetNum)));
413+
return reportError(createStringError(
414+
errc::invalid_argument,
415+
"expecting exactly one host target but got " + Twine(HostTargetNum)));
415416
}
416417

417418
OffloadBundler Bundler(BundlerConfig);
418419

419-
doWork([&]() {
420+
return doWork([&]() {
420421
if (Unbundle) {
421422
if (BundlerConfig.FilesType == "a")
422423
return Bundler.UnbundleArchive();
@@ -425,5 +426,4 @@ int main(int argc, const char **argv) {
425426
} else
426427
return Bundler.BundleFiles();
427428
});
428-
return 0;
429429
}

0 commit comments

Comments
 (0)