diff options
author | Eric Fiselier <eric@efcs.ca> | 2016-12-03 01:26:47 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2016-12-03 01:26:47 +0000 |
commit | 283d8d45dbfcd12aec26d08e54eaae3c1c81aebc (patch) | |
tree | 943455c4996c64984836cb722838ead725b99103 /clang/lib/AST/DeclCXX.cpp | |
parent | 572e6deeb7b1c13c58ac3e9861669d6b3374d9f7 (diff) | |
download | bcm5719-llvm-283d8d45dbfcd12aec26d08e54eaae3c1c81aebc.tar.gz bcm5719-llvm-283d8d45dbfcd12aec26d08e54eaae3c1c81aebc.zip |
[Sema] Don't perform aggregate initialization for types with explicit constructors
Summary:
The C++17 rules for aggregate initialization changed to disallow types with explicit constructors [dcl.init.aggr]p1. This patch implements that new rule.
Reviewers: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D25654
llvm-svn: 288565
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 6df15b07a50..f1848e8e092 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -533,6 +533,17 @@ void CXXRecordDecl::addedMember(Decl *D) { } else if (Constructor->isMoveConstructor()) SMKind |= SMF_MoveConstructor; } + + // C++ [dcl.init.aggr]p1: + // An aggregate is an array or a class with no user-declared + // constructors [...]. + // C++11 [dcl.init.aggr]p1: DR1518 + // An aggregate is an array or a class with no user-provided, explicit, or + // inherited constructors + if (getASTContext().getLangOpts().CPlusPlus11 + ? (Constructor->isUserProvided() || Constructor->isExplicit()) + : !Constructor->isImplicit()) + data().Aggregate = false; } // Handle constructors, including those inherited from base classes. @@ -546,20 +557,6 @@ void CXXRecordDecl::addedMember(Decl *D) { // constructor [...] if (Constructor->isConstexpr() && !Constructor->isCopyOrMoveConstructor()) data().HasConstexprNonCopyMoveConstructor = true; - - // C++ [dcl.init.aggr]p1: - // An aggregate is an array or a class with no user-declared - // constructors [...]. - // C++11 [dcl.init.aggr]p1: - // An aggregate is an array or a class with no user-provided - // constructors [...]. - // C++11 [dcl.init.aggr]p1: - // An aggregate is an array or a class with no user-provided - // constructors (including those inherited from a base class) [...]. - if (getASTContext().getLangOpts().CPlusPlus11 - ? Constructor->isUserProvided() - : !Constructor->isImplicit()) - data().Aggregate = false; } // Handle destructors. @@ -989,8 +986,12 @@ void CXXRecordDecl::addedMember(Decl *D) { if (UsingDecl *Using = dyn_cast<UsingDecl>(D)) { if (Using->getDeclName().getNameKind() == - DeclarationName::CXXConstructorName) + DeclarationName::CXXConstructorName) { data().HasInheritedConstructor = true; + // C++1z [dcl.init.aggr]p1: + // An aggregate is [...] a class [...] with no inherited constructors + data().Aggregate = false; + } if (Using->getDeclName().getCXXOverloadedOperator() == OO_Equal) data().HasInheritedAssignment = true; |