diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-09-26 19:00:16 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-09-26 19:00:16 +0000 |
commit | 79c88c31056fc52f8414c497f2d6e2e53749c48b (patch) | |
tree | e39d1f3a122dc10559f9d9863b6f3c44416aa40b /clang/lib/Sema/SemaInit.cpp | |
parent | 8fe53c490a567d3e9337b974057a239477dbe685 (diff) | |
download | llvm-79c88c31056fc52f8414c497f2d6e2e53749c48b.zip llvm-79c88c31056fc52f8414c497f2d6e2e53749c48b.tar.gz llvm-79c88c31056fc52f8414c497f2d6e2e53749c48b.tar.bz2 |
P1008R1 Classes with user-declared constructors are never aggregates in
C++20.
llvm-svn: 343131
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index a25818f..a678a31 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -964,6 +964,14 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, StructuredSubobjectInitList->getEndLoc()), "}"); } + + // Warn if this type won't be an aggregate in future versions of C++. + auto *CXXRD = T->getAsCXXRecordDecl(); + if (CXXRD && CXXRD->hasUserDeclaredConstructor()) { + SemaRef.Diag(StructuredSubobjectInitList->getBeginLoc(), + diag::warn_cxx2a_compat_aggregate_init_with_ctors) + << StructuredSubobjectInitList->getSourceRange() << T; + } } } @@ -1106,9 +1114,30 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, } } - if (!VerifyOnly && T->isScalarType() && - IList->getNumInits() == 1 && !isa<InitListExpr>(IList->getInit(0))) - warnBracedScalarInit(SemaRef, Entity, IList->getSourceRange()); + if (!VerifyOnly) { + if (T->isScalarType() && IList->getNumInits() == 1 && + !isa<InitListExpr>(IList->getInit(0))) + warnBracedScalarInit(SemaRef, Entity, IList->getSourceRange()); + + // Warn if this is a class type that won't be an aggregate in future + // versions of C++. + auto *CXXRD = T->getAsCXXRecordDecl(); + if (CXXRD && CXXRD->hasUserDeclaredConstructor()) { + // Don't warn if there's an equivalent default constructor that would be + // used instead. + bool HasEquivCtor = false; + if (IList->getNumInits() == 0) { + auto *CD = SemaRef.LookupDefaultConstructor(CXXRD); + HasEquivCtor = CD && !CD->isDeleted(); + } + + if (!HasEquivCtor) { + SemaRef.Diag(IList->getBeginLoc(), + diag::warn_cxx2a_compat_aggregate_init_with_ctors) + << IList->getSourceRange() << T; + } + } + } } void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, |