diff options
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 49 | 
1 files changed, 47 insertions, 2 deletions
| diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index cb454581d1a..56e965f81fe 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4988,6 +4988,49 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S,      ArgType = ArgType.withConst();    ArgType = Context.getLValueReferenceType(ArgType); +  // C++ [except.spec]p14: +  //   An implicitly declared special member function (Clause 12) shall have an  +  //   exception-specification. [...] +  ImplicitExceptionSpecification ExceptSpec(Context); +  unsigned Quals = HasConstCopyConstructor? Qualifiers::Const : 0; +  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(), +                                       BaseEnd = ClassDecl->bases_end(); +       Base != BaseEnd;  +       ++Base) { +    // Virtual bases are handled below. +    if (Base->isVirtual()) +      continue; +     +    const CXXRecordDecl *BaseClassDecl +      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); +    if (CXXConstructorDecl *CopyConstructor +                          = BaseClassDecl->getCopyConstructor(Context, Quals)) +      ExceptSpec.CalledDecl(CopyConstructor); +  } +  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(), +                                       BaseEnd = ClassDecl->vbases_end(); +       Base != BaseEnd;  +       ++Base) { +    const CXXRecordDecl *BaseClassDecl +      = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); +    if (CXXConstructorDecl *CopyConstructor +                          = BaseClassDecl->getCopyConstructor(Context, Quals)) +      ExceptSpec.CalledDecl(CopyConstructor); +  } +  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), +                                  FieldEnd = ClassDecl->field_end(); +       Field != FieldEnd; +       ++Field) { +    QualType FieldType = Context.getBaseElementType((*Field)->getType()); +    if (const RecordType *FieldClassType = FieldType->getAs<RecordType>()) { +      const CXXRecordDecl *FieldClassDecl +        = cast<CXXRecordDecl>(FieldClassType->getDecl()); +      if (CXXConstructorDecl *CopyConstructor +                          = FieldClassDecl->getCopyConstructor(Context, Quals)) +        ExceptSpec.CalledDecl(CopyConstructor); +    } +  } +      //   An implicitly-declared copy constructor is an inline public    //   member of its class.    DeclarationName Name @@ -4999,8 +5042,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(Scope *S,                                   Context.getFunctionType(Context.VoidTy,                                                           &ArgType, 1,                                                           false, 0, -                                               /*FIXME: hasExceptionSpec*/false, -                                                         false, 0, 0, +                                         ExceptSpec.hasExceptionSpecification(), +                                      ExceptSpec.hasAnyExceptionSpecification(), +                                                         ExceptSpec.size(), +                                                         ExceptSpec.data(),                                                         FunctionType::ExtInfo()),                                   /*TInfo=*/0,                                   /*isExplicit=*/false, | 

