[clang-tools-extra] r255758 - [clang-tidy] Fix a crash in misc-new-delete-overloads

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 16 05:25:38 PST 2015


On Wed, Dec 16, 2015 at 5:58 AM, Alexander Kornienko via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Author: alexfh
> Date: Wed Dec 16 04:58:14 2015
> New Revision: 255758
>
> URL: http://llvm.org/viewvc/llvm-project?rev=255758&view=rev
> Log:
> [clang-tidy] Fix a crash in misc-new-delete-overloads

Good catch, thanks!

~Aaron

>
> Modified:
>     clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
>     clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp
>
> Modified: clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp?rev=255758&r1=255757&r2=255758&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp (original)
> +++ clang-tools-extra/trunk/clang-tidy/misc/NewDeleteOverloadsCheck.cpp Wed Dec 16 04:58:14 2015
> @@ -98,32 +98,30 @@ bool areCorrespondingOverloads(const Fun
>    return RHS->getOverloadedOperator() == getCorrespondingOverload(LHS);
>  }
>
> -bool hasCorrespondingOverloadInOneClass(const CXXRecordDecl *RD,
> -                                        const CXXMethodDecl *MD) {
> -  // Check the methods in the given class and accessible to derived classes.
> -  for (const auto *BMD : RD->methods())
> -    if (BMD->isOverloadedOperator() && BMD->getAccess() != AS_private &&
> -        areCorrespondingOverloads(MD, BMD))
> -      return true;
> -
> -  // Check base classes.
> -  for (const auto &BS : RD->bases())
> -    if (hasCorrespondingOverloadInOneClass(BS.getType()->getAsCXXRecordDecl(),
> -                                           MD))
> -      return true;
> +bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD,
> +                                         const CXXRecordDecl *RD = nullptr) {
> +  if (RD) {
> +    // Check the methods in the given class and accessible to derived classes.
> +    for (const auto *BMD : RD->methods())
> +      if (BMD->isOverloadedOperator() && BMD->getAccess() != AS_private &&
> +          areCorrespondingOverloads(MD, BMD))
> +        return true;
> +  } else {
> +    // Get the parent class of the method; we do not need to care about checking
> +    // the methods in this class as the caller has already done that by looking
> +    // at the declaration contexts.
> +    RD = MD->getParent();
> +  }
>
> -  return false;
> -}
> -bool hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD) {
> -  // Get the parent class of the method; we do not need to care about checking
> -  // the methods in this class as the caller has already done that by looking
> -  // at the declaration contexts.
> -  const CXXRecordDecl *RD = MD->getParent();
> -
> -  for (const auto &BS : RD->bases())
> -    if (hasCorrespondingOverloadInOneClass(BS.getType()->getAsCXXRecordDecl(),
> -                                           MD))
> +  for (const auto &BS : RD->bases()) {
> +    // We can't say much about a dependent base class, but to avoid false
> +    // positives assume it can have a corresponding overload.
> +    if (BS.getType()->isDependentType())
>        return true;
> +    if (const auto *BaseRD = BS.getType()->getAsCXXRecordDecl())
> +      if (hasCorrespondingOverloadInBaseClass(MD, BaseRD))
> +        return true;
> +  }
>
>    return false;
>  }
> @@ -174,24 +172,23 @@ void NewDeleteOverloadsCheck::onEndOfTra
>      // to shard the overloads by declaration context to reduce the algorithmic
>      // complexity when searching for corresponding free store functions.
>      for (const auto *Overload : RP.second) {
> -      const auto *Match = std::find_if(
> -          RP.second.begin(), RP.second.end(), [&](const FunctionDecl *FD) {
> -            if (FD == Overload)
> -              return false;
> -            // If the declaration contexts don't match, we don't
> -            // need to check
> -            // any further.
> -            if (FD->getDeclContext() != Overload->getDeclContext())
> -              return false;
> -
> -            // Since the declaration contexts match, see whether
> -            // the current
> -            // element is the corresponding operator.
> -            if (!areCorrespondingOverloads(Overload, FD))
> -              return false;
> +      const auto *Match =
> +          std::find_if(RP.second.begin(), RP.second.end(),
> +                       [&Overload](const FunctionDecl *FD) {
> +                         if (FD == Overload)
> +                           return false;
> +                         // If the declaration contexts don't match, we don't
> +                         // need to check any further.
> +                         if (FD->getDeclContext() != Overload->getDeclContext())
> +                           return false;
> +
> +                         // Since the declaration contexts match, see whether
> +                         // the current element is the corresponding operator.
> +                         if (!areCorrespondingOverloads(Overload, FD))
> +                           return false;
>
> -            return true;
> -          });
> +                         return true;
> +                       });
>
>        if (Match == RP.second.end()) {
>          // Check to see if there is a corresponding overload in a base class
>
> Modified: clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp
> URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp?rev=255758&r1=255757&r2=255758&view=diff
> ==============================================================================
> --- clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp (original)
> +++ clang-tools-extra/trunk/test/clang-tidy/misc-new-delete-overloads.cpp Wed Dec 16 04:58:14 2015
> @@ -75,3 +75,7 @@ struct H : G {
>    // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
>    void *operator new(size_t) noexcept; // base class operator is inaccessible
>  };
> +
> +template <typename Base> struct Derived : Base {
> +  void operator delete(void *);
> +};
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


More information about the cfe-commits mailing list