[cfe-dev] ASTMatcher unexpected result

Nathan James via cfe-dev cfe-dev at lists.llvm.org
Tue Oct 6 11:31:45 PDT 2020


Hi Siegfried,

I believe this bug was fixed in https://reviews.llvm.org/D80025. A
quick check against trunk clang-query shows correct behaviour no matter
which order the submatchers appear.

>match forStmt(unless(hasAncestor(forStmt())),
unless(hasDescendant(forStmt())))

>Match #1:
>
>
>
><source>:3:3: note: "root" binds here
>
>  for (int i1 = 0; i1 < n; i1++) {  // dosomething();
>
>  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>1 match.

>match forStmt(unless(hasDescendant(forStmt())),
unless(hasAncestor(forStmt())))

>Match #1:
>
>
>
><source>:3:3: note: "root" binds here
>
>  for (int i1 = 0; i1 < n; i1++) {  // dosomething();
>
>  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>1 match.

Can you please check against trunk(or latest release
candidate(currently RC5) on your end. The patch was landed before the
11 branch was created so it should be good there.

~Nathan

On Tue, 2020-10-06 at 10:25 +0000, Hartogs Siegfried via cfe-dev wrote:
> Hi everyone, 
> 
> I'm trying to use AST Matchers in clang-query to find single-depth
> for-loops,
> i.e. for-loops that are neither contained in any other for-loop nor
> contain for-loops themselves.
> 
> Approach:
> forStmt( unless(hasAncestor(forStmt())),
> unless(hasDescendant(forStmt())) )
> 
> 
> In the following code, I want it to match only the loop in foo1, but
> unfortunately it also matches the loop in foo2.
> 
> 
> void foo1(){ int n = 10; for(int i1=0; i1<n; i1++){ // dosomething();
> } } void foo2(){ int n = 10; for(int i21=0; i21<n; i21++){
>  for(int i22=0; i22<n; i22++){ // dosomething(); } } }
> 
> 
> Match #1:
> ~/cq.cpp:4:5: note: "root" binds here
>     for(int i1=0; i1<n; i1++){
>     ^~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Match #2:
> ~/cq.cpp:11:5: note: "root" binds here
>     for(int i21=0; i21<n; i21++){
>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 2 matches.
> 
> When I interchange "hasAncestor" and "hasDescendant" in the matcher,
> the second match changes:
> 
> 
> Match #1:
> ~/cq.cpp:4:5: note: "root" binds here
>     for(int i1=0; i1<n; i1++){
>     ^~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Match #2:
> ~/cq.cpp:11:5: note: "root" binds here
>     for(int i22=0; i21<n; i22++){
>     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 2 matches.
> 
> To me, it doesn't make sense why the result changes (implicit allOf()
> matcher's argument order shouldn't matter), but I don't understand
> why the matcher returns a loop from foo2 in the first place. 
> 
> Best regards,
> Siegfried Hartogs
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



More information about the cfe-dev mailing list