summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/CommandLine.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-07-24 14:32:01 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-07-24 14:32:01 +0000
commita8e7c26ee0e0655660d5ed3cdad213b619b3ae3b (patch)
tree741b56b2dfdecef086f5a19cbc8c91a6b285b7c8 /llvm/lib/Support/CommandLine.cpp
parentebde78c4c6149dfd6dfcddd39ed07e5aec1860ed (diff)
downloadbcm5719-llvm-a8e7c26ee0e0655660d5ed3cdad213b619b3ae3b.tar.gz
bcm5719-llvm-a8e7c26ee0e0655660d5ed3cdad213b619b3ae3b.zip
Don't leak when expanding response files.
Before this patch we would strdup each argument. If one was a response file, we would replace it with the response file contents, leaking the original strdup result. We now don't strdup the originals and let StringSaver free any memory it allocated. This also saves a bit of malloc traffic when response files are not used. Leak found by the valgrind build bot. llvm-svn: 187042
Diffstat (limited to 'llvm/lib/Support/CommandLine.cpp')
-rw-r--r--llvm/lib/Support/CommandLine.cpp32
1 files changed, 15 insertions, 17 deletions
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
index c2a25a18cd9..1975a013385 100644
--- a/llvm/lib/Support/CommandLine.cpp
+++ b/llvm/lib/Support/CommandLine.cpp
@@ -563,8 +563,19 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
namespace {
class StrDupSaver : public StringSaver {
+ std::vector<char*> Dups;
+ public:
+ ~StrDupSaver() {
+ for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end();
+ I != E; ++I) {
+ char *Dup = *I;
+ free(Dup);
+ }
+ }
const char *SaveString(const char *Str) LLVM_OVERRIDE {
- return strdup(Str);
+ char *Dup = strdup(Str);
+ Dups.push_back(Dup);
+ return Dup;
}
};
}
@@ -588,20 +599,14 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
// Get program's "name", which we wouldn't know without the caller
// telling us.
SmallVector<const char *, 20> newArgv;
- newArgv.push_back(strdup(progName));
+ StrDupSaver Saver;
+ newArgv.push_back(Saver.SaveString(progName));
// Parse the value of the environment variable into a "command line"
// and hand it off to ParseCommandLineOptions().
- StrDupSaver Saver;
TokenizeGNUCommandLine(envValue, Saver, newArgv);
int newArgc = static_cast<int>(newArgv.size());
ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
-
- // Free all the strdup()ed strings.
- for (SmallVectorImpl<const char *>::iterator i = newArgv.begin(),
- e = newArgv.end();
- i != e; ++i)
- free(const_cast<char *>(*i));
}
void cl::ParseCommandLineOptions(int argc, const char * const *argv,
@@ -618,7 +623,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Expand response files.
SmallVector<const char *, 20> newArgv;
for (int i = 0; i != argc; ++i)
- newArgv.push_back(strdup(argv[i]));
+ newArgv.push_back(argv[i]);
StrDupSaver Saver;
ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);
argv = &newArgv[0];
@@ -914,13 +919,6 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
PositionalOpts.clear();
MoreHelp->clear();
- // Free the memory allocated by ExpandResponseFiles.
- // Free all the strdup()ed strings.
- for (SmallVectorImpl<const char *>::iterator i = newArgv.begin(),
- e = newArgv.end();
- i != e; ++i)
- free(const_cast<char *>(*i));
-
// If we had an error processing our arguments, don't let the program execute
if (ErrorParsing) exit(1);
}
OpenPOWER on IntegriCloud