Skip to content

Commit

Permalink
[clang] Fix a crash with parenthesized aggregate initialization and b…
Browse files Browse the repository at this point in the history
…ase classes

When calling InitializeBase(...), TryOrBuidlParenListInit(...) needs to
pass in the parent entity; otherwise, we erroneously try to cast
CurContext to a CXXConstructorDecl[0], which can't be done since we're
performing aggregate initialization, not constructor initialization.

Field initialization is not affected, but this patch still adds some
tests for it.

Fixes 62296

[0]: https://github.com/llvm/llvm-project/blob/33d6bd1c667456f7f4a9d338a7996a30a3af50a3/clang/lib/Sema/SemaAccess.cpp#L1696

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D149301
  • Loading branch information
alanzhao1 authored and tstellar committed May 2, 2023
1 parent 7a26555 commit 33b41a6
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,10 @@ Improvements to Clang's diagnostics
Bug Fixes in This Version
-------------------------

- Fix crash when attempting to perform parenthesized initialization of an
aggregate with a base class with only non-public constructors.
(`#62296 <https://github.com/llvm/llvm-project/issues/62296>`_)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5420,8 +5420,9 @@ static void TryOrBuildParenListInitialization(
} else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());

auto BaseRange = map_range(RD->bases(), [&S](auto &base) {
return InitializedEntity::InitializeBase(S.getASTContext(), &base, false);
auto BaseRange = map_range(RD->bases(), [&](auto &base) {
return InitializedEntity::InitializeBase(S.getASTContext(), &base, false,
&Entity);
});
auto FieldRange = map_range(RD->fields(), [](auto *field) {
return InitializedEntity::InitializeMember(field);
Expand Down
23 changes: 23 additions & 0 deletions clang/test/SemaCXX/paren-list-agg-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,26 @@ void bar() {
// expected-error@-1 {{call to implicitly-deleted copy constructor of 'V'}}
}
}

namespace gh62296 {
struct L {
protected:
L(int);
// expected-note@-1 2{{declared protected here}}
};

struct M : L {};

struct N {
L l;
};

M m(42);
// expected-error@-1 {{base class 'L' has protected constructor}}
// beforecxx20-warning@-2 {{aggregate initialization of type 'M' from a parenthesized list of values is a C++20 extension}}

N n(43);
// expected-error@-1 {{field of type 'L' has protected constructor}}
// beforecxx20-warning@-2 {{aggregate initialization of type 'N' from a parenthesized list of values is a C++20 extension}}

}

0 comments on commit 33b41a6

Please sign in to comment.