Skip to content

Commit 0b333f3

Browse files
committed
Avoid forwarding a bounds-checked subscript operation, closes #799
1 parent 8c934bf commit 0b333f3

13 files changed

+26
-26
lines changed

include/cpp2util.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,22 +457,22 @@ auto assert_not_null(auto&& p CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> declty
457457

458458
// Subscript bounds checking
459459
//
460-
auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
460+
auto assert_in_bounds_impl(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> void
461461
requires (std::is_integral_v<CPP2_TYPEOF(arg)> &&
462462
requires { std::size(x); std::ssize(x); x[arg]; std::begin(x) + 2; })
463463
{
464464
Bounds.expects(0 <= arg && arg < [&]() -> auto {
465465
if constexpr (std::is_signed_v<CPP2_TYPEOF(arg)>) { return std::ssize(x); }
466466
else { return std::size(x); }
467467
}(), "out of bounds access attempt detected" CPP2_SOURCE_LOCATION_ARG);
468-
return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
469468
}
470469

471-
auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
470+
auto assert_in_bounds_impl(auto&&, auto&& CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> void
472471
{
473-
return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
474472
}
475473

474+
#define CPP2_ASSERT_IN_BOUNDS(x, arg) (cpp2::assert_in_bounds_impl((x),(arg)), (x)[(arg)])
475+
476476

477477
//-----------------------------------------------------------------------
478478
//

regression-tests/test-results/mixed-bounds-check.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@
2727

2828
std::vector v {1, 2, 3, 4, 5, -999};
2929
CPP2_UFCS_0(pop_back, v);
30-
std::cout << cpp2::assert_in_bounds(std::move(v), 5) << "\n";
30+
std::cout << CPP2_ASSERT_IN_BOUNDS(std::move(v), 5) << "\n";
3131
}
3232

regression-tests/test-results/mixed-test-parens.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ constexpr int a = 1;
2828
#line 8 "mixed-test-parens.cpp2"
2929
[[nodiscard]] auto main() -> int{
3030
std::vector<int> v {1, 2, 3};
31-
std::cout << (1 + 2) * (3 + cpp2::assert_in_bounds(std::move(v), 0));
31+
std::cout << (1 + 2) * (3 + CPP2_ASSERT_IN_BOUNDS(std::move(v), 0));
3232
f<(cpp2::cmp_greater(1,2))>(3, 4);
3333
f<a + a>(5, 6);
3434
}

regression-tests/test-results/pure2-bounds-safety-span.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ auto print_and_decorate(auto const& thing) -> void;
3636

3737
auto i {0};
3838
for( ; cpp2::cmp_less(i,CPP2_UFCS_0(ssize, s)); ++i ) {
39-
print_and_decorate(cpp2::assert_in_bounds(s, i));
39+
print_and_decorate(CPP2_ASSERT_IN_BOUNDS(s, i));
4040
}
4141
}
4242

regression-tests/test-results/pure2-bugfix-for-non-local-initialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ auto main() -> int;
2828

2929
#line 5 "pure2-bugfix-for-non-local-initialization.cpp2"
3030
auto main() -> int{
31-
cpp2::Testing.expects(cpp2::assert_in_bounds(t::value, 0) == 17, "");
32-
cpp2::Testing.expects(cpp2::assert_in_bounds(t::value, 1) == 29, "");
31+
cpp2::Testing.expects(CPP2_ASSERT_IN_BOUNDS(t::value, 0) == 17, "");
32+
cpp2::Testing.expects(CPP2_ASSERT_IN_BOUNDS(t::value, 1) == 29, "");
3333
}
3434

regression-tests/test-results/pure2-intro-example-three-loops.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ auto decorate_and_print(auto& thing) -> void{
4545

4646
auto i {cpp2_new<int>(0)};
4747
for( ; cpp2::cmp_less(*cpp2::assert_not_null(i),CPP2_UFCS_0(ssize, view)); ++*cpp2::assert_not_null(i) ) {
48-
print(cpp2::assert_in_bounds(view, *cpp2::assert_not_null(i)));
48+
print(CPP2_ASSERT_IN_BOUNDS(view, *cpp2::assert_not_null(i)));
4949
}
5050

5151
do {

regression-tests/test-results/pure2-main-args.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ auto main(int const argc_, char** argv_) -> int {
2222
#line 2 "pure2-main-args.cpp2"
2323
std::cout
2424
<< "args.argc is " + cpp2::to_string(args.argc) + "\n"
25-
<< "args.argv[0] is " + cpp2::to_string(cpp2::assert_in_bounds(args.argv, 0)) + "\n"; }
25+
<< "args.argv[0] is " + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(args.argv, 0)) + "\n"; }
2626

regression-tests/test-results/pure2-print.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
102102
ret += strlen(s) - 10 + CPP2_UFCS_0(strlen, std::move(s)) * (16 / (3 & 2)) % 3;
103103

104104
map<int const,string> m {};
105-
cpp2::assert_in_bounds(m, 0) = cpp2::as_<string>("har");
105+
CPP2_ASSERT_IN_BOUNDS(m, 0) = cpp2::as_<string>("har");
106106
ret -= CPP2_UFCS_0(length, h("x", m));
107107
static_cast<void>(std::move(m));
108108

@@ -133,7 +133,7 @@ requires (true) inline CPP2_CONSTEXPR T outer::object_alias = 42;
133133

134134
cpp2::Default.expects(true, "");
135135

136-
return [_0 = (s + cpp2::assert_in_bounds(m, 0))]() -> std::string { return _0; }();
136+
return [_0 = (s + CPP2_ASSERT_IN_BOUNDS(m, 0))]() -> std::string { return _0; }();
137137
}
138138

139139
template<typename T> [[nodiscard]] auto outer::mytype::values([[maybe_unused]] T const& unnamed_param_2) const& -> values_ret{

regression-tests/test-results/pure2-raw-string-literal-and-interpolation.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
#line 2 "pure2-raw-string-literal-and-interpolation.cpp2"
2222
auto i {42};
2323
std::map<std::string,int> m {};
24-
cpp2::assert_in_bounds(m, "one") = 1;
25-
cpp2::assert_in_bounds(m, "two") = 2;
24+
CPP2_ASSERT_IN_BOUNDS(m, "one") = 1;
25+
CPP2_ASSERT_IN_BOUNDS(m, "two") = 2;
2626

2727
std::string str {"this is a string"};
2828

@@ -38,7 +38,7 @@ lines)test"};
3838
that can last for multiple
3939
lines
4040
)test" + cpp2::to_string(i) + R"test( R"(this can be added too)"
41-
calculations like m["one"] + m["two"] = )test" + cpp2::to_string(cpp2::assert_in_bounds(m, "one") + cpp2::assert_in_bounds(m, "two")) + R"test( also works
41+
calculations like m["one"] + m["two"] = )test" + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(m, "one") + CPP2_ASSERT_IN_BOUNDS(m, "two")) + R"test( also works
4242
)test" + cpp2::to_string("at the beginning of the line") + R"test(!!!)test"};
4343

4444
std::string raw_str_inter_multi {R"(
@@ -50,6 +50,6 @@ calculations like m["one"] + m["two"] = )test" + cpp2::to_string(cpp2::assert_in
5050
std::cout << std::move(raw_str_multi) << std::endl;
5151
std::cout << std::move(raw_str_inter) << std::endl;
5252
std::cout << std::move(raw_str_inter_multi) << std::endl;
53-
std::cout << (cpp2::to_string(cpp2::assert_in_bounds(m, "one")) + R"(.)" + cpp2::to_string(cpp2::assert_in_bounds(m, "two")) + R"(.)" + cpp2::to_string(cpp2::assert_in_bounds(std::move(m), "three")) + R"(.)" + cpp2::to_string(std::move(i))) << std::endl;
53+
std::cout << (cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(m, "one")) + R"(.)" + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(m, "two")) + R"(.)" + cpp2::to_string(CPP2_ASSERT_IN_BOUNDS(std::move(m), "three")) + R"(.)" + cpp2::to_string(std::move(i))) << std::endl;
5454
}
5555

regression-tests/test-results/version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
cppfront compiler v0.3.0 Build 8B19:1018
2+
cppfront compiler v0.3.0 Build 8B20:1424
33
Copyright(c) Herb Sutter All rights reserved
44

55
SPDX-License-Identifier: CC-BY-NC-ND-4.0

0 commit comments

Comments
 (0)