From: Renato Golin Date: Fri, 22 May 2015 20:43:30 +0000 (+0000) Subject: Reinforce ARMTargetParser::getCanonicalArchName validation X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=0ceb20d6f46f6e5b54fa36f792cdc6a252e6edc6;p=oota-llvm.git 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 --- 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: