aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorAlan Zhao <ayzhao@google.com>2023-04-27 15:31:51 -0700
committerAlan Zhao <ayzhao@google.com>2023-05-01 09:27:52 -0700
commitda0089c99ba1507b876cf3d2a205ba108aad65ff (patch)
treedd1c415ed42459651d05e81f92135c3e063e06b2 /clang/lib/Sema/SemaInit.cpp
parentce357fd4ee7f1f0b054d01166329b5b3d0d91441 (diff)
downloadllvm-da0089c99ba1507b876cf3d2a205ba108aad65ff.zip
llvm-da0089c99ba1507b876cf3d2a205ba108aad65ff.tar.gz
llvm-da0089c99ba1507b876cf3d2a205ba108aad65ff.tar.bz2
[clang] Fix default initializers being ignored when initializing templated aggregate types
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 Reviewed By: shafik Differential Revision: https://reviews.llvm.org/D149389
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp16
1 files changed, 9 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index c218470..55ef72d 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -5377,14 +5377,16 @@ static void TryOrBuildParenListInitialization(
// The remaining elements are initialized with their default member
// initializers, if any
auto *FD = cast<FieldDecl>(SubEntity.getDecl());
- if (Expr *ICE = FD->getInClassInitializer(); ICE && !VerifyOnly) {
- ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD);
- if (DIE.isInvalid())
- return false;
- S.checkInitializerLifetime(SubEntity, DIE.get());
- InitExprs.push_back(DIE.get());
+ if (FD->hasInClassInitializer()) {
+ if (!VerifyOnly) {
+ ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD);
+ if (DIE.isInvalid())
+ return false;
+ S.checkInitializerLifetime(SubEntity, DIE.get());
+ InitExprs.push_back(DIE.get());
+ }
continue;
- };
+ }
}
// Remaining class elements without default member initializers and
// array elements are value initialized: