ASTMatcher unexpected result

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

ASTMatcher unexpected result

Manas via cfe-dev
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
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: ASTMatcher unexpected result

Manas via cfe-dev
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
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: ASTMatcher unexpected result

Manas via cfe-dev
Hi Nathan, thanks for your swift answer.

the binary works nicely on 11.0.0-rc5 on Apple.

Best, Siegfried

> On 6Oct, 2020, at 20:31, Nathan James <[hidden email]> wrote:
>
> 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.
>
> 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
>> [hidden email]
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev