Jason Merrill <ja...@redhat.com> writes: > What if the built-in macro appears in a macro defined in a system > header but used in user code? This would resolve the location all the > way to the user code, and warn. I think we only want to step out > until we reach a non-built-in macro, not all the way to the outermost > expansion point.
I think it's not that simple. If we simply do what you propose, then we regress on a test like the below, distilled from testsuite/c-c++-common/dfp/convert-int-saturate.c: volatile unsigned int usi; int main () { usi = DEC32_MAX; /* { dg-warning "overflow in implicit constant conversion" } */ ... } We fail to warn here because DEC32_MAX is defined in the system header float.h to a built-in macro: #define DEC32_MAX __DEC32_MAX__ I tried to do what the C FE seems to do, which is to consider that the default location (the global input_location variable) is on the LHS of the assignment (on the usi variable), rather than on the token that comes from DEC32_MAX. But then it regresses notably on tests like testsuite/g++.dg/warn/pr35635.C: void func3() { unsigned char uchar_x; ... uchar_x = bar != 0 ? (unsigned char) 1024 : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */ } It seems to me that ultimately, things like conversion routines that emit diagnostics should know about the expression that represents the context in which they are emitting the said diagnostic. In this particular case, warnings_for_convert_and_check should know about the assignment expression "usi = DEC32_MAX", so that it can determine that the whole expression is spelled in user code, and thus, the diagnostic should be emitted. IOW, just knowing about the single token on which the error occurs is not enough to decide. But handling that seems like a huge task. So maybe we could, for now, going for the solution that makes us regress the less, while improving things nonetheless? -- Dodji