tolerate padding in mbstate_t
authorAlexandre Oliva <oliva@adacore.com>
Thu, 23 Jan 2020 19:36:34 +0000 (16:36 -0300)
committerAlexandre Oliva <oliva@gnu.org>
Thu, 23 Jan 2020 19:36:34 +0000 (16:36 -0300)
Padding in mbstate_t objects may get the memcmp to fail.
Attempt to avoid the failure with zero initialization.

for  libstdc++-v3/ChangeLog

* testsuite/27_io/fpos/mbstate_t/1.cc: Zero-init mbstate_t.

libstdc++-v3/ChangeLog
libstdc++-v3/testsuite/27_io/fpos/mbstate_t/1.cc

index 539b0f6e593dbea3e4a09ecd83a49083ba8cdfbd..ae1af01840852b33f51f4f116b07dce16f3e61ac 100644 (file)
@@ -1,3 +1,7 @@
+2020-01-23  Alexandre Oliva <oliva@adacore.com>
+
+       * testsuite/27_io/fpos/mbstate_t/1.cc: Zero-init mbstate_t.
+
 2020-01-23  Jonathan Wakely  <jwakely@redhat.com>
 
        PR libstdc++/91947
index f92d68ffefa3823d1cf39a39316e64e4899093b2..28fec8e8ef29771672d6d315c0b44787e0236b44 100644 (file)
 void test01()
 {
   typedef std::mbstate_t state_type;
-  state_type state01 = state_type();
-  state_type state02 = state_type();
+  // Use zero-initialization of the underlying memory so that padding
+  // bytes, if any, stand a better chance of comparing the same.
+  // Zero-initialized memory is guaranteed to be a valid initial
+  // state.  This doesn't quite guarantee that any padding bits won't
+  // be overwritten when copying from other instances that haven't
+  // been fully initialized: this data type is compatible with C, so
+  // it is likely plain old data, but it could have a default ctor
+  // that initializes only the relevant fields, whereas copy-ctor and
+  // operator= could be implemented as a full-object memcpy, including
+  // padding bits, rather than fieldwise copying.  However, since
+  // we're comparing two values copied from the same state_type
+  // instance, if padding bits are copied, we'll get the same for both
+  // of them, and if they aren't, we'll keep the values we initialized
+  // them with, so this should be good.
+  state_type state[2];
+  std::memset(state, 0, sizeof (state));
+
 
   std::streampos pos01(0);
-  std::streampos pos02(0);
 
   // 27.4.3.1 fpos members
   // void state(state_type s);
   // state_type state();
 
   // XXX Need to have better sanity checking for the mbstate_t type,
-  // or whatever the insantiating type for class fpos happens to be
+  // or whatever the instantiating type for class fpos happens to be
   // for streampos, as things like equality operators and assignment
   // operators, increment and deincrement operators need to be in
   // place.
-  pos01.state(state02);
-  state01 = pos01.state();
-  VERIFY( std::memcmp(&state01, &state02, sizeof(state_type)) == 0 );
+  pos01.state(state[1]);
+  state[0] = pos01.state();
+  VERIFY( std::memcmp(&state[0], &state[1], sizeof(state_type)) == 0 );
 }
 
 int main()