about summary refs log tree commit diff
path: root/absl/strings
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings')
-rw-r--r--absl/strings/internal/str_format/arg.cc4
-rw-r--r--absl/strings/internal/str_format/arg.h21
-rw-r--r--absl/strings/internal/str_format/checker.h9
-rw-r--r--absl/strings/internal/str_format/extension.h17
4 files changed, 29 insertions, 22 deletions
diff --git a/absl/strings/internal/str_format/arg.cc b/absl/strings/internal/str_format/arg.cc
index 964f25f7da64..02646addec11 100644
--- a/absl/strings/internal/str_format/arg.cc
+++ b/absl/strings/internal/str_format/arg.cc
@@ -302,7 +302,7 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv,
       return ConvertFloatImpl(static_cast<double>(v), conv, sink);
 
     default:
-      return false;
+       ABSL_INTERNAL_ASSUME(false);
   }
 
   if (conv.is_basic()) {
@@ -321,7 +321,6 @@ bool ConvertFloatArg(T v, const FormatConversionSpecImpl conv,
 
 inline bool ConvertStringArg(string_view v, const FormatConversionSpecImpl conv,
                              FormatSinkImpl *sink) {
-  if (conv.conversion_char() != FormatConversionCharInternal::s) return false;
   if (conv.is_basic()) {
     sink->Append(v);
     return true;
@@ -366,7 +365,6 @@ FormatConvertImpl(const char *v, const FormatConversionSpecImpl conv,
 // ==================== Raw pointers ====================
 ArgConvertResult<FormatConversionCharSetInternal::p> FormatConvertImpl(
     VoidPtr v, const FormatConversionSpecImpl conv, FormatSinkImpl *sink) {
-  if (conv.conversion_char() != FormatConversionCharInternal::p) return {false};
   if (!v.value) {
     sink->Append("(nil)");
     return {true};
diff --git a/absl/strings/internal/str_format/arg.h b/absl/strings/internal/str_format/arg.h
index 9a1e5ef276e8..8f79948bd91c 100644
--- a/absl/strings/internal/str_format/arg.h
+++ b/absl/strings/internal/str_format/arg.h
@@ -86,10 +86,6 @@ template <class AbslCord, typename std::enable_if<std::is_same<
 StringConvertResult FormatConvertImpl(const AbslCord& value,
                                       FormatConversionSpecImpl conv,
                                       FormatSinkImpl* sink) {
-  if (conv.conversion_char() != FormatConversionCharInternal::s) {
-    return {false};
-  }
-
   bool is_left = conv.has_left_flag();
   size_t space_remaining = 0;
 
@@ -249,6 +245,15 @@ struct FormatArgImplFriend {
   }
 };
 
+template <typename Arg>
+constexpr FormatConversionCharSet ArgumentToConv() {
+  return absl::str_format_internal::ExtractCharSet(
+      decltype(str_format_internal::FormatConvertImpl(
+          std::declval<const Arg&>(),
+          std::declval<const FormatConversionSpecImpl&>(),
+          std::declval<FormatSinkImpl*>())){});
+}
+
 // A type-erased handle to a format argument.
 class FormatArgImpl {
  private:
@@ -411,9 +416,13 @@ class FormatArgImpl {
       return ToInt<T>(arg, static_cast<int*>(out), std::is_integral<T>(),
                       std::is_enum<T>());
     }
-
+    if (ABSL_PREDICT_FALSE(!Contains(ArgumentToConv<T>(),
+                                     spec.conversion_char()))) {
+      return false;
+    }
     return str_format_internal::FormatConvertImpl(
-               Manager<T>::Value(arg), spec, static_cast<FormatSinkImpl*>(out))
+               Manager<T>::Value(arg), spec,
+               static_cast<FormatSinkImpl*>(out))
         .value;
   }
 
diff --git a/absl/strings/internal/str_format/checker.h b/absl/strings/internal/str_format/checker.h
index 73ef05ff44b3..424c51f74f17 100644
--- a/absl/strings/internal/str_format/checker.h
+++ b/absl/strings/internal/str_format/checker.h
@@ -24,15 +24,6 @@ constexpr bool AllOf(bool b, T... t) {
   return b && AllOf(t...);
 }
 
-template <typename Arg>
-constexpr FormatConversionCharSet ArgumentToConv() {
-  return absl::str_format_internal::ExtractCharSet(
-      decltype(str_format_internal::FormatConvertImpl(
-          std::declval<const Arg&>(),
-          std::declval<const FormatConversionSpecImpl&>(),
-          std::declval<FormatSinkImpl*>())){});
-}
-
 #ifdef ABSL_INTERNAL_ENABLE_FORMAT_CHECKER
 
 constexpr bool ContainsChar(const char* chars, char c) {
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index ce78a02aefbb..36e70646d7d1 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -327,12 +327,16 @@ constexpr FormatConversionCharSet FormatConversionCharSetUnion(
       static_cast<uint64_t>(FormatConversionCharSetUnion(rest...)));
 }
 
+constexpr uint64_t FormatConversionCharToConvInt(FormatConversionChar c) {
+  return uint64_t{1} << (1 + static_cast<uint8_t>(c));
+}
+
 constexpr uint64_t FormatConversionCharToConvInt(char conv) {
   return
-#define ABSL_INTERNAL_CHAR_SET_CASE(c)                                        \
-  conv == #c[0] ? (uint64_t{1} << (1 + static_cast<uint8_t>(                  \
-                                           FormatConversionCharInternal::c))) \
-                :
+#define ABSL_INTERNAL_CHAR_SET_CASE(c)                                 \
+  conv == #c[0]                                                        \
+      ? FormatConversionCharToConvInt(FormatConversionCharInternal::c) \
+      :
       ABSL_INTERNAL_CONVERSION_CHARS_EXPAND_(ABSL_INTERNAL_CHAR_SET_CASE, )
 #undef ABSL_INTERNAL_CHAR_SET_CASE
                   conv == '*'
@@ -406,6 +410,11 @@ constexpr bool Contains(FormatConversionCharSet set,
          static_cast<uint64_t>(c);
 }
 
+// Checks whether all the characters in `c` are contained in `set`
+constexpr bool Contains(FormatConversionCharSet set, FormatConversionChar c) {
+  return (static_cast<uint64_t>(set) & FormatConversionCharToConvInt(c)) != 0;
+}
+
 // Return capacity - used, clipped to a minimum of 0.
 inline size_t Excess(size_t used, size_t capacity) {
   return used < capacity ? capacity - used : 0;