summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Driver/Driver.h9
-rw-r--r--clang/lib/Driver/Driver.cpp28
-rw-r--r--clang/lib/Driver/Tools.cpp7
-rw-r--r--clang/test/Driver/darwin-ld.c24
4 files changed, 63 insertions, 5 deletions
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index f0924946e84..03e6ed0ed3f 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -475,6 +475,15 @@ public:
static bool GetReleaseVersion(const char *Str, unsigned &Major,
unsigned &Minor, unsigned &Micro,
bool &HadExtra);
+
+ /// Parse digits from a string \p Str and fulfill \p Digits with
+ /// the parsed numbers. This method assumes that the max number of
+ /// digits to look for is equal to Digits.size().
+ ///
+ /// \return True if the entire string was parsed and there are
+ /// no extra characters remaining at the end.
+ static bool GetReleaseVersion(const char *Str,
+ MutableArrayRef<unsigned> Digits);
};
/// \return True if the last defined optimization level is -Ofast.
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a5f9ebbdb15..64903de2945 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -2545,6 +2545,34 @@ bool Driver::GetReleaseVersion(const char *Str, unsigned &Major,
return true;
}
+/// Parse digits from a string \p Str and fulfill \p Digits with
+/// the parsed numbers. This method assumes that the max number of
+/// digits to look for is equal to Digits.size().
+///
+/// \return True if the entire string was parsed and there are
+/// no extra characters remaining at the end.
+bool Driver::GetReleaseVersion(const char *Str,
+ MutableArrayRef<unsigned> Digits) {
+ if (*Str == '\0')
+ return false;
+
+ char *End;
+ unsigned CurDigit = 0;
+ while (CurDigit < Digits.size()) {
+ unsigned Digit = (unsigned)strtol(Str, &End, 10);
+ Digits[CurDigit] = Digit;
+ if (*Str != '\0' && *End == '\0')
+ return true;
+ if (*End != '.' || Str == End)
+ return false;
+ Str = End + 1;
+ CurDigit++;
+ }
+
+ // More digits than requested, bail out...
+ return false;
+}
+
std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks() const {
unsigned IncludedFlagsBitmask = 0;
unsigned ExcludedFlagsBitmask = options::NoDriverOption;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index b441c72f03f..b7981c045e3 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -7245,12 +7245,9 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
const Driver &D = getToolChain().getDriver();
const toolchains::MachO &MachOTC = getMachOToolChain();
- unsigned Version[3] = {0, 0, 0};
+ unsigned Version[5] = {0, 0, 0, 0, 0};
if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
- bool HadExtra;
- if (!Driver::GetReleaseVersion(A->getValue(), Version[0], Version[1],
- Version[2], HadExtra) ||
- HadExtra)
+ if (!Driver::GetReleaseVersion(A->getValue(), Version))
D.Diag(diag::err_drv_invalid_version_number) << A->getAsString(Args);
}
diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c
index 185ed886883..a7681fad8b6 100644
--- a/clang/test/Driver/darwin-ld.c
+++ b/clang/test/Driver/darwin-ld.c
@@ -303,3 +303,27 @@
// RUN: FileCheck --check-prefix=LINK-IFRAMEWORK %s
// LINK-IFRAMEWORK: {{ld(.exe)?"}}
// LINK-IFRAMEWORK: "-FBar"
+
+// Check ld64 accepts up to 5 digits with no extra characters
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3 2> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0 2>> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0.1 2>> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0.1.2 2>> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0.1.2.6 2>> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0.1.a 2>> %t.log
+// RUN: %clang -target x86_64-apple-darwin12 %s -### -o %t \
+// RUN: -mlinker-version=133.3.0.1a 2>> %t.log
+// RUN: FileCheck -check-prefix=LINK_VERSION_DIGITS %s < %t.log
+// LINK_VERSION_DIGITS-NOT: invalid version number in '-mlinker-version=133.3'
+// LINK_VERSION_DIGITS-NOT: invalid version number in '-mlinker-version=133.3.0'
+// LINK_VERSION_DIGITS-NOT: invalid version number in '-mlinker-version=133.3.0.1'
+// LINK_VERSION_DIGITS-NOT: invalid version number in '-mlinker-version=133.3.0.1.2'
+// LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1.2.6'
+// LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1.a'
+// LINK_VERSION_DIGITS: invalid version number in '-mlinker-version=133.3.0.1a'
OpenPOWER on IntegriCloud