From: John McCall Date: Fri, 17 Jun 2011 00:18:42 +0000 (+0000) Subject: When synthesizing implicit copy/move constructors and copy/move assignment X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b77115d7b988f55f961e24129a62f20dfd066a94;p=clang When synthesizing implicit copy/move constructors and copy/move assignment operators, don't make an initializer or sub-operation for zero-width bitfields. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133221 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 09597d2ef1..53b5ad2765 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1972,6 +1972,11 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, if (ImplicitInitKind == IIK_Copy) { ParmVarDecl *Param = Constructor->getParamDecl(0); QualType ParamType = Param->getType().getNonReferenceType(); + + // Suppress copying zero-width bitfields. + if (const Expr *Width = Field->getBitWidth()) + if (Width->EvaluateAsInt(SemaRef.Context) == 0) + return false; Expr *MemberExprBase = DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), Param, @@ -2256,11 +2261,10 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor, return false; } -bool -Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, - CXXCtorInitializer **Initializers, - unsigned NumInitializers, - bool AnyErrors) { +bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, + CXXCtorInitializer **Initializers, + unsigned NumInitializers, + bool AnyErrors) { if (Constructor->getDeclContext()->isDependentContext()) { // Just store the initializers as written, they will be checked during // instantiation. @@ -7011,6 +7015,11 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, Invalid = true; continue; } + + // Suppress assigning zero-width bitfields. + if (const Expr *Width = Field->getBitWidth()) + if (Width->EvaluateAsInt(Context) == 0) + continue; QualType FieldType = Field->getType().getNonReferenceType(); if (FieldType->isIncompleteArrayType()) { diff --git a/test/CodeGenCXX/implicit-copy-constructor.cpp b/test/CodeGenCXX/implicit-copy-constructor.cpp index 500860182e..8bc84a534b 100644 --- a/test/CodeGenCXX/implicit-copy-constructor.cpp +++ b/test/CodeGenCXX/implicit-copy-constructor.cpp @@ -70,3 +70,13 @@ void test_X2() pimpl pdata; pdata.f0( new impl(*i)); } + +// rdar://problem/9598341 +namespace test3 { + struct A { A(const A&); A&operator=(const A&); }; + struct B { A a; unsigned : 0; }; + void test(const B &x) { + B y = x; + y = x; + } +}