[libcxx-commits] [libcxx] ec5f700 - [libc++][format] Addresses LWG3825.

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 14 10:32:47 PDT 2023


Author: Mark de Wever
Date: 2023-03-14T18:32:40+01:00
New Revision: ec5f7004c0878f44843f2a4be1dbda7045a212c1

URL: https://github.com/llvm/llvm-project/commit/ec5f7004c0878f44843f2a4be1dbda7045a212c1
DIFF: https://github.com/llvm/llvm-project/commit/ec5f7004c0878f44843f2a4be1dbda7045a212c1.diff

LOG: [libc++][format] Addresses LWG3825.

  LWG3825 Missing compile-time argument id check in
  basic_format_parse_context::next_arg_id

Reviewed By: #libc, ldionne

Differential Revision: https://reviews.llvm.org/D144327

Added: 
    libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.verify.cpp

Modified: 
    libcxx/docs/Status/Cxx2bIssues.csv
    libcxx/include/__format/format_parse_context.h
    libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index 53f554f968acd..2a8a4dcce9dbd 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -256,7 +256,7 @@
 "`3807 <https://wg21.link/LWG3807>`__","The feature test macro for ``ranges::find_last`` should be renamed","February 2023","","","|ranges|"
 "`3811 <https://wg21.link/LWG3811>`__","``views::as_const`` on ``ref_view<T>`` should return ``ref_view<const T>``","February 2023","","","|ranges|"
 "`3820 <https://wg21.link/LWG3820>`__","``cartesian_product_view::iterator::prev`` is not quite right","February 2023","","","|ranges|"
-"`3825 <https://wg21.link/LWG3825>`__","Missing compile-time argument ``id`` check in ``basic_format_parse_context::next_arg_id``","February 2023","","","|format|"
+"`3825 <https://wg21.link/LWG3825>`__","Missing compile-time argument ``id`` check in ``basic_format_parse_context::next_arg_id``","February 2023","|Complete|","17.0","|format|"
 "`3204 <https://wg21.link/LWG3204>`__","``sub_match::swap`` only swaps the base class","February 2023","|Complete|","17.0",""
 "`3733 <https://wg21.link/LWG3733>`__","``ranges::to`` misuses ``cpp17-input-iterator``","February 2023","","","|ranges|"
 "`3742 <https://wg21.link/LWG3742>`__","``deque::prepend_range`` needs to permute","February 2023","","","|ranges|"

diff  --git a/libcxx/include/__format/format_parse_context.h b/libcxx/include/__format/format_parse_context.h
index fc1d0a3982fe4..ac2f5a843405f 100644
--- a/libcxx/include/__format/format_parse_context.h
+++ b/libcxx/include/__format/format_parse_context.h
@@ -59,6 +59,18 @@ class _LIBCPP_TEMPLATE_VIS _LIBCPP_AVAILABILITY_FORMAT basic_format_parse_contex
 
     if (__indexing_ == __unknown)
       __indexing_ = __automatic;
+
+    // Throws an exception to make the expression a non core constant
+    // expression as required by:
+    // [format.parse.ctx]/8
+    //   Remarks: Let cur-arg-id be the value of next_arg_id_ prior to this
+    //   call. Call expressions where cur-arg-id >= num_args_ is true are not
+    //   core constant expressions (7.7 [expr.const]).
+    // Note: the Throws clause [format.parse.ctx]/9 doesn't specify the
+    // behavior when id >= num_args_.
+    if (is_constant_evaluated() && __next_arg_id_ >= __num_args_)
+      std::__throw_format_error("Argument index outside the valid range");
+
     return __next_arg_id_++;
   }
   _LIBCPP_HIDE_FROM_ABI constexpr void check_arg_id(size_t __id) {

diff  --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp
index dbca19c1d5243..5ec3a943ba974 100644
--- a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp
+++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.pass.cpp
@@ -25,7 +25,7 @@
 #include "test_macros.h"
 
 constexpr bool test() {
-  std::format_parse_context context("");
+  std::format_parse_context context("", 10);
   for (size_t i = 0; i < 10; ++i)
     assert(i == context.next_arg_id());
 

diff  --git a/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.verify.cpp b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.verify.cpp
new file mode 100644
index 0000000000000..f505a605c3e5f
--- /dev/null
+++ b/libcxx/test/std/utilities/format/format.formatter/format.parse.ctx/next_arg_id.verify.cpp
@@ -0,0 +1,33 @@
+//===----------------------------------------------------------------------===//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// UNSUPPORTED: libcpp-has-no-incomplete-format
+
+// constexpr size_t next_arg_id()
+
+#include <format>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  // [format.parse.ctx]/8
+  // Let cur-arg-id be the value of next_arg_id_ prior to this call. Call
+  // expressions where cur-arg-id >= num_args_ is true are not core constant
+  // expressions (7.7 [expr.const]).
+  std::format_parse_context context("", 0);
+  context.next_arg_id();
+
+  return true;
+}
+
+int main(int, char**) {
+  // expected-error-re at +1 {{{{(static_assert|static assertion)}} expression is not an integral constant expression}}
+  static_assert(test());
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list