Repository navigation
Fix #15130 FN passedByValue (nested anonymous union) #8963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8690,7 +8690,6 @@ template<class F> | |
| static Result accumulateStructMembers(const Scope* scope, F f, ValueType::Accuracy accuracy, const Settings& settings) | ||
| { | ||
| size_t total = 0; | ||
| std::set<const Scope*> anonScopes; | ||
| for (const Variable& var : scope->varlist) { | ||
| if (var.isStatic()) | ||
| continue; | ||
|
|
@@ -8701,12 +8700,7 @@ static Result accumulateStructMembers(const Scope* scope, F f, ValueType::Accura | |
| const MathLib::bigint dim = std::accumulate(var.dimensions().cbegin(), var.dimensions().cend(), MathLib::bigint(1), [](MathLib::bigint i1, const Dimension& dim) { | ||
| return i1 * dim.num; | ||
| }); | ||
| if (var.nameToken()->scope() != scope && var.nameToken()->scope()->definedType) { // anonymous union | ||
| const auto ret = anonScopes.insert(var.nameToken()->scope()); | ||
| if (ret.second) | ||
| total = f(total, *vt, dim, bits); | ||
| } | ||
| else if (vt->container && vt->container->startPattern == "std :: array <") { | ||
| if (vt->container && vt->container->startPattern == "std :: array <") { | ||
| const ValueType vtElement = ValueType::parseDecl(vt->containerTypeToken, settings); | ||
| total = f(total, vtElement, dim, bits); | ||
| } | ||
|
|
@@ -8840,7 +8834,8 @@ size_t ValueType::getSizeOf( const Settings& settings, Accuracy accuracy, SizeOf | |
| currentBitfieldAlloc = 0; | ||
| currentBitCount = 0; | ||
| } | ||
| return typeScope->type == ScopeType::eUnion ? std::max(total, n) : total + padding + n; | ||
| const bool isUnion = typeScope->type == ScopeType::eUnion || (vt2.typeScope && vt2.typeScope->nestedIn->type == ScopeType::eUnion && vt2.typeScope->nestedIn->className.empty()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AI review This only gives union semantics to members whose own type is an unnamed struct declared inside an anonymous union. Any other member of an anonymous union is summed like a struct member:
The condition also takes The anonymous union scope should be sized once, as the max of its members. That size should then be added with padding to the enclosing struct. |
||
| return isUnion ? std::max(total, n) : total + padding + n; | ||
| }; | ||
| Result result = accumulateStructMembers(typeScope, accHelper, accuracy, settings); | ||
| size_t total = result.total; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AI review
Removing the
anonScopeshandling means every member of an anonymous union is now passed tof.getAlignOfis fine with this because it takes the max. IngetSizeOf, though, these members are now added together unless the newisUnionheuristic matches, and it doesn't match plain-typed members. That causes the regressions described on line 8837.