diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/AST/CXXInheritance.cpp | 35 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 7 | 
2 files changed, 28 insertions, 14 deletions
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index d616e42e007..bdba01402c3 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -559,22 +559,23 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,        for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {          const CXXMethodDecl *CanonOM            = cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl()); + +        // C++ [class.virtual]p2: +        //   A virtual member function C::vf of a class object S is +        //   a final overrider unless the most derived class (1.8) +        //   of which S is a base class subobject (if any) declares +        //   or inherits another member function that overrides vf. +        // +        // Treating this object like the most derived class, we +        // replace any overrides from base classes with this +        // overriding virtual function. +        Overriders[CanonOM].replaceAll( +                               UniqueVirtualMethod(CanonM, SubobjectNumber, +                                                   InVirtualSubobject)); +          if (CanonOM->begin_overridden_methods() -                                       == CanonOM->end_overridden_methods()) { -          // C++ [class.virtual]p2: -          //   A virtual member function C::vf of a class object S is -          //   a final overrider unless the most derived class (1.8) -          //   of which S is a base class subobject (if any) declares -          //   or inherits another member function that overrides vf. -          // -          // Treating this object like the most derived class, we -          // replace any overrides from base classes with this -          // overriding virtual function. -          Overriders[CanonOM].replaceAll( -                                 UniqueVirtualMethod(CanonM, SubobjectNumber, -                                                     InVirtualSubobject)); +                                       == CanonOM->end_overridden_methods())            continue; -        }           // Continue recursion to the methods that this virtual method          // overrides. @@ -582,6 +583,12 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,                                         CanonOM->end_overridden_methods()));        }      } + +    // C++ [class.virtual]p2: +    //   For convenience we say that any virtual function overrides itself. +    Overriders[CanonM].add(SubobjectNumber, +                           UniqueVirtualMethod(CanonM, SubobjectNumber, +                                               InVirtualSubobject));    }  } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8630e73ceea..76a2f4f612f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -2326,6 +2326,10 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,    CXXFinalOverriderMap FinalOverriders;    RD->getFinalOverriders(FinalOverriders); +  // Keep a set of seen pure methods so we won't diagnose the same method +  // more than once. +  llvm::SmallPtrSet<const CXXMethodDecl *, 8> SeenPureMethods; +      for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(),                                      MEnd = FinalOverriders.end();         M != MEnd;  @@ -2345,6 +2349,9 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,        if (!SO->second.front().Method->isPure())          continue; +      if (!SeenPureMethods.insert(SO->second.front().Method)) +        continue; +        Diag(SO->second.front().Method->getLocation(),              diag::note_pure_virtual_function)           << SO->second.front().Method->getDeclName();  | 

