This is an archive of the discontinued LLVM Phabricator instance.

[ASTImporter] Fix 'isVirtual()' assert failure while importing overridden methods
ClosedPublic

Authored by danix800 on Jul 7 2023, 4:04 AM.

Details

Summary

CXXMethodDecl::isVirtual() count the number of overridden methods.
This assertion is not true before overridden methods are fully loaded.
The body of this CXXMethodDecl can introduce deps on a derived class
which contains a method overriding this method, causing the assertion failure.

ImportOverriddenMethods() is moved before body loading to fix this issue.

Testcase is contributed by Balázs Kéri (balazske)

Diff Detail

Event Timeline

danix800 created this revision.Jul 7 2023, 4:04 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 7 2023, 4:04 AM
danix800 requested review of this revision.Jul 7 2023, 4:04 AM
danix800 retitled this revision from Overridden CXXMethodDecl::isVirtual() assertion failed before fully imported. to [clang] Overridden CXXMethodDecl::isVirtual() assertion failed before fully imported..Jul 7 2023, 5:03 AM

It is possible to reproduce the same problem with this test added to ASTImporterTest.cpp:

TEST_P(ASTImporterOptionSpecificTestBase, ImportVirtualOverriddenMethodTest) {
  const char *Code =
      R"(
      void f1();
      class A {
        virtual void f(){}
      };
      class B: public A {
        void f() override {
          f1();
        }
      };
      class C: public B {
        void f() override {}
      };
      void f1() { C c; }
      )";
  Decl *FromTU = getTuDecl(Code, Lang_CXX11);

  auto *FromF = FirstDeclMatcher<CXXMethodDecl>().match(
      FromTU, cxxMethodDecl(hasName("B::f")));

  auto *ToBF = Import(FromF, Lang_CXX11);
  EXPECT_TRUE(ToBF->isVirtual());

  auto *ToCF = FirstDeclMatcher<CXXMethodDecl>().match(
      ToBF->getTranslationUnitDecl(), cxxMethodDecl(hasName("C::f")));
  EXPECT_TRUE(ToCF->isVirtual());
}

I am not opposed to removal of the assertion as fix because it looks not very important (probably it can be replaced by another assertion for example to not allow constructors here, see this commit) but another person in the AST area should check this.

clang/test/Analysis/ctu-astimport-virtual-assertion/main.cpp
22 ↗(On Diff #538067)

Such tests are not in the Analysis folder but in the ASTMerge folder instead. I would say that this test is not necessary if the other test (in my added note) is inserted.

danix800 planned changes to this revision.Jul 11 2023, 8:07 PM
danix800 added inline comments.Jul 11 2023, 8:10 PM
clang/test/Analysis/ctu-astimport-virtual-assertion/main.cpp
22 ↗(On Diff #538067)

Thanks for the testcase! The orignal one will be removed.

danix800 updated this revision to Diff 539910.Jul 13 2023, 2:56 AM
danix800 retitled this revision from [clang] Overridden CXXMethodDecl::isVirtual() assertion failed before fully imported. to [ASTImporter] Fix 'isVirtual()' assert failure while importing overridden methods.
danix800 edited the summary of this revision. (Show Details)
danix800 added a reviewer: balazske.

The root cause is on a circular dependency loop. Importing overridden methods before method body can fix this.

danix800 edited the summary of this revision. (Show Details)Jul 13 2023, 7:12 AM
balazske accepted this revision.Jul 14 2023, 12:32 AM
This revision is now accepted and ready to land.Jul 14 2023, 12:32 AM
This revision was landed with ongoing or failed builds.Jul 18 2023, 1:34 AM
This revision was automatically updated to reflect the committed changes.