Skip to content

Commit 986fe31

Browse files
committed
fix(cpp1): support empty and multi-argument indexing
1 parent 52a2798 commit 986fe31

7 files changed

+58
-7
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
t: type = {
2+
operator[]: (inout this) -> i32 = 1;
3+
operator[]: (inout this, x: _) -> i32 = 2;
4+
operator[]: (inout this, x: _, y: _) -> i32 = 3;
5+
}
6+
main: () = {
7+
[[assert: t()[] == 1]]
8+
[[assert: t()[1] == 2]]
9+
[[assert: t()[1, 2] == 3]]
10+
}

regression-tests/test-results/gcc-13/pure2-bugfix-for-empty-index.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-bugfix-for-empty-index.cpp.output

Whitespace-only changes.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
#line 1 "pure2-bugfix-for-empty-index.cpp2"
10+
class t;
11+
12+
13+
//=== Cpp2 type definitions and function declarations ===========================
14+
15+
#line 1 "pure2-bugfix-for-empty-index.cpp2"
16+
class t {
17+
public: [[nodiscard]] auto operator[]() -> cpp2::i32;
18+
public: [[nodiscard]] auto operator[](auto const& x) -> cpp2::i32;
19+
public: [[nodiscard]] auto operator[](auto const& x, auto const& y) -> cpp2::i32;
20+
21+
public: t() = default;
22+
public: t(t const&) = delete; /* No 'that' constructor, suppress copy */
23+
public: auto operator=(t const&) -> void = delete;
24+
#line 5 "pure2-bugfix-for-empty-index.cpp2"
25+
};
26+
auto main() -> int;
27+
28+
29+
//=== Cpp2 function definitions =================================================
30+
31+
32+
#line 2 "pure2-bugfix-for-empty-index.cpp2"
33+
[[nodiscard]] auto t::operator[]() -> cpp2::i32 { return 1; }
34+
[[nodiscard]] auto t::operator[](auto const& x) -> cpp2::i32 { return 2; }
35+
[[nodiscard]] auto t::operator[](auto const& x, auto const& y) -> cpp2::i32 { return 3; }
36+
37+
auto main() -> int{
38+
cpp2::Default.expects(t()[]==1, "");
39+
cpp2::Default.expects(cpp2::assert_in_bounds(t(), 1)==2, "");
40+
cpp2::Default.expects(t()[1, 2]==3, "");
41+
}
42+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-bugfix-for-empty-index.cpp2... ok (all Cpp2, passes safety checks)
2+

source/cppfront.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3029,6 +3029,7 @@ class cppfront
30293029
if (
30303030
flag_safe_subscripts
30313031
&& i->op->type() == lexeme::LeftBracket
3032+
&& std::ssize(i->expr_list->expressions) == 1
30323033
)
30333034
{
30343035
suffix.emplace_back( ")", i->op->position() );
@@ -3065,6 +3066,7 @@ class cppfront
30653066
if (
30663067
flag_safe_subscripts
30673068
&& i->op->type() == lexeme::LeftBracket
3069+
&& std::ssize(i->expr_list->expressions) == 1
30683070
)
30693071
{
30703072
prefix.emplace_back( "cpp2::assert_in_bounds(", i->op->position() );

source/parse.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4084,7 +4084,7 @@ class parser
40844084
//G postfix-expression:
40854085
//G primary-expression
40864086
//G postfix-expression postfix-operator [Note: without whitespace before the operator]
4087-
//G postfix-expression '[' expression-list ']'
4087+
//G postfix-expression '[' expression-list? ']'
40884088
//G postfix-expression '(' expression-list? ')'
40894089
//G postfix-expression '.' id-expression
40904090
//G
@@ -4161,13 +4161,8 @@ class parser
41614161
if (term.op->type() == lexeme::LeftBracket)
41624162
{
41634163
term.expr_list = expression_list(term.op);
4164-
if (
4165-
!term.expr_list
4166-
|| term.expr_list->expressions.empty()
4167-
)
4164+
if (!term.expr_list)
41684165
{
4169-
error("subscript expression [ ] must not be empty (if you were trying to name a C-style array type, use 'std::array' instead)");
4170-
next();
41714166
return {};
41724167
}
41734168
if (curr().type() != lexeme::RightBracket)

0 commit comments

Comments
 (0)