llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.81k stars 11.91k forks source link

Some Matchers return Blank match with diag output #51810

Open Dylan-Brotherston opened 2 years ago

Dylan-Brotherston commented 2 years ago
Bugzilla Link 52468
Version unspecified
OS Linux
CC @AaronBallman

Extended Description

Using the example given on the AST Matcher Reference for the Matcher

  void f(int b) {
    int a[b];
  }

running the example snippet will not produce the desired output

clang-query> m variableArrayType(hasSizeExpr(ignoringImpCasts(declRefExpr(to(varDecl(hasName("b")))))))

Match #​1:

1 match.

The match occurs but no actual information is returned.

Using any of:

set output print
set output detailed-ast
set output dump

will give output.

But:

set output diag

the default, will return it to no output.

This can be simplified to the most simple variableArrayType() expression with the same result (also on a bigger file)

clang-query> m variableArrayType()

Match #​1:

Match #​2:

Match #​3:

Match #​4:

4 matches.

This is of course in contrast to other matchers like varDecl() that will always output

clang-query> m varDecl()

Match #​1:

vla.c:1:8: note: "root" binds here
void f(int b) {
       ^~~~~

Match #​2:

vla.c:2:3: note: "root" binds here
  int a[b];
  ^~~~~~~~
2 matches.

Other matchers have a similar issue:

clang-query> m arrayType()

Match #​1:

Match #​2:

2 matches.

Apologies if this is documented behavior, but i haven't found it anywhere.

AaronBallman commented 2 years ago

The issue is not specific to variableArrayType(), this happens for all type matchers: https://godbolt.org/z/GadjG3M3n

The issue is that DynTypedNode::getSourceRange() has no idea how to find the source range for a type that is not a type location because types don't store their source location directly (for performance reasons). But the MatchQuery::run() method looks to see if the matched location has a valid source location before attempting to print a text diagnostic from it. This is why set output diag is the failure point -- other outputs don't require a valid source location.

A workaround for this is to wrap your type matcher with loc() to convert it to a TypeLoc matcher that has source location information. e.g., https://godbolt.org/z/qa18escqG

AaronBallman commented 2 years ago

Can confirm that this occurs on trunk and is not expected behavior. https://godbolt.org/z/jcPKGo1sW

Dylan-Brotherston commented 2 years ago
$ clang --version
Ubuntu clang version 11.0.0-2~ubuntu20.04.1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$ clang-query-12 --version
LLVM (http://llvm.org/):
  LLVM version 12.0.0

  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: znver2