Avoid calling std::memcmp with nullptr
authorVitaly Buka <vitalybuka@google.com>
Tue, 15 Nov 2016 00:01:40 +0000 (00:01 +0000)
committerVitaly Buka <vitalybuka@google.com>
Tue, 15 Nov 2016 00:01:40 +0000 (00:01 +0000)
Summary:
UBSAN complains that this is undefined behavior.

We can assume that empty substring (N==1) always satisfy conditions. So
std::memcmp will be called only only for N > 1 and Str.size() > 0.

Reviewers: ruiu, zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D26646

llvm-svn: 286910

llvm/include/llvm/ADT/StringSwitch.h

index d2a0521..75577b7 100644 (file)
@@ -72,8 +72,9 @@ public:
   template<unsigned N>
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   StringSwitch& Case(const char (&S)[N], const T& Value) {
+    assert(N);
     if (!Result && N-1 == Str.size() &&
-        (std::memcmp(S, Str.data(), N-1) == 0)) {
+        (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) {
       Result = &Value;
     }
     return *this;
@@ -82,8 +83,9 @@ public:
   template<unsigned N>
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
+    assert(N);
     if (!Result && Str.size() >= N-1 &&
-        std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
+        (N == 1 || std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0)) {
       Result = &Value;
     }
     return *this;
@@ -92,8 +94,9 @@ public:
   template<unsigned N>
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
+    assert(N);
     if (!Result && Str.size() >= N-1 &&
-        std::memcmp(S, Str.data(), N-1) == 0) {
+        (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) {
       Result = &Value;
     }
     return *this;