Issue 143585
Summary Bad source locations in implicit deduction guides AST nodes
Labels new issue
Assignees
Reporter michael-jabbour-sonarsource
    ## Problem

There seems to be a general problem in `SourceLocation`s of AST nodes that are created in `TemplateSubstitutionKind::Rewrite` mode. My understanding is that [this mode is used](https://github.com/llvm/llvm-project/blob/7e471c1fd0c4de4656cfaac39e247d207e987510/clang/include/clang/Sema/Template.h#L46-L55) to “rewrite” constructor decls as implicit deduction guides, or when "rewriting" expressions for the spacehip operator. The problem is that in this mode, `TemplateInstantiator` re-uses the location of child nodes while substituting into the template pattern. For example, in the following example:

```cpp
template <int N1, int N2>
struct SomeClass2Arrs {
  SomeClass2Arrs(int (&arr)[N2]);
  SomeClass2Arrs(int (&arr1)[N1], int (&arr2)[N2]);
  template <int OtherN,
            int Test1 = N1 + OtherN | 1>
  constexpr SomeClass2Arrs(const SomeClass2Arrs<N1, N2>& other);

};

template <int N> using SomeClassSquare1 = SomeClass2Arrs<N, N>;
int arr[10]; SomeClassSquare1 scs(arr, arr);

template <int N> using SomeClass1Arr = SomeClass2Arrs<("this is an arbitrarily complex expr", "using comma", 42), N>;
SomeClass1Arr sc1a(arr);
```

In this case, the implicit deduction guide doesn’t contain the `DeclRefExpr` to `N1` anymore, but the whole thing has been substituted by the _expression_ at line 14. The problem is that this results in bad incorrect `SourceLocation` for many nodes (e.g. note the bad range for BinaryOperator '|' `<line:14:55, line:6:39>`):

```
|-FunctionTemplateDecl 0x18ef4d10 <line:14:1, col:116> col:18 implicit <deduction guide for SomeClass1Arr>
| |-NonTypeTemplateParmDecl 0x18ef4448 <col:11, col:15> col:15 'int' depth 0 index 0 N
| |-NonTypeTemplateParmDecl 0x18ef44c0 <line:5:13, col:17> col:17 'int' depth 0 index 1 OtherN
| |-NonTypeTemplateParmDecl 0x18ef4538 <line:6:13, col:39> col:17 'int' depth 0 index 2 Test1
| | `-TemplateArgument <line:14:55, line:6:39> expr '("this is an arbitrarily complex expr" , "using comma" , 42) + OtherN | 1'
| |   `-BinaryOperator 0x18ef45b0 <line:14:55, line:6:39> 'int' '|'
| |     |-BinaryOperator 0x18ef4590 <line:14:55, line:5:17> 'int' '+'
| |     | |-ParenExpr 0x18ef2c58 <line:14:55, col:112> 'int'
| |     | | `-BinaryOperator 0x18ef2c38 <col:56, col:110> 'int' ','
| |     | |   |-BinaryOperator 0x18ef2bf8 <col:56, col:95> 'const char[12]' lvalue ','
| |     | |   | |-StringLiteral 0x18ef2b30 <col:56> 'const char[36]' lvalue "this is an arbitrarily complex expr"
| |     | |   | `-StringLiteral 0x18ef2bd0 <col:95> 'const char[12]' lvalue "using comma"
| |     | |   `-IntegerLiteral 0x18ef2c18 <col:110> 'int' 42
| |     | `-DeclRefExpr 0x18ef4518 <line:5:17> 'int' NonTypeTemplateParm 0x18ef44c0 'OtherN' 'int'
| |     `-IntegerLiteral 0x18ec8ef0 <line:6:39> 'int' 1
```
Live example on CE: https://godbolt.org/z/87rs3aP89

## Impact

The issue seems to impact some clang-tidy checks. For example, when running the `hicpp-signed-bitwise` check on the "simpler" example below, one can see that one of the reported issues has an incorrect range:

```cpp
template <int N> struct SomeClass {
  explicit SomeClass(int(&)[N]);
  template <int OtherN,
            int Test = OtherN + 1 | N>
  SomeClass(const SomeClass<OtherN>& other);

};

// Trigger the generation of the implicit deduction guides
int arr[5]; SomeClass s(arr);
```

```
$ clang-tidy-19 --checks=-*,hicpp-signed-bitwise file.cpp --
3 warnings generated.
/home/user/file.cpp:3:17: warning: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise]
    3 |   template <int OtherN,
      |                 ^~~~~~~
    4 |             int Test = OtherN + 1 | N>
      |             ~~~~~~~~~~~~~~~~~~~~~ ~
/home/user/file.cpp:4:17: warning: use of a signed integer operand with a binary bitwise operator [hicpp-signed-bitwise]
    4 |             int Test = OtherN + 1 | N>
      |                        ^~~~~~~~~~ ~

```
Live example on CE: https://godbolt.org/z/K36qvcP8o

_The result of running `hicpp-signed-bitwise` check on the previous example also results in broken ranges and can be seen in the previous CE link._

I am wondering if the described behavior is intended (e.g. for performance reasons, or to avoid making `TemplateInstantiator` more complex). Are there any caveats that one should be aware of before trying to fix the AST location in `Rewrite` mode? Or does this feel out of scope for the clang frontend? I would appreciate any thoughts about that.

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to