You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Repeated constexpr initialization of a local array from a string literal [GH #521] - #526
When extract_value_from_constant copies a string literal (a ck_string
constant) into the storage being initialized, it maps that storage back to the
constant (map_stack_bytes). Callers that copy into aggregate elements undo
that mapping afterward, but process_dyn_init_work did not do so for the dik_constant initializer of a local array. So when the same storage was
initialized again (e.g., in the next iteration of a loop, as in the issue's
example), the interpreter tried to map an existing key and asserted
"duplicate map key in interpreter".
process_dyn_init_work now unmaps the array storage after a ck_string
initializer has been copied. It does so only if the storage is actually mapped
to that constant, because extract_value_from_constant can return before
installing the mapping.
The new test regressions/gh-521.sft.cpp covers the issue's example, an array
modified on each iteration, and const char[], char16_t, and wchar_t
arrays, in C++14 and C++20 modes.
Summary by CodeRabbit
Bug Fixes
Fixed an internal error that could occur when local character arrays initialized from string literals were initialized again in a loop.
Repeated initialization now works as expected for mutable and const arrays, including narrow and wide character types, in C++14 and C++20.
No actionable comments were generated in the recent review.
Walkthrough
The interpreter now removes a destination-storage mapping when it still points to an extracted string constant. Regression tests cover repeated local array initialization from string literals during constant evaluation in C++14 and C++20 modes.
Changes: Repeated string initialization
Layer / File(s)
Summary
Mapping cleanup and regression coverage src/interpret.c, tests/tests/regressions/gh-521.sft.cpp, tests/tests/regressions/.gh-521.rto/*, src/pending_changes/gh-521-string-init-local-array-loop.txt
After aggregate extraction, the interpreter removes the destination-storage mapping only when it still points to the extracted string constant. Regression checks cover repeated narrow, UTF-16, and wide array initialization, including per-iteration mutation. The test fixtures run in C++14 and C++20 modes.
The change fixes an internal compiler error during repeated constexpr initialization of local arrays from string literals and adds regression tests. No merge-blocking risk is identified.
Pre-merge checks: 4
Check name
Status
Explanation
Description Check
Check skipped - CodeRabbit’s high-level summary is enabled.
Title check
The title names the main change: repeated constexpr initialization of a local array from a string literal, which matches the regression fix for GH #521 in the interpreter's dynamic initializer handlin…
Linked Issues check
Issue #521 requires that a constexpr loop which initializes a local char array from a string literal more than once must not trigger the "duplicate map key in interpreter" assertion. In src/interpret.…
Out of Scope Changes check
All whole-PR changes relate to issue #521. The src/interpret.c change is the direct fix for the duplicate-map-key assertion. The regression test gh-521.sft.cpp and its .rto fixture files (default.1.1.…
Full details: Title check
Explanation
The title names the main change: repeated constexpr initialization of a local array from a string literal, which matches the regression fix for GH #521 in the interpreter's dynamic initializer handling and the new regression test. The title is specific and accurate, and it does not describe anything absent from the changeset.
Full details: Linked Issues check
Explanation
Issue #521 requires that a constexpr loop which initializes a local char array from a string literal more than once must not trigger the "duplicate map key in interpreter" assertion. In src/interpret.c, process_dyn_init_work (dik_constant and dik_nonconstant_aggregate branch) now calls get_stack_bytes on the destination storage after extract_value_from_constant. If the storage maps to the same ck_string constant, the code calls unmap_stack_bytes. This removes the stale reverse mapping before the next initialization of the same storage. The guard on the mapping covers the case where extract_value_from_constant returns before installing a mapping. The new test tests/tests/regressions/gh-521.sft.cpp contains the issue's reproducer shape (f(), char a[2] = "a" in a loop) with a static_assert, and it runs in --c++14 and --c++20 modes. It also covers a modified array across iterations (g()) and const char[], char16_t, and wchar_t arrays (h()). The expected values in the static_asserts were checked by hand and match the loop semantics. No coding requirement remains unmet. Automated test execution results were not available to this review, so the runtime pass of the test is not independently confirmed.
Full details: Out of Scope Changes check
Explanation
All whole-PR changes relate to issue #521. The src/interpret.c change is the direct fix for the duplicate-map-key assertion. The regression test gh-521.sft.cpp and its .rto fixture files (default.1.1.txt, default.2.1.txt) verify that fix in C++14 and C++20 modes. The pending_changes entry documents the fix. No unrelated file or hunk was identified in the reviewed diff.
Finishing Touches
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #521.
When
extract_value_from_constantcopies a string literal (ack_stringconstant) into the storage being initialized, it maps that storage back to the
constant (
map_stack_bytes). Callers that copy into aggregate elements undothat mapping afterward, but
process_dyn_init_workdid not do so for thedik_constantinitializer of a local array. So when the same storage wasinitialized again (e.g., in the next iteration of a loop, as in the issue's
example), the interpreter tried to map an existing key and asserted
"duplicate map key in interpreter".
process_dyn_init_worknow unmaps the array storage after ack_stringinitializer has been copied. It does so only if the storage is actually mapped
to that constant, because
extract_value_from_constantcan return beforeinstalling the mapping.
The new test
regressions/gh-521.sft.cppcovers the issue's example, an arraymodified on each iteration, and
const char[],char16_t, andwchar_tarrays, in C++14 and C++20 modes.
Summary by CodeRabbit