From 0ceb20d6f46f6e5b54fa36f792cdc6a252e6edc6 Mon Sep 17 00:00:00 2001 From: Renato Golin Date: Fri, 22 May 2015 20:43:30 +0000 Subject: [PATCH] Reinforce ARMTargetParser::getCanonicalArchName validation Before, getCanonicalArchName was relying on parseArch() to validate the arch name, which was a problem when other methods, that also needed to call it, were duplicating the steps. But to dissociate getCanonicalArchName from parseArch, we needed to make getCanonicalArchName more robust in detecting valid arch names. It's still not perfect, but will do for the time being, until we merge Triple with TargetParser into a TargetDescription mega class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238047 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/TargetParser.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/Support/TargetParser.cpp b/lib/Support/TargetParser.cpp index 590a1458558..a3998d2d13e 100644 --- a/lib/Support/TargetParser.cpp +++ b/lib/Support/TargetParser.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/TargetParser.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" +#include using namespace llvm; @@ -279,14 +280,17 @@ StringRef ARMTargetParser::getArchSynonym(StringRef Arch) { // MArch is expected to be of the form (arm|thumb)?(eb)?(v.+)?(eb)?, but // (iwmmxt|xscale)(eb)? is also permitted. If the former, return -// "v.+", if the latter, return unmodified string. If invalid, return "". +// "v.+", if the latter, return unmodified string, minus 'eb'. +// If invalid, return empty string. StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) { size_t offset = StringRef::npos; StringRef A = Arch; StringRef Error = ""; // Begins with "arm" / "thumb", move past it. - if (A.startswith("arm")) + if (A.startswith("arm64")) + offset = 5; + else if (A.startswith("arm")) offset = 3; else if (A.startswith("thumb")) offset = 5; @@ -305,21 +309,25 @@ StringRef ARMTargetParser::getCanonicalArchName(StringRef Arch) { // Or, if it ends with eb ("armv7eb"), chop it off. else if (A.endswith("eb")) A = A.substr(0, A.size() - 2); - // Reached the end or a 'v', canonicalise. - if (offset != StringRef::npos && (offset == A.size() || A[offset] == 'v')) + // Trim the head + if (offset != StringRef::npos) A = A.substr(offset); - // Empty string mans offset reached the end. Although valid, this arch - // will not have a match in the table. Return the original string. + // Empty string means offset reached the end, which means it's valid. if (A.empty()) return Arch; - // If can't find the arch, return an empty StringRef. - if (parseArch(A) == ARM::AK_INVALID) - return Error; + // Only match non-marketing names + if (offset != StringRef::npos) { + // Must start with 'vN'. + if (A[0] != 'v' || !std::isdigit(A[1])) + return Error; + // Can't have an extra 'eb'. + if (A.find("eb") != StringRef::npos) + return Error; + } - // Arch will either be a 'v' name (v7a) or a marketing name (xscale) - // or empty, if invalid. + // Arch will either be a 'v' name (v7a) or a marketing name (xscale). return A; } @@ -390,7 +398,6 @@ unsigned ARMTargetParser::parseArchEndian(StringRef Arch) { // Profile A/R/M unsigned ARMTargetParser::parseArchProfile(StringRef Arch) { - // FIXME: We're running parseArch twice. Arch = getCanonicalArchName(Arch); switch(parseArch(Arch)) { case ARM::AK_ARMV6M: @@ -409,9 +416,8 @@ unsigned ARMTargetParser::parseArchProfile(StringRef Arch) { return ARM::PK_INVALID; } -// Version number 4 ~ 8 (ex. v7 = 7). +// Version number (ex. v7 = 7). unsigned ARMTargetParser::parseArchVersion(StringRef Arch) { - // FIXME: We're running parseArch twice. Arch = getCanonicalArchName(Arch); switch(parseArch(Arch)) { case ARM::AK_ARMV2: