From 1ac3353e9f831748d7d9b89f8e8de6e41ecac02e Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Thu, 1 Oct 2026 16:59:11 -0400 Subject: [PATCH] Fix C++-generating back end issue with dependent multi-dimensional subscripts [GH #195] --- src/Changes | 24 +++++++++++++++++++ src/cp_gen_be.c | 24 +++++++++++++------ .../regressions/.gh-195.rto/default.1.1.txt | 1 + tests/tests/regressions/gh-195.sft.cpp | 9 +++++++ 4 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 tests/tests/regressions/.gh-195.rto/default.1.1.txt create mode 100644 tests/tests/regressions/gh-195.sft.cpp diff --git a/src/Changes b/src/Changes index 79bcd59a6c..5fc124d9e5 100644 --- a/src/Changes +++ b/src/Changes @@ -8,6 +8,30 @@ behavior standard-mandated. It is now the default behavior, except in Microsoft mode with microsoft_version < 1951. +Version 7.1 + +10/1/26 [GH #195] +C++-generating back end: dependent multi-dimensional subscripts + +In cases in which template definitions are generated from the prototype +instantiation IL, when a dependent multi-dimensional subscript operation +appears in a template definition, the C++-generating back end previously +emitted only the first subscript. This is now fixed. For example, with +--c++23: + + template auto f(const T &t) { + return t[1, 2]; // Previously generated as "t[1]" + } + + +10/1/26 [GH #191] +C++-generating back end: inaccessible or out-of-scope template arguments + +In certain complex cases, the C++-generating back end could put out a +template argument that uses an inaccessible or out-of-scope name, making +the generated code uncompilable. This is now fixed. + + Version 7.0, September 28, 2026 9/15/26 [EDGcpfe/28958] diff --git a/src/cp_gen_be.c b/src/cp_gen_be.c index 80536553a5..2f5bfe14dc 100644 --- a/src/cp_gen_be.c +++ b/src/cp_gen_be.c @@ -15255,16 +15255,26 @@ it is a tpck_unknown_function constant and to NULL otherwise. } /* is_dot_static_operation */ -static void gen_array_subscript(an_expr_node_ptr expr) +static void gen_array_subscript_list(an_expr_node_ptr expr) /* -Render the given expression surrounded by brackets. +Put out the given expression list surrounded by square brackets. */ { + a_boolean first = TRUE; + write_tok_ch('['); - gen_expr(expr, /*need_parens=*/expr_has_comma_operation(expr), - /*obj_expr_of_mfunc_operator=*/FALSE); + while (expr != NULL) { + if (first) { + first = FALSE; + } else { + write_tok_str(", "); + } /* if */ + gen_expr(expr, /*need_parens=*/expr_has_comma_operation(expr), + /*obj_expr_of_mfunc_operator=*/FALSE); + expr = expr->next; + } /* if */ write_tok_ch(']'); -} /* gen_array_subscript */ +} /* gen_array_subscript_list */ static void gen_va_arg(an_expr_node_ptr expr) @@ -17852,7 +17862,7 @@ handled through recursion. break; case eok_subscript: gen_member_selector_for_builtin_offsetof(arg1); - gen_array_subscript(arg2); + gen_array_subscript_list(arg2); break; case eok_cast: case eok_base_class_cast: @@ -19245,7 +19255,7 @@ gen_expr that might end up generating this expr as a temporary. parens_may_be_needed(generated_precedence[eok_subscript], operand_1), /*obj_expr_of_mfunc_operator=*/FALSE); - gen_array_subscript(operand_2); + gen_array_subscript_list(operand_2); goto done_with_operation; case eok_cli_subscript: gen_expr_with_parens(operand_1); diff --git a/tests/tests/regressions/.gh-195.rto/default.1.1.txt b/tests/tests/regressions/.gh-195.rto/default.1.1.txt new file mode 100644 index 0000000000..954f8043b9 --- /dev/null +++ b/tests/tests/regressions/.gh-195.rto/default.1.1.txt @@ -0,0 +1 @@ +cpfe -DTEST_NUMBER=1 --c++23 Test_name.c diff --git a/tests/tests/regressions/gh-195.sft.cpp b/tests/tests/regressions/gh-195.sft.cpp new file mode 100644 index 0000000000..df7d4c4f73 --- /dev/null +++ b/tests/tests/regressions/gh-195.sft.cpp @@ -0,0 +1,9 @@ +//options_all:--c++23 +//type:cp +template auto f(const T &t) { + return t[1, 2]; // Previously generated as "t[1]" +} +struct S { + int operator[](int, int) const; +} s; +int i = f(s);