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

source/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
"8B19:1018"
1+
"8B20:1424"

source/reflect.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,7 @@ namespace meta {
753753
[[nodiscard]] auto compiler_services::get_argument(cpp2::in<int> index) & -> std::string{
754754
metafunctions_used = true;
755755
if (([_0 = 0, _1 = index, _2 = CPP2_UFCS_0(ssize, metafunction_args)]{ return cpp2::cmp_less_eq(_0,_1) && cpp2::cmp_less(_1,_2); }())) {
756-
return cpp2::assert_in_bounds(metafunction_args, index);
756+
return CPP2_ASSERT_IN_BOUNDS(metafunction_args, index);
757757
}
758758
return "";
759759
}
@@ -1395,7 +1395,7 @@ std::string value = "-1";
13951395

13961396
nextval(value, init);
13971397

1398-
auto v {std::strtoll(&cpp2::assert_in_bounds(value, 0), nullptr, 10)}; // for non-numeric values we'll just get 0 which is okay for now
1398+
auto v {std::strtoll(&CPP2_ASSERT_IN_BOUNDS(value, 0), nullptr, 10)}; // for non-numeric values we'll just get 0 which is okay for now
13991399
if (cpp2::cmp_less(v,min_value)) {
14001400
min_value = v;
14011401
}
@@ -1535,7 +1535,7 @@ auto cpp2_enum(meta::type_declaration& t) -> void
15351535
if (!(CPP2_UFCS_0(empty, specified_value))) {
15361536
value = specified_value;
15371537
}else {
1538-
auto v {std::strtoll(&cpp2::assert_in_bounds(value, 0), nullptr, 10)};
1538+
auto v {std::strtoll(&CPP2_ASSERT_IN_BOUNDS(value, 0), nullptr, 10)};
15391539
value = cpp2::as_<std::string>((std::move(v) + 1));
15401540
}
15411541
},
@@ -1552,7 +1552,7 @@ auto flag_enum(meta::type_declaration& t) -> void
15521552
if (!(CPP2_UFCS_0(empty, specified_value))) {
15531553
value = specified_value;
15541554
}else {
1555-
auto v {std::strtoll(&cpp2::assert_in_bounds(value, 0), nullptr, 10)};
1555+
auto v {std::strtoll(&CPP2_ASSERT_IN_BOUNDS(value, 0), nullptr, 10)};
15561556
if (cpp2::cmp_less(v,1)) {
15571557
value = "1";
15581558
}
@@ -1810,7 +1810,7 @@ auto print(cpp2::in<meta::type_declaration> t) -> void
18101810
&& !(CPP2_UFCS_0(arguments_were_used, rtype))))
18111811

18121812
{
1813-
error(name + " did not use its template arguments - did you mean to write '" + name + " <" + cpp2::assert_in_bounds(args, 0) + "> type' (with the spaces)?");
1813+
error(name + " did not use its template arguments - did you mean to write '" + name + " <" + CPP2_ASSERT_IN_BOUNDS(args, 0) + "> type' (with the spaces)?");
18141814
return false;
18151815
}
18161816
}

source/to_cpp1.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3178,7 +3178,7 @@ class cppfront
31783178
&& std::ssize(i->expr_list->expressions) == 1
31793179
)
31803180
{
3181-
prefix.emplace_back( "cpp2::assert_in_bounds(", i->op->position() );
3181+
prefix.emplace_back( "CPP2_ASSERT_IN_BOUNDS(", i->op->position() );
31823182
suffix.emplace_back( ", ", i->op->position() );
31833183
}
31843184
else {
@@ -5342,7 +5342,7 @@ class cppfront
53425342

53435343
auto func_name = n.name()->to_string();
53445344

5345-
// If it's a single named value, emit it as an aonymous return value
5345+
// If it's a single named value, emit it as an anonymous return value
53465346
if (std::ssize(r->parameters) == 1)
53475347
{
53485348
printer.print_extra(

0 commit comments

Comments
 (0)