Skip to content

Commit ba9a180

Browse files
derekmaurocopybara-github
authored andcommitted
Fix CHECK_<OP> ambiguous overload for operator<< in older versions of GCC
when C-style strings are compared Regression introduced in 57bc7ed PiperOrigin-RevId: 800142107 Change-Id: Ibafe2dc58b1d1cb0e24e3e0c36d095d35a5f7bd3
1 parent 72d59c9 commit ba9a180

File tree

4 files changed

+22
-13
lines changed

4 files changed

+22
-13
lines changed

absl/log/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ absl_cc_library(
4646
absl::base
4747
absl::config
4848
absl::core_headers
49+
absl::has_ostream_operator
4950
absl::leak_check
5051
absl::log_internal_nullguard
5152
absl::log_internal_nullstream

absl/log/check_test_impl.inc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
// See the License for the specific language governing permissions and
1414
// limitations under the License.
1515

16+
// SKIP_ABSL_INLINE_NAMESPACE_CHECK
17+
1618
#ifndef ABSL_LOG_CHECK_TEST_IMPL_H_
1719
#define ABSL_LOG_CHECK_TEST_IMPL_H_
1820

@@ -241,6 +243,18 @@ TEST(CHECKTest, TestBinaryChecksWithPrimitives) {
241243
ABSL_TEST_CHECK_LT(1, 2);
242244
}
243245

246+
TEST(CHECKTest, TestBinaryChecksWithStringComparison) {
247+
const std::string a = "a";
248+
ABSL_TEST_CHECK_EQ(a, "a");
249+
ABSL_TEST_CHECK_NE(a, "b");
250+
ABSL_TEST_CHECK_GE(a, a);
251+
ABSL_TEST_CHECK_GE("b", a);
252+
ABSL_TEST_CHECK_LE(a, "a");
253+
ABSL_TEST_CHECK_LE(a, "b");
254+
ABSL_TEST_CHECK_GT("b", a);
255+
ABSL_TEST_CHECK_LT(a, "b");
256+
}
257+
244258
// For testing using CHECK*() on anonymous enums.
245259
enum { CASE_A, CASE_B };
246260

absl/log/internal/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ cc_library(
8181
"//absl/base:nullability",
8282
"//absl/debugging:leak_check",
8383
"//absl/strings",
84+
"//absl/strings:has_ostream_operator",
8485
],
8586
)
8687

absl/log/internal/check_op.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "absl/log/internal/nullstream.h"
4141
#include "absl/log/internal/strip.h"
4242
#include "absl/strings/has_absl_stringify.h"
43+
#include "absl/strings/has_ostream_operator.h"
4344
#include "absl/strings/string_view.h"
4445

4546
// `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
@@ -357,21 +358,12 @@ std::enable_if_t<HasAbslStringify<T>::value,
357358
StringifyToStreamWrapper<T>>
358359
Detect(...); // Ellipsis has lowest preference when int passed.
359360

360-
// is_streamable is true for types that have an output stream operator<<.
361-
template <class T, class = void>
362-
struct is_streamable : std::false_type {};
363-
364-
template <class T>
365-
struct is_streamable<T, std::void_t<decltype(std::declval<std::ostream&>()
366-
<< std::declval<T>())>>
367-
: std::true_type {};
368-
369361
// This overload triggers when T is neither possible to print nor an enum.
370362
template <typename T>
371363
std::enable_if_t<std::negation_v<std::disjunction<
372364
std::is_convertible<T, int>, std::is_enum<T>,
373365
std::is_pointer<T>, std::is_same<T, std::nullptr_t>,
374-
is_streamable<T>, HasAbslStringify<T>>>,
366+
HasOstreamOperator<T>, HasAbslStringify<T>>>,
375367
UnprintableWrapper>
376368
Detect(...);
377369

@@ -382,9 +374,10 @@ Detect(...);
382374
// one backed by another integer is converted to (u)int64_t.
383375
template <typename T>
384376
std::enable_if_t<
385-
std::conjunction_v<
386-
std::is_enum<T>, std::negation<std::is_convertible<T, int>>,
387-
std::negation<is_streamable<T>>, std::negation<HasAbslStringify<T>>>,
377+
std::conjunction_v<std::is_enum<T>,
378+
std::negation<std::is_convertible<T, int>>,
379+
std::negation<HasOstreamOperator<T>>,
380+
std::negation<HasAbslStringify<T>>>,
388381
std::conditional_t<
389382
std::is_same_v<std::underlying_type_t<T>, bool> ||
390383
std::is_same_v<std::underlying_type_t<T>, char> ||

0 commit comments

Comments
 (0)