This is an archive of the discontinued LLVM Phabricator instance.

[clang] Fix default initializers being ignored when initializing templated aggregate types
ClosedPublic

Authored by ayzhao on Apr 27 2023, 3:40 PM.

Details

Summary

Previously, when checking whether an in-class initializer exists when
performing parenthesized aggregate initialization, Clang checks that the
output of FieldDecl::getInClassInitializer() is non-null. This is
incorrect; if the field is part of a templated type, then
getInClassInitializer() will return nullptr if we haven't called
Sem::BuildCXXDefaultInitExpr(...) before, even if
FieldDecl::hasInClassInitializer() returns true. The end result is that
Clang incorrectly ignores the in class initializer and
value-initializes the field. The fix therefore is to instead call
FieldDecl::hasInClassInitializer(), which is what we do for braced init
lists [0].

Before this patch, Clang does correctly recognize the in-class field
initializer in certain cases. This is Sema::BuildCXXDefaultInitExpr(...)
populates the in class initializer of the corresponding FieldDecl
object. Therefore, if that method was previously called with the same
FieldDecl object, as can happen with a decltype(...) or a braced list
initialization, FieldDecl::getInClassInitializer() will return a
non-null expression, and the field becomes properly initialized.

Fixes 62266

[0]: https://github.com/llvm/llvm-project/blob/be5f35e24f4c15caf3c4aeccddc54c52560c28a0/clang/lib/Sema/SemaInit.cpp#L685

Diff Detail

Event Timeline

ayzhao created this revision.Apr 27 2023, 3:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2023, 3:40 PM
ayzhao requested review of this revision.Apr 27 2023, 3:40 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2023, 3:40 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

So the change makes sense but the original issue: https://github.com/llvm/llvm-project/issues/62266 it worked for the first once but not the second, it also worked for the non-paren aggregate init. So I feel like the explanation is missing some details.

It seems like the codegen test should be mimicing the test from the bug report more closely w/ two paren inits.

Please also add a release note.

ayzhao updated this revision to Diff 518054.Apr 28 2023, 2:19 PM

rebase + add release notes

ayzhao edited the summary of this revision. (Show Details)Apr 28 2023, 2:22 PM

So the change makes sense but the original issue: https://github.com/llvm/llvm-project/issues/62266 it worked for the first once but not the second, it also worked for the non-paren aggregate init. So I feel like the explanation is missing some details.

Patch description has been updated with an explanation.

It seems like the codegen test should be mimicing the test from the bug report more closely w/ two paren inits.

The bug was that Clang wasn't calling the default-member intializer in the first initializer, which the CodeGen test asserts. The second initializer is irrelevant - it's only function is to provide the expected value of the initialized field. In fact, changing the test assertion to be the same as that in the bug report (asserting that the values of the fields in the two objects are equal) is worse because that test would pass if we value-initialize the fields instead of calling the default initialization expression for both objects.

Please also add a release note.

Done

So the change makes sense but the original issue: https://github.com/llvm/llvm-project/issues/62266 it worked for the first once but not the second, it also worked for the non-paren aggregate init. So I feel like the explanation is missing some details.

Patch description has been updated with an explanation.

It seems like the codegen test should be mimicing the test from the bug report more closely w/ two paren inits.

The bug was that Clang wasn't calling the default-member intializer in the first initializer, which the CodeGen test asserts. The second initializer is irrelevant - it's only function is to provide the expected value of the initialized field. In fact, changing the test assertion to be the same as that in the bug report (asserting that the values of the fields in the two objects are equal) is worse because that test would pass if we value-initialize the fields instead of calling the default initialization expression for both objects.

Apologies, I was not alluding to the comparing of the results of the two initializations but ensuring that it does the right thing for not just the first but also the second. So we did not change the bug in some strange way where the first now succeeds but now the second fails.

shafik accepted this revision.Apr 28 2023, 6:59 PM

LGTM

This revision is now accepted and ready to land.Apr 28 2023, 6:59 PM
danakj added a subscriber: danakj.Apr 30 2023, 11:11 AM
This revision was landed with ongoing or failed builds.May 1 2023, 9:28 AM
This revision was automatically updated to reflect the committed changes.