[cfe-dev] CXXRecordDecl::getNumBases() in matcher asserts under certain conditions

Adam McLaughlin via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 29 06:52:58 PDT 2016


Hi Jason,

Do you care about the distinction between class declarations and class
definitions? If not, the following matcher should suffice:

DeclarationMatcher CLASS_MATCHER
    = cxxRecordDecl(
       isDefinition(),
        unless(isTemplateInstantiation()),
        hasAncestor(
            namespaceDecl(hasName("test"))
        )
      ).bind("class");


Similarly, in the code that handles the matcher you could check if the
result is a definition. This latter approach is useful if you do care about
this distinction.

-Adam

On Thu, Jul 28, 2016 at 6:11 PM, Jason Murray via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> Hey all,
>
> I've been working with AST Matchers with minimal issues for a while
> now, but I recently started running into issues when querying matched
> CXXRecordDecls for information about their base classes.
>
> Here's a repro repo: https://github.com/nopppers/clang-bases-bug
>
> Given the following matcher,
>
> DeclarationMatcher CLASS_MATCHER
>     = cxxRecordDecl(
>         unless(isTemplateInstantiation()),
>         hasAncestor(
>             namespaceDecl(hasName("test"))
>         )
>       ).bind("class");
>
> Calling CXXRecordDecl::getNumBases() or other base-class-related
> functions like bases_begin() on the result of the matcher will
> sometimes hit an assert. The debug message in the assert is
> "queried property of class with no definition"
>
> The first condition under which the assert will trigger is when the
> matcher callback recieves the CXXRecordDecl for the implicit
> self-reference that the class has. For example, if the matcher is run
> on the following code:
>
> namespace test
> {
> class Foo {};
> }
>
> The call to getNumBases() will succeed for the first match, test::Foo,
> and assert for the match test::Foo::Foo.
>
> To circumvent this, I've tried testing for
> CXXRecordDecl::isImplicit(), which works around the assert properly.
> There is, however, a second situation where the assert is triggered
> that I don't understand.
>
> Running the matcher on the following code
>
> namespace test
> {
>     template <typename T>
>     class DummyTemplate{};
>
>     class Dummy
>     {
>     public:
>         // DummyTemplate<int> uncommentMeAndTheAssertWontTrigger;
>     };
>
>     extern DummyTemplate<int> triggersAssertIfAboveIsCommentedOut;
> }
>
> Results in the same assert, but only if the variable declaration in
> the class is commented out.
> Adding a classTemplateSpecialization matcher reveals some more info:
>
> Output with class var decl commented out:
>
> Found CXXRecordDecl
> NumBases for test::DummyTemplate: 0
> End.
> Found CXXRecordDecl
> NumBases for test::DummyTemplate: Assertion failed: DD && "queried
> property of class with no definition", file
>
> S:\programming\libraries\clang\llvm\tools\clang\include\clang/AST/DeclCXX.h,
> line 595
>
> Output with var decl uncommented:
>
> Found CXXRecordDecl
> NumBases for test::DummyTemplate: 0
> End.
> Found ClassTemplateSpecializationDecl
> NumBases for test::DummyTemplate: 0
> End.
> Found CXXRecordDecl
> NumBases for test::Dummy: 0
> End.
>
> So what is one to do? I'm unsure whether hitting the assert is
> intentional in either case. If it is, how can I avoid hitting it in
> the second case?
>
> Repro link again: https://github.com/nopppers/clang-bases-bug
>
> Regards,
> Jason Powers Murray
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20160729/a4169f54/attachment.html>


More information about the cfe-dev mailing list