[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