Hi, I have tweaked the testcases as follows. They now work with -O2 and additionally test better for locations of individual warnings. The output is as follows:
../../gcc/testsuite/g++.dg/lto/odr-3_0.C:5:3: warning: type ‘struct YYSTYPE’ violates the C++ One Definition Rule [-Wodr] 5 | } YYSTYPE; // { dg-lto-message "violates the C\\+\\+ One Definition Rule" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:1:16: note: a different type is defined in another translation unit 1 | typedef struct YYSTYPE { // { dg-lto-message "type" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:4:7: note: the first difference of corresponding definitions is field ‘a’ 4 | int a; // { dg-lto-message "the first difference of corresponding definitions is field 'a'" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:1:16: note: a type with different number of fields is defined in another translation unit 1 | typedef struct YYSTYPE { // { dg-lto-message "type" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:9:7: warning: type ‘union yyalloc’ violates the C++ One Definition Rule [-Wodr] 9 | union yyalloc { // { dg-lto-warning "7: type 'union yyalloc' violates the C\\+\\+ One Definition Rule" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:6:7: note: a different type is defined in another translation unit 6 | union yyalloc { // { dg-lto-message "type" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:11:11: note: the first difference of corresponding definitions is field ‘yyvs’ 11 | YYSTYPE yyvs; // { dg-lto-message "the first difference of corresponding definitions is field 'yyvs'" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:11:11: note: a field of same name but different type is defined in another translation unit 11 | YYSTYPE yyvs; // { dg-lto-message "field of same name but different type is defined in another translation unit" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:5:3: note: type ‘struct YYSTYPE’ itself violates the C++ One Definition Rule 5 | } YYSTYPE; // { dg-lto-message "violates the C\\+\\+ One Definition Rule" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:13:16: warning: ‘a’ violates the C++ One Definition Rule [-Wodr] 13 | extern yyalloc a; // { dg-lto-warning "16: 'a' violates the C\\+\\+ One Definition Rule" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:6:7: note: type ‘union yyalloc’ itself violates the C++ One Definition Rule 6 | union yyalloc { // { dg-lto-message "type" 2 } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_0.C:9:7: note: the incompatible type is defined here 9 | union yyalloc { // { dg-lto-warning "7: type 'union yyalloc' violates the C\\+\\+ One Definition Rule" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:15:9: note: ‘a’ was previously declared here 15 | yyalloc a; // { dg-lto-message "'a' was previously declared here" } | ^ ../../gcc/testsuite/g++.dg/lto/odr-3_1.C:15:9: note: code may be misoptimized unless -fno-strict-aliasing is used which I hope is informative enough. One problem is that I not know how to pattern match warning and note or multiple notes pointing to single location, so I have added somewhat generic dg-message patterns. Help would be apprechiated. I think ODR warnings should be in reasonable shape and it would be nice to have more testsuite coverage. I find it very time consuming to write the pattern matching, hope I will improve with time :) The reason for verbosity is that they are often very cryptic to analyze when difference comes from some ifdefs or other things not obvious in the sources. Honza * g++.dg/lto/odr-2_0.C: Drop dg-lto-options. * g++.dg/lto/odr-3_0.C: Likewise; harden for optimizing compilatoin. Index: g++.dg/lto/odr-2_0.C =================================================================== --- g++.dg/lto/odr-2_0.C (revision 266382) +++ g++.dg/lto/odr-2_0.C (working copy) @@ -1,5 +1,4 @@ // { dg-lto-do link } -// { dg-lto-options { -O0 -flto } } enum a {} b; // { dg-lto-warning "6: type 'a' violates the C\\+\\+ One Definition Rule" } int main(void) Index: g++.dg/lto/odr-3_0.C =================================================================== --- g++.dg/lto/odr-3_0.C (revision 266382) +++ g++.dg/lto/odr-3_0.C (working copy) @@ -1,12 +1,32 @@ // { dg-lto-do link } -// { dg-lto-options { -O0 -flto } } typedef struct { int a; // { dg-lto-message "the first difference of corresponding definitions is field 'a'" } -} YYSTYPE; // { dg-lto-warning "3: warning: type ‘struct YYSTYPE’ violates the C\\+\\+ One Definition Rule" } -union yyalloc { // { dg-lto-warning "7: type ‘union yyalloc’ violates the C\\+\\+ One Definition Rule" } +} YYSTYPE; // { dg-lto-message "violates the C\\+\\+ One Definition Rule" 2 } + // Here we get warning and a note: + // warning: type 'struct YYSTYPE' violates the C++ One Definition Rule + // note: type 'struct YYSTYPE' itself violates the C++ One Definition Rule +union yyalloc { // { dg-lto-warning "7: type 'union yyalloc' violates the C\\+\\+ One Definition Rule" } short yyss; - YYSTYPE yyvs; // { dg-lto-message "the first difference of corresponding definitions is field ‘yyvs’" } + YYSTYPE yyvs; // { dg-lto-message "the first difference of corresponding definitions is field 'yyvs'" } }; -void b() { yyalloc c; } +extern yyalloc a; // { dg-lto-warning "16: 'a' violates the C\\+\\+ One Definition Rule" } +int +main (void) {return a.yyss;} +/* Match warnings as follows: + odr-3_0.C:5:3: warning: type 'struct YYSTYPE' violates the C++ One Definition Rule [-Wodr] + odr-3_1.C:1:16: note: a different type is defined in another translation unit^ + odr-3_0.C:4:7: note: the first difference of corresponding definitions is field 'a' + odr-3_1.C:1:16: note: a type with different number of fields is defined in another translation unit + odr-3_0.C:9:7: warning: type 'union yyalloc' violates the C++ One Definition Rule [-Wodr] + odr-3_1.C:6:7: note: a different type is defined in another translation unit + odr-3_0.C:11:11: note: the first difference of corresponding definitions is field 'yyvs' + odr-3_1.C:11:11: note: a field of same name but different type is defined in another translation unit + odr-3_0.C:5:3: note: type 'struct YYSTYPE' itself violates the C++ One Definition Rule + odr-3_0.C:13:16: warning: 'a' violates the C++ One Definition Rule [-Wodr] + odr-3_1.C:6:7: note: type 'union yyalloc' itself violates the C++ One Definition Rule + odr-3_0.C:9:7: note: the incompatible type is defined here + odr-3_1.C:15:9: note: 'a' was previously declared here + odr-3_1.C:15:9: note: code may be misoptimized unless -fno-strict-aliasing is used +*/ Index: g++.dg/lto/odr-3_1.C =================================================================== --- g++.dg/lto/odr-3_1.C (revision 266382) +++ g++.dg/lto/odr-3_1.C (working copy) @@ -1,9 +1,16 @@ -typedef struct YYSTYPE { // { dg-lto-message ":16 a different type is defined in another translation unit" } +typedef struct YYSTYPE { // { dg-lto-message "type" 2 } + // We get two notes here: + // note: a different type is defined in another translation unit + // note: a type with different number of fields is defined in another translation unit } YYSTYPE; -union yyalloc { +union yyalloc { // { dg-lto-message "type" 2 } + // We get here three notes: + // note: a different type is defined in another translation unit + // note: type 'union yyalloc' itself violates the C++ One Definition Rule short yyss; - YYSTYPE yyvs; // { dg-lto-message "the first difference of corresponding definitions is field ‘yyvs’" } + YYSTYPE yyvs; // { dg-lto-message "field of same name but different type is defined in another translation unit" } -}; -void a() { yyalloc b; } +}; + +yyalloc a; // { dg-lto-message "'a' was previously declared here" }