libstdc++: Fix test that fails on Solaris [PR104731]

On Solaris the dirent::d_name member is a single char, causing this test
to fail with warnings about buffer overflow. Change the test to use a
union with additional space for writing a string to the d_name member.

libstdc++-v3/ChangeLog:

	PR libstdc++/104731
	* testsuite/27_io/filesystem/iterators/error_reporting.cc:
	Use a trailing char array as storage for dirent::d_name.
This commit is contained in:
Jonathan Wakely 2022-05-06 14:31:06 +01:00
parent e112e37f29
commit aa8bdfee1d

View file

@ -28,35 +28,44 @@
int choice;
struct dirent global_dirent;
extern "C" struct dirent* readdir(DIR*)
{
// On some targets dirent::d_name is very small, but the OS allocates
// a trailing char array after the dirent struct. Emulate that here.
union State
{
struct dirent d;
char buf[sizeof(struct dirent) + 16] = {};
};
static State state;
char* d_name = state.buf + offsetof(struct dirent, d_name);
switch (choice)
{
case 1:
global_dirent.d_ino = 999;
state.d.d_ino = 999;
#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_REG
global_dirent.d_type = DT_REG;
state.d.d_type = DT_REG;
#endif
global_dirent.d_reclen = 0;
std::char_traits<char>::copy(global_dirent.d_name, "file", 5);
state.d.d_reclen = 0;
std::char_traits<char>::copy(d_name, "file", 5);
choice = 0;
return &global_dirent;
return &state.d;
case 2:
global_dirent.d_ino = 111;
state.d.d_ino = 111;
#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_DIR
global_dirent.d_type = DT_DIR;
state.d.d_type = DT_DIR;
#endif
global_dirent.d_reclen = 60;
std::char_traits<char>::copy(global_dirent.d_name, "subdir", 7);
state.d.d_reclen = 60;
std::char_traits<char>::copy(d_name, "subdir", 7);
choice = 1;
return &global_dirent;
return &state.d;
default:
errno = EIO;
return nullptr;
}
return &global_dirent;
return &state.d;
}
void