| Issue |
180638
|
| Summary |
Deferred diagnostics issued repeatedly with misleading notes attached
|
| Labels |
cuda,
clang:diagnostics,
SYCL
|
| Assignees |
|
| Reporter |
tahonermann
|
The following example is ill-formed because CUDA does not allow code emitted during device compilation to call a host-only function. `hf()` is a host-only function. The lambda in the definition of `l` is a host-device function that may be called by code emitted for either host or device compilation; the lambda erroneously calls a host-only function, but that is only an error if the function is actually called in a device context. `df1()` and `df2()` are both device-only functions.
https://godbolt.org/z/6qGnjrjqY
```
$ cat t.cpp
// Macros locally defined to avoid needing a local CUDA toolkit installation.
#define __global__ __attribute__((global))
#define __host__ __attribute__((host))
#define __device__ __attribute__((device))
__host__ void hf();
__device__ auto l =
[] {
hf(); // #1
hf(); // #2
};
__device__ void df1() {
l();
}
__device__ void df2() {
l();
}
```
Clang produces the following diagnostics. The `-nocudainc` and `-nocudalib` options are used to avoid a dependency on a local CUDA toolkit installation.
```
$ clang -fsyntax-only -nocudainc -nocudalib t.cu
t.cu:8:5: error: reference to __host__ function 'hf' in __host__ __device__ function
8 | hf(); // #1
| ^
t.cu:12:4: note: called by 'df1'
12 | l();
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
t.cu:9:5: error: reference to __host__ function 'hf' in __host__ __device__ function
9 | hf(); // #2
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
t.cu:8:5: error: reference to __host__ function 'hf' in __host__ __device__ function
8 | hf(); // #1
| ^
t.cu:15:4: note: called by 'df2'
15 | l();
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
t.cu:9:5: error: reference to __host__ function 'hf' in __host__ __device__ function
9 | hf(); // #2
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
4 errors generated when compiling for sm_52.
```
The diagnostics have the following issues:
1. Diagnostics related to the calls to `hf()` at the locations annotated as `#1` and `#2` are issued multiple times.
2. The "called by" notes are misleading. Consider the "called by 'df1'" case. The error concerns an attempted call to a function named `hf()`. The note suggests the call was made by `df()` and then presents a source line showing a call to `l()`. The note is intended to indicate that `l()` (the lambda) was used as a device function due to it's use in `df1()`. This is useful information, but the presentation is confusing.
3. The "called by" notes are only issued for the first deferred error/warning diagnostic that is issued for a function. Subsequent diagnostics are not noted as being related to use of the function in a device context.
The user experience could be improved by doing one or more of the following:
1. Instead of attaching notes to deferred diagnostics to note the device context, issue distinct diagnostics for each use of a function with deferred diagnostics.
2. Attaching notes that more closely match those used in code synthesis contexts:
- "in instantiation of ... requested here"
- "in implicit initialization of ..."
- "in implicit call to ..."
- "in evaluation of ... needed here"
- "in call to ..."
3. Only issuing deferred diagnostics in the context of the first call from a device context.
4. Only issuing the first deferred diagnostic similar to the diagnostic behavior for errors in template instantiation contexts; see https://godbolt.org/z/cGYEMzTWj.
For example, the follow demonstrates what implementation of options 1 and 3 might look like. The term "device-promoted" is intended to indicate a function that is not declaratively restricted to host or device context but is used in a device context (for CUDA, I believe this only applies to lambdas).
```
t.cu:12:4: error: use of device-promoted function 'lambda at ...' with errors
12 | l();
| ^
t.cu:8:5: error: reference to __host__ function 'hf' in __host__ __device__ function
8 | hf(); // #1
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
t.cu:9:5: error: reference to __host__ function 'hf' in __host__ __device__ function
9 | hf(); // #2
| ^
t.cu:5:15: note: 'hf' declared here
5 | __host__ void hf();
| ^
t.cu:15:4: error: use of device-promoted function 'lambda at ...' with errors
15 | l();
| ^
```
These issues were observed while attempting to use deferred diagnostics to implement some SYCL related diagnostics. These issues are not specific to CUDA; they are issues with the deferred diagnostic support.
@yxsamliu and @rjmccall for awareness; the current behavior was implemented in commit 2c31aa2de13a23a00ced87123b92e905f2929c7b for https://reviews.llvm.org/D77028.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs