diff --git a/CMakeLists.txt b/CMakeLists.txt index 39352d684..d5acdc0d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,14 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CLANG) set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wframe-larger-than=25344") endif() + # -Wctad-maybe-unsupported was added in Clang 10, which is AppleClang 12.0.0. + if((CMAKE_C_COMPILER_ID STREQUAL "Clang" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0.0") OR + (CMAKE_C_COMPILER_ID STREQUAL "AppleClang" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0.0")) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wctad-maybe-unsupported") + endif() + if(CLANG OR CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0") set(C_CXX_FLAGS "${C_CXX_FLAGS} -Wimplicit-fallthrough") endif() diff --git a/include/openssl/span.h b/include/openssl/span.h index 38196ae8a..4f11559e7 100644 --- a/include/openssl/span.h +++ b/include/openssl/span.h @@ -49,6 +49,16 @@ class SpanBase { friend bool operator!=(Span lhs, Span rhs) { return !(lhs == rhs); } }; + +// Heuristically test whether C is a container type that can be converted into +// a Span by checking for data() and size() member functions. +// +// TODO(davidben): Require C++17 support for std::is_convertible_v, etc. +template +using EnableIfContainer = std::enable_if_t< + std::is_convertible().data()), T *>::value && + std::is_integral().size())>::value>; + } // namespace internal // A Span is a non-owning reference to a contiguous array of objects of type @@ -84,16 +94,6 @@ class SpanBase { // a reference or pointer to a container or array. template class Span : private internal::SpanBase { - private: - // Heuristically test whether C is a container type that can be converted into - // a Span by checking for data() and size() member functions. - // - // TODO(davidben): Require C++17 support for std::is_convertible_v, etc. - template - using EnableIfContainer = std::enable_if_t< - std::is_convertible().data()), T *>::value && - std::is_integral().size())>::value>; - public: static const size_t npos = static_cast(-1); @@ -114,12 +114,12 @@ class Span : private internal::SpanBase { template constexpr Span(T (&array)[N]) : Span(array, N) {} - template , + template , typename = std::enable_if_t::value, C>> constexpr Span(const C &container) : data_(container.data()), size_(container.size()) {} - template , + template , typename = std::enable_if_t::value, C>> constexpr explicit Span(C &container) : data_(container.data()), size_(container.size()) {} @@ -188,6 +188,20 @@ class Span : private internal::SpanBase { template const size_t Span::npos; +#if __cplusplus >= 201703L +template +Span(T *, size_t) -> Span; +template +Span(T (&array)[size]) -> Span; +template < + typename C, + typename T = std::remove_pointer_t().data())>, + typename = internal::EnableIfContainer> +Span(C &) -> Span; +#endif + +// C++17 callers can instead rely on CTAD and the deduction guides defined +// above. template constexpr Span MakeSpan(T *ptr, size_t size) { return Span(ptr, size); diff --git a/pki/cert_error_params.cc b/pki/cert_error_params.cc index 075d7ef33..dd962c43f 100644 --- a/pki/cert_error_params.cc +++ b/pki/cert_error_params.cc @@ -43,11 +43,8 @@ class CertErrorParams2Der : public CertErrorParams { static void AppendDer(const char *name, const std::string &der, std::string *out) { *out += name; - // TODO(crbug.com/boringssl/661): Introduce a convenience function to go - // from a Span to a Span. - *out += - ": " + bssl::string_util::HexEncode(MakeConstSpan( - reinterpret_cast(der.data()), der.size())); + *out += ": "; + *out += bssl::string_util::HexEncode(StringAsBytes(der)); } const char *name1_; diff --git a/pki/input.cc b/pki/input.cc index 156d2485b..2f5a8b162 100644 --- a/pki/input.cc +++ b/pki/input.cc @@ -10,9 +10,7 @@ namespace bssl::der { std::string Input::AsString() const { return std::string(AsStringView()); } -bool operator==(Input lhs, Input rhs) { - return MakeConstSpan(lhs) == MakeConstSpan(rhs); -} +bool operator==(Input lhs, Input rhs) { return Span(lhs) == Span(rhs); } bool operator!=(Input lhs, Input rhs) { return !(lhs == rhs); } diff --git a/pki/input.h b/pki/input.h index 30ce5d4af..6ed79d9e0 100644 --- a/pki/input.h +++ b/pki/input.h @@ -42,16 +42,14 @@ class OPENSSL_EXPORT Input { // Creates an Input from the given |data| and |len|. constexpr explicit Input(const uint8_t *data, size_t len) - : data_(MakeConstSpan(data, len)) {} + : data_(Span(data, len)) {} // Deprecated: Use StringAsBytes. // // Creates an Input from a std::string_view. The constructed Input is only // valid as long as |data| points to live memory. If constructed from, say, a // |std::string|, mutating the vector will invalidate the Input. - explicit Input(std::string_view str) - : data_(MakeConstSpan(reinterpret_cast(str.data()), - str.size())) {} + explicit Input(std::string_view str) : data_(StringAsBytes(str)) {} // The following APIs have the same semantics as in |bssl::Span|. constexpr Span::iterator begin() const { diff --git a/pki/parse_name.cc b/pki/parse_name.cc index f1b3a9188..2c4695f31 100644 --- a/pki/parse_name.cc +++ b/pki/parse_name.cc @@ -129,8 +129,7 @@ bool X509NameAttribute::AsRFC2253String(std::string *out) const { value_string += c; } else if (c < 32 || c > 126) { nonprintable = true; - value_string += - "\\" + bssl::string_util::HexEncode(MakeConstSpan(&c, 1)); + value_string += "\\" + bssl::string_util::HexEncode(Span(&c, 1)); } else { value_string += c; } diff --git a/pki/verify.cc b/pki/verify.cc index e7e4980f3..6bd9dc2d3 100644 --- a/pki/verify.cc +++ b/pki/verify.cc @@ -103,8 +103,7 @@ std::unique_ptr VerifyTrustStore::FromDER( return {}; } - auto parsed_cert = InternalParseCertificate( - Span(CBS_data(&cert), CBS_len(&cert)), out_diagnostic); + auto parsed_cert = InternalParseCertificate(cert, out_diagnostic); if (!parsed_cert.has_value()) { return {}; }