Использование сопоставителей clang для определения последовательности шаблонов

Можно ли использовать сопоставители clang для определения последовательности шаблонов в программе?

Например, мне нужно найти случаи, когда паттерн1 предшествует паттерну2.

Например:

Pattern1 = присвоение значения указателю P
pattern2 = разыменование указателя P

Я могу идентифицировать случаи, когда в коде встречаются шаблоны1 и шаблон2, но можно ли указать порядок? (скажем, шаблон1 должен произойти до шаблона2 и соответствовать только этим случаям) Спасибо!


person Mehrnoosh EP    schedule 25.05.2016    source источник


Ответы (1)


Правильный ответ

На самом деле обход AST для построения паттернов последовательности (который является основой статического анализа) на самом деле не является правильным подходом, потому что вы НЕ знаете, произойдет ли на самом деле утверждение pattern1 до pattern2

Рассмотреть возможность

 int foo() {
       int a = 0;
       int *b;
       int c = -1;
       if(c < 0) goto fixit;
 nowhat:
       b = &a;
 fixit: 
       c = *b;
       goto nowhat;
 }

Как видите, AST здесь не поможет, но CFG — правильный выбор.

Некоторый ответ с использованием AST

Если вы посмотрите на Traversal Matchers в AST (v6.0.0), то увидите, что они в значительной степени иерархичны по своей природе. Вы хотите расширить соответствие, чтобы найти братьев и сестер.

Большая часть того, о чем я собираюсь рассказать, предполагает, что вы знаете, как реализовать пользовательский сопоставитель AST. Если нет, это довольно хорошо объясняет Ману Санчес в его Написание AST Matchers для записи в блоге libclang.

Не уверен, что он на самом деле напишет сопоставитель братьев и сестер, но он очень близок к этому, поэтому начните с этого, а затем вам придется реализовать что-то вроде этого:

Скажем, учитывая код:

  class P {}; class Q {}; class R {};

Мы хотим иметь возможность делать что-то вроде:

 (matcher = recordDecl(hasName("P"), \
        hasNextSibling(recordDecl(hasName("R"))))`

Вы можете комбинировать matchesChild и matchesParent в классе AstMatchFinder и проходить дочерние элементы родителя текущего курсора (это будут братья и сестры: P). Прочтите сноски, так как вам придется реализовать BoundCursors, чтобы избежать безудержной рекурсии.

person Ahmed Masud    schedule 27.09.2017