Skip to content

Commit cceb500

Browse files
author
Tor Didriksen
committed
Bug#37273525 libc++ is deprecating/removing char_traits<unsigned char> [noclose]
The LLVM libc++ library is deprecating/removing char_traits<unsigned char> See https://reviews.llvm.org/D157058 The deprecation comes with clang-18, removal with clang-19 This means that our code using e.g. std::basic_string<uchar> std::basic_ostringstream<unsigned char> will no longer compile for clang/gcc -stdlib=libc++ We usually build with -stdlib=libstdc++ which is the standard library that comes with gcc. The exception is MacOS, where we always use libc++ Implement our own standards-compliant my_char_traits<unsigned char> and use that as a drop-in replacement for std::char_traits<unsigned char> Change-Id: I3cd16503543e74dff852d8708766181807910f00 (cherry picked from commit 0ca5bb128763857c1e5dd6f34796aaa922677611)
1 parent dc78d13 commit cceb500

File tree

4 files changed

+80
-10
lines changed

4 files changed

+80
-10
lines changed

include/my_char_traits.h

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* Copyright (c) 2024, Oracle and/or its affiliates.
2+
3+
This program is free software; you can redistribute it and/or modify
4+
it under the terms of the GNU General Public License, version 2.0,
5+
as published by the Free Software Foundation.
6+
7+
This program is designed to work with certain software (including
8+
but not limited to OpenSSL) that is licensed under separate terms,
9+
as designated in a particular file or component or in included license
10+
documentation. The authors of MySQL hereby grant you an additional
11+
permission to link the program and your derivative works with the
12+
separately licensed software that they have either included with
13+
the program or referenced in the documentation.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU General Public License, version 2.0, for more details.
19+
20+
You should have received a copy of the GNU General Public License
21+
along with this program; if not, write to the Free Software
22+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23+
24+
#ifndef MY_CHAR_TRAITS_INCLUDED
25+
#define MY_CHAR_TRAITS_INCLUDED
26+
27+
#include <cstring>
28+
29+
template <class CharT>
30+
struct my_char_traits;
31+
32+
/*
33+
This is a standards-compliant, drop-in replacement for
34+
std::char_traits<unsigned char>
35+
We need this because clang libc++ is removing support for it in clang 19.
36+
It is not a complete implementation. Rather we implement just enough to
37+
compile any usage of char_traits<uchar> we have in our codebase.
38+
*/
39+
template <>
40+
struct my_char_traits<unsigned char> {
41+
using char_type = unsigned char;
42+
using int_type = unsigned int;
43+
44+
static void assign(char_type &c1, const char_type &c2) { c1 = c2; }
45+
46+
static char_type *assign(char_type *s, std::size_t n, char_type a) {
47+
return static_cast<char_type *>(memset(s, a, n));
48+
}
49+
50+
static int compare(const char_type *s1, const char_type *s2, std::size_t n) {
51+
return memcmp(s1, s2, n);
52+
}
53+
54+
static char_type *move(char_type *s1, const char_type *s2, std::size_t n) {
55+
if (n == 0) return s1;
56+
return static_cast<char_type *>(memmove(s1, s2, n));
57+
}
58+
59+
static char_type *copy(char_type *s1, const char_type *s2, std::size_t n) {
60+
if (n == 0) return s1;
61+
return static_cast<char_type *>(memcpy(s1, s2, n));
62+
}
63+
};
64+
65+
#endif // MY_CHAR_TRAITS_INCLUDED

sql/mdl_context_backup.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <map>
2929
#include <memory>
3030

31+
#include "my_char_traits.h"
3132
#include "sql/malloc_allocator.h"
3233
#include "sql/mdl.h"
3334

@@ -47,7 +48,8 @@ class MDL_context_backup_manager {
4748
/**
4849
Key for uniquely identifying MDL_context in the MDL_context_backup map.
4950
*/
50-
typedef std::basic_string<uchar> MDL_context_backup_key;
51+
using MDL_context_backup_key =
52+
std::basic_string<uchar, my_char_traits<uchar>>;
5153

5254
class MDL_context_backup;
5355

sql/stream_cipher.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,17 @@
2828
#include <memory>
2929
#include <string>
3030

31+
#include "my_char_traits.h"
32+
3133
/**
3234
@file stream_cipher.h
3335
3436
@brief This file includes core components for encrypting/decrypting
3537
binary log files.
3638
*/
3739

38-
typedef std::basic_string<unsigned char> Key_string;
40+
using Key_string =
41+
std::basic_string<unsigned char, my_char_traits<unsigned char>>;
3942

4043
/**
4144
@class Stream_cipher

unittest/gunit/binlogevents/transaction_compression-t.cc

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include <array>
26+
#include <string>
2627

2728
#include <gtest/gtest.h>
2829
#include "mysql/binlog/event/binary_log.h"
@@ -49,13 +50,12 @@ class TransactionPayloadCompressionTest : public ::testing::Test {
4950
using Managed_buffer_t = Decompressor_t::Managed_buffer_t;
5051
using Size_t = Decompressor_t::Size_t;
5152
using Char_t = Decompressor_t::Char_t;
52-
using String_t = std::basic_string<Char_t>;
5353
using Decompress_status_t =
5454
mysql::binlog::event::compression::Decompress_status;
5555
using Compress_status_t = mysql::binlog::event::compression::Compress_status;
5656

57-
static String_t constant_data(Size_t size) {
58-
return String_t(size, (Char_t)'a');
57+
static std::string constant_data(Size_t size) {
58+
return std::string(size, (Char_t)'a');
5959
}
6060

6161
protected:
@@ -66,7 +66,7 @@ class TransactionPayloadCompressionTest : public ::testing::Test {
6666
void TearDown() override {}
6767

6868
static void compression_idempotency_test(Compressor_t &c, Decompressor_t &d,
69-
String_t data) {
69+
const std::string &data) {
7070
auto debug_string = concat(
7171
mysql::binlog::event::compression::type_to_string(c.get_type_code()),
7272
" ", data.size());
@@ -101,8 +101,8 @@ class TransactionPayloadCompressionTest : public ::testing::Test {
101101

102102
// Check decompressed data
103103
ASSERT_EQ(managed_buffer.read_part().size(), data.size()) << debug_string;
104-
ASSERT_EQ(data, String_t(managed_buffer.read_part().begin(),
105-
managed_buffer.read_part().end()))
104+
ASSERT_EQ(data, std::string(managed_buffer.read_part().begin(),
105+
managed_buffer.read_part().end()))
106106
<< debug_string;
107107

108108
// Check that we reached EOF
@@ -115,7 +115,7 @@ TEST_F(TransactionPayloadCompressionTest, CompressDecompressZstdTest) {
115115
for (auto size : buffer_sizes) {
116116
mysql::binlog::event::compression::Zstd_dec d;
117117
mysql::binlog::event::compression::Zstd_comp c;
118-
String_t data{TransactionPayloadCompressionTest::constant_data(size)};
118+
std::string data{TransactionPayloadCompressionTest::constant_data(size)};
119119
TransactionPayloadCompressionTest::compression_idempotency_test(c, d, data);
120120
c.set_compression_level(22);
121121
TransactionPayloadCompressionTest::compression_idempotency_test(c, d, data);
@@ -126,7 +126,7 @@ TEST_F(TransactionPayloadCompressionTest, CompressDecompressNoneTest) {
126126
for (auto size : buffer_sizes) {
127127
mysql::binlog::event::compression::None_dec d;
128128
mysql::binlog::event::compression::None_comp c;
129-
String_t data{TransactionPayloadCompressionTest::constant_data(size)};
129+
std::string data{TransactionPayloadCompressionTest::constant_data(size)};
130130
TransactionPayloadCompressionTest::compression_idempotency_test(c, d, data);
131131
}
132132
}

0 commit comments

Comments
 (0)