[libcxx-commits] [libcxx] [libcxx][ios] initialize __fill_val_ in _FillHelper (PR #110279)

David Tenty via libcxx-commits libcxx-commits at lists.llvm.org
Fri Sep 27 08:02:58 PDT 2024


https://github.com/daltenty created https://github.com/llvm/llvm-project/pull/110279

This is a small fix to https://github.com/llvm/llvm-project/pull/89305. In the `__init` function of `_FillHelper`, `__fill_val_` was left uninitialized. This worked for the implementation in the PR because we always checked `__set_` before trying to read it, and would initialize if it was unset.

However it turns out in earlier versions of the header (at least on AIX which followed this path), we do a read of the field even if `__set_` was false before initializing to check if it matched the sentinel value, so this causes undesired behaviour and UB.

>From ecb50a92a88b08a451da9b7b1dab6a9146367d54 Mon Sep 17 00:00:00 2001
From: David Tenty <daltenty at ibm.com>
Date: Wed, 25 Sep 2024 16:52:53 -0400
Subject: [PATCH] [libcxx][ios] initialize __fill_val_ in _FillHelper

(cherry picked from commit 6c2bb185d91552032b1140d7c08b43ecf114e066)
---
 libcxx/include/ios | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/ios b/libcxx/include/ios
index 61a05fadd29a17..d4f15a269a11a6 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -524,7 +524,10 @@ template <class _Traits>
 // Attribute 'packed' is used to keep the layout compatible with the previous
 // definition of the '__fill_' and '_set_' pair in basic_ios on AIX & z/OS.
 struct _LIBCPP_PACKED _FillHelper {
-  _LIBCPP_HIDE_FROM_ABI void __init() { __set_ = false; }
+  _LIBCPP_HIDE_FROM_ABI void __init() {
+    __set_      = false;
+    __fill_val_ = _Traits::eof();
+  }
   _LIBCPP_HIDE_FROM_ABI _FillHelper& operator=(typename _Traits::int_type __x) {
     __set_      = true;
     __fill_val_ = __x;



More information about the libcxx-commits mailing list