Can I determine if an AST node is synthesised?

Hi,

I am trying to write a new check that bans certain builtin functions (e.g. __builtin_memcpy), if they are used by the user directly. My check matches on CallExpr and I then get the name of the function called, etc.

My check basically works, but there is one very odd example where it does not.

potato.cpp:1:7: warning: __builtin_memcpy is not an allowed builtin
class Potato
      ^

Barring bugs in clang, I guess there is a legitimate reason why this node was synthesised and inserted into the tree. Is there a way to figure out if such a node is “coming from source”?

I’ve read clang: clang::CallExpr Class Reference but I couldn’t find anything obvious.

The source code is:

struct Potato
{
  int data_[2][2];
};

void Wibble()
{
  Potato a;
  Potato b;
  a = b;
}

I read more docs and tried this

  Finder->addMatcher(traverse(TK_IgnoreUnlessSpelledInSource,
			      callExpr().bind("x")), this);

Actually, this turns out to not work at all. The call is still there, even with that traversal option :frowning:

I have solved this myself by filtering out nodes with implicit ancestors.

  Finder->addMatcher
    (callExpr(unless(hasAncestor(cxxMethodDecl(isImplicit())))).bind("x"),
     this);

Isn’t the declaration of a builtin always implicit, regardless of whether it’s used explicitly or implicitly?