Skip to content

Conversation

@Sterling-Augustine
Copy link
Contributor

This is the promised follow-up to #167779. It simply adds a test case provided by philnik777

This is the promised follow-up to llvm#167779. It simply adds a test case.
@Sterling-Augustine Sterling-Augustine requested a review from a team as a code owner November 13, 2025 19:41
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Nov 13, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 13, 2025

@llvm/pr-subscribers-libcxx

Author: None (Sterling-Augustine)

Changes

This is the promised follow-up to #167779. It simply adds a test case provided by philnik777


Full diff: https://github.com/llvm/llvm-project/pull/167937.diff

2 Files Affected:

  • (added) libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp (+72)
  • (added) libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat (+1)
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp
new file mode 100644
index 0000000000000..ec555ea4d259b
--- /dev/null
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.pass.cpp
@@ -0,0 +1,72 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// FILE_DEPENDENCIES: xsgetn.test.dat
+
+// <fstream>
+
+// template <class charT, class traits = char_traits<charT> >
+// class basic_ifstream
+
+// streamsize xsgetn(char_type*, streamsize) override;
+
+// This isn't a required override by the standard, but most implementations override it, since it allows for
+// significantly improved performance in some cases. All of this code is required to work, so this isn't a libc++
+// extension
+
+#include <cassert>
+#include <fstream>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  {
+    char buffer[10];
+    std::ifstream fs("xsgetn.test.dat");
+    std::filebuf* fb = fs.rdbuf();
+    fb->pubsetbuf(buffer, 10);
+
+    // Ensure that the buffer is set up
+    assert(fb->sgetc() == 't');
+
+    std::string str(5, '\0');
+
+    { // Check that a read smaller than the buffer works fine
+      assert(fb->sgetn(str.data(), 5) == 5);
+      assert(str == "this ");
+    }
+    { // Check that reading up to the buffer end works fine
+      assert(fb->sgetn(str.data(), 5) == 5);
+      assert(str == "is so");
+    }
+    { // Check that reading from an empty buffer, but more than the buffer can hold works fine
+      str.resize(12);
+      assert(fb->sgetn(str.data(), 12) == 12);
+      assert(str == "me random da");
+    }
+    { // Check that reading from a non-empty buffer, and more than the buffer can hold works fine
+      // Fill the buffer up
+      str.resize(2);
+      assert(fb->sgetn(str.data(), 2) == 2);
+      assert(str == "ta");
+
+      // Do the actual check
+      str.resize(12);
+      assert(fb->sgetn(str.data(), 12) == 12);
+      assert(str == " to be able ");
+    }
+    { // Check that trying to read more than the file size works fine
+      str.resize(30);
+      assert(fb->sgetn(str.data(), 30) == 24);
+      str.resize(24);
+      assert(str == "to test buffer behaviour");
+    }
+  }
+
+  return 0;
+}
diff --git a/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat
new file mode 100644
index 0000000000000..06d663b9bf23d
--- /dev/null
+++ b/libcxx/test/std/input.output/file.streams/fstreams/ifstream.members/xsgetn.test.dat
@@ -0,0 +1 @@
+this is some random data to be able to test buffer behaviour
\ No newline at end of file

#include "test_macros.h"

int main(int, char**) {
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there an additional scope?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was originally written that way. Removed. Breakages addressed.

Writing data to a buffer obtained by data() is undefined behavior. Fix that.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants