Skip to content

Commit f009f72

Browse files
[libc] Add printf strerror conversion (%m) (#105891)
This patch adds the %m conversion to printf, which prints the strerror(errno). Explanation of why is below, this patch also updates the docs, tests, and build system to accomodate this. The standard for syslog in posix specifies it uses the same format as printf, but adds %m which prints the error message string for the current value of errno. For ease of implementation, it's standard practice for libc implementers to just add %m to printf instead of creating a separate parser for syslog.
1 parent cead904 commit f009f72

File tree

20 files changed

+470
-4
lines changed

20 files changed

+470
-4
lines changed

libc/config/baremetal/config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
},
1717
"LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
1818
"value": false
19+
},
20+
"LIBC_CONF_PRINTF_DISABLE_STRERROR": {
21+
"value": true
1922
}
2023
},
2124
"qsort": {

libc/config/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
"LIBC_CONF_PRINTF_DISABLE_FIXED_POINT": {
2626
"value": false,
2727
"doc": "Disable printing fixed point values in printf and friends."
28+
},
29+
"LIBC_CONF_PRINTF_DISABLE_STRERROR": {
30+
"value": false,
31+
"doc": "Disable handling of %m to print strerror in printf and friends."
2832
}
2933
},
3034
"scanf": {

libc/config/gpu/config.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
},
1717
"LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE": {
1818
"value": false
19+
},
20+
"LIBC_CONF_PRINTF_DISABLE_STRERROR": {
21+
"value": true
1922
}
2023
},
2124
"scanf": {

libc/docs/configure.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ to learn about the defaults for your platform and target.
3838
- ``LIBC_CONF_PRINTF_DISABLE_FIXED_POINT``: Disable printing fixed point values in printf and friends.
3939
- ``LIBC_CONF_PRINTF_DISABLE_FLOAT``: Disable printing floating point values in printf and friends.
4040
- ``LIBC_CONF_PRINTF_DISABLE_INDEX_MODE``: Disable index mode in the printf format string.
41+
- ``LIBC_CONF_PRINTF_DISABLE_STRERROR``: Disable handling of %m to print strerror in printf and friends.
4142
- ``LIBC_CONF_PRINTF_DISABLE_WRITE_INT``: Disable handling of %n in printf format string.
4243
- ``LIBC_CONF_PRINTF_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE``: Use large table for better printf long double performance.
4344
* **"pthread" options**

libc/docs/dev/printf_behavior.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,15 @@ The %r, %R, %k, and %K fixed point number format specifiers are accepted as
213213
defined in ISO/IEC TR 18037 (the fixed point number extension). These are
214214
available when the compiler is detected as having support for fixed point
215215
numbers and the LIBC_COPT_PRINTF_DISABLE_FIXED_POINT flag is not set.
216+
217+
The %m conversion will behave as specified by POSIX for syslog: It takes no
218+
arguments, and outputs the result of strerror(errno). Additionally, to match
219+
existing printf behaviors, it will behave as if it is a %s string conversion for
220+
the purpose of all options, except for the alt form flag. If the alt form flag
221+
is specified, %m will instead output a string matching the macro name of the
222+
value of errno (e.g. "ERANGE" for errno = ERANGE), again treating it as a string
223+
conversion. If there is no corresponding macro, then alt form %m will print the
224+
value of errno as an integer with the %d format, including all options. If
225+
errno = 0 and alt form is specified, the conversion will be a string conversion
226+
on "0" for simplicity of implementation. This matches what other libcs
227+
implementing this feature have done.

libc/src/__support/StringUtil/error_to_string.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ constexpr size_t TOTAL_STR_LEN = total_str_len(PLATFORM_ERRORS);
4545
constexpr size_t ERR_ARRAY_SIZE = max_key_val(PLATFORM_ERRORS) + 1;
4646

4747
constexpr MessageMapper<ERR_ARRAY_SIZE, TOTAL_STR_LEN>
48-
error_mapper(PLATFORM_ERRORS);
48+
ERROR_MAPPER(PLATFORM_ERRORS);
49+
50+
constexpr MessageMapper<ERR_ARRAY_SIZE, TOTAL_STR_LEN>
51+
ERRNO_NAME_MAPPER(PLATFORM_ERRNO_NAMES);
4952

5053
cpp::string_view build_error_string(int err_num, cpp::span<char> buffer) {
5154
// if the buffer can't hold "Unknown error" + ' ' + num_str, then just
@@ -68,11 +71,15 @@ cpp::string_view get_error_string(int err_num) {
6871
}
6972

7073
cpp::string_view get_error_string(int err_num, cpp::span<char> buffer) {
71-
auto opt_str = internal::error_mapper.get_str(err_num);
74+
auto opt_str = internal::ERROR_MAPPER.get_str(err_num);
7275
if (opt_str)
7376
return *opt_str;
7477
else
7578
return internal::build_error_string(err_num, buffer);
7679
}
7780

81+
cpp::optional<cpp::string_view> try_get_errno_name(int err_num) {
82+
return internal::ERRNO_NAME_MAPPER.get_str(err_num);
83+
}
84+
7885
} // namespace LIBC_NAMESPACE_DECL

libc/src/__support/StringUtil/error_to_string.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_ERROR_TO_STRING_H
1010
#define LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_ERROR_TO_STRING_H
1111

12+
#include "src/__support/CPP/optional.h"
1213
#include "src/__support/CPP/span.h"
1314
#include "src/__support/CPP/string_view.h"
1415
#include "src/__support/macros/config.h"
@@ -19,6 +20,8 @@ cpp::string_view get_error_string(int err_num);
1920

2021
cpp::string_view get_error_string(int err_num, cpp::span<char> buffer);
2122

23+
cpp::optional<cpp::string_view> try_get_errno_name(int err_num);
24+
2225
} // namespace LIBC_NAMESPACE_DECL
2326

2427
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_ERROR_TO_STRING_H

libc/src/__support/StringUtil/tables/linux_extension_errors.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,61 @@ constexpr MsgTable<52> LINUX_ERRORS = {
7171
MsgMapping(EHWPOISON, "Memory page has hardware error"),
7272
};
7373

74+
constexpr MsgTable<52> LINUX_ERRNO_NAMES = {
75+
MsgMapping(ENOTBLK, "ENOTBLK"),
76+
MsgMapping(ECHRNG, "ECHRNG"),
77+
MsgMapping(EL2NSYNC, "EL2NSYNC"),
78+
MsgMapping(EL3HLT, "EL3HLT"),
79+
MsgMapping(EL3RST, "EL3RST"),
80+
MsgMapping(ELNRNG, "ELNRNG"),
81+
MsgMapping(EUNATCH, "EUNATCH"),
82+
MsgMapping(ENOCSI, "ENOCSI"),
83+
MsgMapping(EL2HLT, "EL2HLT"),
84+
MsgMapping(EBADE, "EBADE"),
85+
MsgMapping(EBADR, "EBADR"),
86+
MsgMapping(EXFULL, "EXFULL"),
87+
MsgMapping(ENOANO, "ENOANO"),
88+
MsgMapping(EBADRQC, "EBADRQC"),
89+
MsgMapping(EBADSLT, "EBADSLT"),
90+
MsgMapping(EBFONT, "EBFONT"),
91+
MsgMapping(ENONET, "ENONET"),
92+
MsgMapping(ENOPKG, "ENOPKG"),
93+
MsgMapping(EREMOTE, "EREMOTE"),
94+
MsgMapping(EADV, "EADV"),
95+
MsgMapping(ESRMNT, "ESRMNT"),
96+
MsgMapping(ECOMM, "ECOMM"),
97+
MsgMapping(EDOTDOT, "EDOTDOT"),
98+
MsgMapping(ENOTUNIQ, "ENOTUNIQ"),
99+
MsgMapping(EBADFD, "EBADFD"),
100+
MsgMapping(EREMCHG, "EREMCHG"),
101+
MsgMapping(ELIBACC, "ELIBACC"),
102+
MsgMapping(ELIBBAD, "ELIBBAD"),
103+
MsgMapping(ELIBSCN, "ELIBSCN"),
104+
MsgMapping(ELIBMAX, "ELIBMAX"),
105+
MsgMapping(ELIBEXEC, "ELIBEXEC"),
106+
MsgMapping(ERESTART, "ERESTART"),
107+
MsgMapping(ESTRPIPE, "ESTRPIPE"),
108+
MsgMapping(EUSERS, "EUSERS"),
109+
MsgMapping(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"),
110+
MsgMapping(EPFNOSUPPORT, "EPFNOSUPPORT"),
111+
MsgMapping(ESHUTDOWN, "ESHUTDOWN"),
112+
MsgMapping(ETOOMANYREFS, "ETOOMANYREFS"),
113+
MsgMapping(EHOSTDOWN, "EHOSTDOWN"),
114+
MsgMapping(EUCLEAN, "EUCLEAN"),
115+
MsgMapping(ENOTNAM, "ENOTNAM"),
116+
MsgMapping(ENAVAIL, "ENAVAIL"),
117+
MsgMapping(EISNAM, "EISNAM"),
118+
MsgMapping(EREMOTEIO, "EREMOTEIO"),
119+
MsgMapping(ENOMEDIUM, "ENOMEDIUM"),
120+
MsgMapping(EMEDIUMTYPE, "EMEDIUMTYPE"),
121+
MsgMapping(ENOKEY, "ENOKEY"),
122+
MsgMapping(EKEYEXPIRED, "EKEYEXPIRED"),
123+
MsgMapping(EKEYREVOKED, "EKEYREVOKED"),
124+
MsgMapping(EKEYREJECTED, "EKEYREJECTED"),
125+
MsgMapping(ERFKILL, "ERFKILL"),
126+
MsgMapping(EHWPOISON, "EHWPOISON"),
127+
};
128+
74129
} // namespace LIBC_NAMESPACE_DECL
75130

76131
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_EXTENSION_ERRORS_H

libc/src/__support/StringUtil/tables/linux_platform_errors.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ namespace LIBC_NAMESPACE_DECL {
1919
LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS =
2020
STDC_ERRORS + POSIX_ERRORS + LINUX_ERRORS;
2121

22+
LIBC_INLINE_VAR constexpr auto PLATFORM_ERRNO_NAMES =
23+
STDC_ERRNO_NAMES + POSIX_ERRNO_NAMES + LINUX_ERRNO_NAMES;
24+
2225
} // namespace LIBC_NAMESPACE_DECL
2326

2427
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_LINUX_PLATFORM_ERRORS_H

libc/src/__support/StringUtil/tables/minimal_platform_errors.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace LIBC_NAMESPACE_DECL {
1616

1717
LIBC_INLINE_VAR constexpr auto PLATFORM_ERRORS = STDC_ERRORS;
1818

19+
LIBC_INLINE_VAR constexpr auto PLATFORM_ERRNO_NAMES = STDC_ERRNO_NAMES;
20+
1921
} // namespace LIBC_NAMESPACE_DECL
2022

2123
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_MINIMAL_PLATFORM_ERRORS_H

libc/src/__support/StringUtil/tables/posix_errors.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,85 @@ LIBC_INLINE_VAR constexpr MsgTable<76> POSIX_ERRORS = {
9595
MsgMapping(ENOTRECOVERABLE, "State not recoverable"),
9696
};
9797

98+
LIBC_INLINE_VAR constexpr MsgTable<76> POSIX_ERRNO_NAMES = {
99+
MsgMapping(EPERM, "EPERM"),
100+
MsgMapping(ENOENT, "ENOENT"),
101+
MsgMapping(ESRCH, "ESRCH"),
102+
MsgMapping(EINTR, "EINTR"),
103+
MsgMapping(EIO, "EIO"),
104+
MsgMapping(ENXIO, "ENXIO"),
105+
MsgMapping(E2BIG, "E2BIG"),
106+
MsgMapping(ENOEXEC, "ENOEXEC"),
107+
MsgMapping(EBADF, "EBADF"),
108+
MsgMapping(ECHILD, "ECHILD"),
109+
MsgMapping(EAGAIN, "EAGAIN"),
110+
MsgMapping(ENOMEM, "ENOMEM"),
111+
MsgMapping(EACCES, "EACCES"),
112+
MsgMapping(EFAULT, "EFAULT"),
113+
MsgMapping(EBUSY, "EBUSY"),
114+
MsgMapping(EEXIST, "EEXIST"),
115+
MsgMapping(EXDEV, "EXDEV"),
116+
MsgMapping(ENODEV, "ENODEV"),
117+
MsgMapping(ENOTDIR, "ENOTDIR"),
118+
MsgMapping(EISDIR, "EISDIR"),
119+
MsgMapping(EINVAL, "EINVAL"),
120+
MsgMapping(ENFILE, "ENFILE"),
121+
MsgMapping(EMFILE, "EMFILE"),
122+
MsgMapping(ENOTTY, "ENOTTY"),
123+
MsgMapping(ETXTBSY, "ETXTBSY"),
124+
MsgMapping(EFBIG, "EFBIG"),
125+
MsgMapping(ENOSPC, "ENOSPC"),
126+
MsgMapping(ESPIPE, "ESPIPE"),
127+
MsgMapping(EROFS, "EROFS"),
128+
MsgMapping(EMLINK, "EMLINK"),
129+
MsgMapping(EPIPE, "EPIPE"),
130+
MsgMapping(EDEADLK, "EDEADLK"),
131+
MsgMapping(ENAMETOOLONG, "ENAMETOOLONG"),
132+
MsgMapping(ENOLCK, "ENOLCK"),
133+
MsgMapping(ENOSYS, "ENOSYS"),
134+
MsgMapping(ENOTEMPTY, "ENOTEMPTY"),
135+
MsgMapping(ELOOP, "ELOOP"),
136+
MsgMapping(ENOMSG, "ENOMSG"),
137+
MsgMapping(EIDRM, "EIDRM"),
138+
MsgMapping(ENOSTR, "ENOSTR"),
139+
MsgMapping(ENODATA, "ENODATA"),
140+
MsgMapping(ETIME, "ETIME"),
141+
MsgMapping(ENOSR, "ENOSR"),
142+
MsgMapping(ENOLINK, "ENOLINK"),
143+
MsgMapping(EPROTO, "EPROTO"),
144+
MsgMapping(EMULTIHOP, "EMULTIHOP"),
145+
MsgMapping(EBADMSG, "EBADMSG"),
146+
MsgMapping(EOVERFLOW, "EOVERFLOW"),
147+
MsgMapping(ENOTSOCK, "ENOTSOCK"),
148+
MsgMapping(EDESTADDRREQ, "EDESTADDRREQ"),
149+
MsgMapping(EMSGSIZE, "EMSGSIZE"),
150+
MsgMapping(EPROTOTYPE, "EPROTOTYPE"),
151+
MsgMapping(ENOPROTOOPT, "ENOPROTOOPT"),
152+
MsgMapping(EPROTONOSUPPORT, "EPROTONOSUPPORT"),
153+
MsgMapping(ENOTSUP, "ENOTSUP"),
154+
MsgMapping(EAFNOSUPPORT, "EAFNOSUPPORT"),
155+
MsgMapping(EADDRINUSE, "EADDRINUSE"),
156+
MsgMapping(EADDRNOTAVAIL, "EADDRNOTAVAIL"),
157+
MsgMapping(ENETDOWN, "ENETDOWN"),
158+
MsgMapping(ENETUNREACH, "ENETUNREACH"),
159+
MsgMapping(ENETRESET, "ENETRESET"),
160+
MsgMapping(ECONNABORTED, "ECONNABORTED"),
161+
MsgMapping(ECONNRESET, "ECONNRESET"),
162+
MsgMapping(ENOBUFS, "ENOBUFS"),
163+
MsgMapping(EISCONN, "EISCONN"),
164+
MsgMapping(ENOTCONN, "ENOTCONN"),
165+
MsgMapping(ETIMEDOUT, "ETIMEDOUT"),
166+
MsgMapping(ECONNREFUSED, "ECONNREFUSED"),
167+
MsgMapping(EHOSTUNREACH, "EHOSTUNREACH"),
168+
MsgMapping(EALREADY, "EALREADY"),
169+
MsgMapping(EINPROGRESS, "EINPROGRESS"),
170+
MsgMapping(ESTALE, "ESTALE"),
171+
MsgMapping(EDQUOT, "EDQUOT"),
172+
MsgMapping(ECANCELED, "ECANCELED"),
173+
MsgMapping(EOWNERDEAD, "EOWNERDEAD"),
174+
MsgMapping(ENOTRECOVERABLE, "ENOTRECOVERABLE"),
175+
};
176+
98177
} // namespace LIBC_NAMESPACE_DECL
99178

100179
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_POSIX_ERRORS_H

libc/src/__support/StringUtil/tables/stdc_errors.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ LIBC_INLINE_VAR constexpr const MsgTable<4> STDC_ERRORS = {
2323
MsgMapping(EILSEQ, "Invalid or incomplete multibyte or wide character"),
2424
};
2525

26+
LIBC_INLINE_VAR constexpr const MsgTable<4> STDC_ERRNO_NAMES = {
27+
MsgMapping(0, "0"),
28+
MsgMapping(EDOM, "EDOM"),
29+
MsgMapping(ERANGE, "ERANGE"),
30+
MsgMapping(EILSEQ, "EILSEQ"),
31+
};
32+
2633
} // namespace LIBC_NAMESPACE_DECL
2734

2835
#endif // LLVM_LIBC_SRC___SUPPORT_STRINGUTIL_TABLES_STDC_ERRORS_H

libc/src/stdio/printf_core/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ endif()
1313
if(LIBC_CONF_PRINTF_DISABLE_FIXED_POINT)
1414
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_DISABLE_FIXED_POINT")
1515
endif()
16+
if(LIBC_CONF_PRINTF_DISABLE_STRERROR)
17+
list(APPEND printf_config_copts "-DLIBC_COPT_PRINTF_DISABLE_STRERROR")
18+
endif()
1619
if(printf_config_copts)
1720
list(PREPEND printf_config_copts "COMPILE_OPTIONS")
1821
endif()
@@ -81,6 +84,7 @@ add_object_library(
8184
float_hex_converter.h
8285
float_dec_converter.h
8386
fixed_converter.h #TODO: Check if this should be disabled when fixed unavail
87+
strerror_converter.h
8488
DEPENDS
8589
.core_structs
8690
.printf_config
@@ -97,6 +101,7 @@ add_object_library(
97101
libc.src.__support.integer_to_string
98102
libc.src.__support.libc_assert
99103
libc.src.__support.uint128
104+
libc.src.__support.StringUtil.error_to_string
100105
)
101106

102107
add_object_library(

libc/src/stdio/printf_core/converter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "src/__support/macros/config.h"
1212
#include "src/stdio/printf_core/core_structs.h"
1313
#include "src/stdio/printf_core/printf_config.h"
14+
#include "src/stdio/printf_core/strerror_converter.h"
1415
#include "src/stdio/printf_core/writer.h"
1516

1617
// This option allows for replacing all of the conversion functions with custom
@@ -84,6 +85,10 @@ int convert(Writer *writer, const FormatSection &to_conv) {
8485
case 'K':
8586
return convert_fixed(writer, to_conv);
8687
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
88+
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
89+
case 'm':
90+
return convert_strerror(writer, to_conv);
91+
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
8792
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
8893
case 'n':
8994
return convert_write_int(writer, to_conv);

libc/src/stdio/printf_core/converter_atlas.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@
4343
// defines convert_pointer
4444
#include "src/stdio/printf_core/ptr_converter.h"
4545

46+
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
47+
// defines convert_strerror
48+
#include "src/stdio/printf_core/strerror_converter.h"
49+
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
50+
4651
#endif // LLVM_LIBC_SRC_STDIO_PRINTF_CORE_CONVERTER_ATLAS_H

libc/src/stdio/printf_core/parser.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#ifdef LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
2525
#include "src/__support/fixed_point/fx_rep.h"
2626
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
27+
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
28+
#include "src/errno/libc_errno.h"
29+
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
2730

2831
namespace LIBC_NAMESPACE_DECL {
2932
namespace printf_core {
@@ -258,9 +261,16 @@ template <typename ArgProvider> class Parser {
258261
}
259262
break;
260263
#endif // LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
264+
#ifndef LIBC_COPT_PRINTF_DISABLE_STRERROR
265+
case ('m'):
266+
// %m is an odd conversion in that it doesn't consume an argument, it
267+
// just takes the current value of errno as its argument.
268+
section.conv_val_raw = libc_errno;
269+
break;
270+
#endif // LIBC_COPT_PRINTF_DISABLE_STRERROR
261271
#ifndef LIBC_COPT_PRINTF_DISABLE_WRITE_INT
262-
case ('n'):
263-
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
272+
case ('n'): // Intentional fallthrough
273+
#endif // LIBC_COPT_PRINTF_DISABLE_WRITE_INT
264274
case ('p'):
265275
WRITE_ARG_VAL_SIMPLEST(section.conv_val_ptr, void *, conv_index);
266276
break;

0 commit comments

Comments
 (0)