https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96969
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- First file: # 1 "one.cc" # 1 "/tmp//" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "one.cc" # 1 "header.h" 1 struct X { int member; }; # 3 "one.cc" 2 long f(X*); int main() { X x = { 0 }; return f(&x); } Second file: # 1 "two.cc" # 1 "/tmp//" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "two.cc" # 1 "header.h" 1 struct X { int field; }; # 3 "two.cc" 2 long f(X* x) { return x->field; } $ g++ -g -flto one.ii two.ii -Wall header.h:1:8: warning: type ‘struct X’ violates the C++ One Definition Rule [-Wodr] 1 | struct X | ^ header.h:1:8: note: a different type is defined in another translation unit 1 | struct X | ^ header.h:3:7: note: the first difference of corresponding definitions is field ‘member’ 3 | int NAME; | ^ header.h:3:7: note: a field with different name is defined in another translation unit 3 | int NAME; | ^ The only locations are from header.h, but the tokens in that header are identical before preprocessing. The problems are due to how that header is included by one.cc and two.cc so those names should be included in the diagnostics.