Repository navigation
Bind an NSDMI's implicit this to the constructed object in a constructor init [GH #324] - #540
Draft
Momen-G-Ar wants to merge 1 commit into
Draft
Momen-G-Ar wants to merge 1 commit into
Momen-G-Ar wants to merge 1 commit into
Conversation
…tor init [GH edgcpp#324] When a default member initializer that aggregate-initializes another object of the same class was used by a constructor, lower_param_ref searched every aggregate on aggregate_this_stack, including the ones skipped because one of their explicit elements was being lowered, before it tried the "this" of the constructor init: struct Y { unsigned k = 7; unsigned n = Y{2, k}.n; }; struct D : Y { D() {} }; // D().n was 2, not 7. The "this" of the constructor init is now used before the skipped aggregates are searched.
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
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. |
Collaborator
|
AcknowlEDG review results updated for
|
Collaborator
|
AcknowlEDG review results updated for
CI success. |
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Follow-up to #408 for discussion #324. #408 fixed the implicit
thisof a default member initializer that aggregate-initializes another object of the same class, but only when the default member initializer is used by an aggregate initialization. When it is used by a constructor,thisstill bound to the nested temporary:khere is(*this).k([class.mfct.non-static]/3, [expr.prim.id.general] in C++23).thisnames the object whose non-static data member's initializer is being evaluated ([expr.prim.this]/1), and Y's constructor initializesnfrom its default member initializer ([class.base.init]/9, [class.default.ctor]/4). Sonis 7. g++ 15 and Clang 21 give 7 in every mode.Y y;,new Y,Y()with constant initializers (folded to{7U, 7U}by the front end)Y{},D() : Y{} {}(aggregate initialization, fixed by #408)D(),D() : Y() {}, a memberY y;of a class with a user-provided constructor, an array member,new Y[2], a class template, an aggregate with a base classthisbound to the nestedY{2, k}unsigned k = seven;withvolatile unsigned seven), so evenY y;runs the constructorthisbound to the nestedY{2, k}Same result in strict,
--g++and--clangmodes, C++14 through C++23. EDG 6.5, 6.7, 6.8, 6.9 and 7.0 all have the bug too.Root cause
lower_param_ref(lower_il.c) replaces theenk_param_refforthisin this order:aggregate_this_stack(Bind an NSDMI's implicit this to the right aggregate [GH #324] #408 skips an aggregate while one of its explicit elements is lowered),ctor_init_this, thethisparameter of the constructor init being lowered (lower_ctor_init,lower_init.c).In Y's constructor, lowering
n = Y{2, k}.npushes the temporary forY{2, k}, and that temporary is skipped while its explicit elementkis lowered. Step 1 finds nothing, and step 2 then takes the skipped temporary, so step 3 is never reached. The lowered constructor read__T.n = __T.k;instead of__T.n = this->k;. This already happened before #408.Change
lower_param_refnow tries thethisof the constructor init after the candidate search and before the search that includes the skipped aggregates (only when its type matches, as the old assertion required). While a constructor init is lowered, every entry on the stack was pushed by that constructor init (constructor inits don't nest), and a skipped entry is never what an explicit element'sthisrefers to. So the constructor'sthisis right whenever no candidate matches. The search that includes the skipped aggregates stays as the last resort outside constructor inits, as before.lower_il.c: reorderedlower_param_refand updated its header comment.lower_init.c: comment at thenot_this_candidateassignment.Changes entry:
src/pending_changes/gh-324-nsdmi-this-ctor-init.txt(passesedg-collect-changes --check). Based onmainat cb7d105. The commit message passesedg-check-commit-messages.Tests
regressions/gh-324-ctor-init.sft.cppstatic,new Y,new Y(),Y()); non-constant initializers (volatile, a function call); Y's constructor called through a derived class,: Y(), a member, an array member, a local array,new Y[2];this->k, nestedY{2, Y{3, k}.n}, through a static member function (by value and byconst &), a lambda capturingthis, designated initializers (C++20); an aggregate with a base class (C++17); class templates; controls that must not change (Y{},: Y{},Y a{1}, the PR c++/100252 shape). The lines that were wrong onmainare marked// Previously 2.Options:--c++14,--c++17,--c++20,--c++20 --g++ --gnu_version=150000,--c++20 --clang,--c++23main(17, 18 or 19 failed checks, depending on the mode) and passes with this change onedg_x86_64andedg_x86_64_cp, in all six option sets. g++ 15 and Clang 21 pass the same checks with-std=c++14throughc++23.edgy -W, and thedefault.*files were reviewed.regressions/gh-324, the NSDMIchangestests, GCC'spr79937-*,nsdmi*,nsdmi-aggr*andconstexpr-nsdmi*,cmeerw/gnats-25426,regressions/gh-90-warn) match their expectations onedg_x86_64andedg_x86_64_cp: no new failures, no unexpected passes.Build & Test CI, all four configurations).Discussion: #324 (follow-up to #408)