[clang-tidy] using isInTemplateInstantiation asserts

Hi guys,
I am having trobles with isInTemplateInstantiation matcher. When I run my matcher (http://reviews.llvm.org/D18136), it fails on the assert in ASTTypeTraits.h:299, when KindId is NodeKindId::NKI_TemplateArgument.

I think my matcher is fine, and there is bug somewhere. Can someone please tell me if I am doing something wrong, and if not, why it doesn’t work and what I should fix?

Here is my backtrace http://4programmers.net/Pastebin/5347

Best
Piotr

bump.

Can you provide a minimal test for this?

This should be enough to break this matcher
http://pastebin.com/CH7a3hur

I can’t reproduce the issue (how I understand it) using clang-query, and http://reviews.llvm.org/D18136 doesn’t apply cleanly, since it depends on some other patch.

$ cat /tmp/q.cc
namespace boost {
template <typename T, typename C>
T lexical_cast(const C&) {
return T();
}
}

namespace std {
template
class basic_string {};
using string = basic_string;
}

int g();
long long f(int p);
using namespace boost;

template
void string_as_T() {
boost::lexical_cast(42);
}

int main() { string_as_Tstd::string(); }

$ clang-query /tmp/q.cc – -std=c++11
clang-query> m callExpr()

Match #1:

/tmp/q.cc:20:3: note: “root” binds here
boost::lexical_cast(42);
^~~~~~~~~~~~~~~~~~~~~~~~~~

Match #2:

/tmp/q.cc:20:3: note: “root” binds here
boost::lexical_cast(42);
^~~~~~~~~~~~~~~~~~~~~~~~~~

Match #3:

/tmp/q.cc:23:14: note: “root” binds here
int main() { string_as_Tstd::string(); }
^~~~~~~~~~~~~~~~~~~~~~~~~~
3 matches.
clang-query> m callExpr(unless(isInTemplateInstantiation()))

Match #1:

/tmp/q.cc:20:3: note: “root” binds here
boost::lexical_cast(42);
^~~~~~~~~~~~~~~~~~~~~~~~~~

Match #2:

/tmp/q.cc:23:14: note: “root” binds here
int main() { string_as_Tstd::string(); }
^~~~~~~~~~~~~~~~~~~~~~~~~~
2 matches.
clang-query>

It requires this patch:
http://reviews.llvm.org/D18274

I am trying to reproduce it right now with clang-query

FWIW, a larger part of your matcher also works fine in clang-query:

$ cat /tmp/q.cc
namespace boost {
template <typename T, typename C>
T lexical_cast(const C&) {
return T();
}
}

namespace std {
template
class basic_string {};
using string = basic_string;
}

int g();
long long f(int p);
using namespace boost;

template
void string_as_T() {
boost::lexical_cast(42);
}

int main() {
string_as_Tstd::string();
boost::lexical_caststd::string(24);
}

$ clang-query /tmp/q.cc – -std=c++11
clang-query> m callExpr(hasDeclaration(functionDecl(returns(hasDeclaration(classTemplateSpecializationDecl(hasName(“std::basic_string”),hasTemplateArgument(0,templateArgument().bind(“char_type”))))),hasName(“boost::lexical_cast”),hasParameter(0, hasType(qualType())))),argumentCountIs(1))

Match #1:

/tmp/q.cc:20:3: note: “root” binds here
boost::lexical_cast(42);
^~~~~~~~~~~~~~~~~~~~~~~~~~

Match #2:

/tmp/q.cc:25:3: note: “root” binds here
boost::lexical_caststd::string(24);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 matches.
clang-query> m callExpr(hasDeclaration(functionDecl(returns(hasDeclaration(classTemplateSpecializationDecl(hasName(“std::basic_string”),hasTemplateArgument(0,templateArgument().bind(“char_type”))))),hasName(“boost::lexical_cast”),hasParameter(0, hasType(qualType())))),argumentCountIs(1),unless(isInTemplateInstantiation()))

Match #1:

/tmp/q.cc:25:3: note: “root” binds here
boost::lexical_caststd::string(24);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 match.
clang-query> ^D

(the first matcher lacks the unless(isInTemplateInstantiation()) part, the second one has it, hence it skips the match in a template instantiation).

The only part of your matcher that is missing from this example is has(substTemplateTypeParmType(isStrictlyInteger())) that needs a locally-defined matcher isStrictlyInteger().

Are you using debug build?
when I use the second matcher that you have send I got core dump.

http://pastebin.com/Z6V3jC3X

I am not using the most recent clang trunk, but someting about 2 weeks old, but I don’t think it is the case.
BTW on other build it works perfectly, it doesn;t crash etc, but it has asserts disabled.

I use an assertions-enabled build of clang-query built just a few hours ago.

I am building most recent debug build right now, but what I saw in the code, there was no chanes in ASTTypeTraits.* files since so I don’t excpect it will make a difference.

yep, the same assert on most recent build. Are you sure your assertions are enabled?

Yes, LLVM_ENABLE_ASSERTIONS is ON in my configuration.

BTW, do you update all working copies (llvm, cfe and clang-tools-extra)?

Yes of course. I am rebuilding clang-query in empty build just to make sure it’s not some weird cmake behaviour.

Ok I see what is the problem.
The code that I have sent doesn’t trigger the problem. This one works:
http://pastebin.com/TkTv2wpC

I have also rebuild clang-query in debug so I am 100% sure that te build is ok.

I was able to reproduce this. Looks like the bug depends on memory layout or something like this, since it appears and disappears from build to build. I’ll try to run this with ASan and see whether it finds any issues.

Sent out a fix: http://reviews.llvm.org/D19144