This patch copies the source location of a FUNCTION_DECL to the TEMPLATE_DECL that build_template_decl() builds out of it. Otherwise, the TEMPLATE_DECL's location becomes input_location, which is the end of the parameter list, while the FUNCTION_DECL's location is the location of the name of the function. Depending on what order templates are defined and used, gcc may emit either the FUNCTION_DECL's or TEMPLATE_DECL's location into the debug location, which causes gold's ODR checker to emit false positives.
Tested with a bootstrap+`make -k check-c++` on x86_64-unknown-linux-gnu. I'm looking to check it in to trunk, and will propagate it to the gcc-4_6-branch if you think that's the right thing to do. No more tests fail than in http://gcc.gnu.org/ml/gcc-testresults/2011-07/msg02995.html. gcc/cp/ChangeLog: 2011-07-26 Jeffrey Yasskin <jyass...@google.com> * pt.c (build_template_decl): Copy the function_decl's source location to the new template_decl. gcc/testsuite/ChangeLog: 2011-07-26 Jeffrey Yasskin <jyass...@google.com> * g++.old-deja/g++.pt/crash60.C: Updated. libstdc++-v3/ChangeLog: 2011-07-26 Jeffrey Yasskin <jyass...@google.com> * testsuite/20_util/weak_ptr/comparison/cmp_neg.cc: Updated.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 178685c..b9e09af 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4121,6 +4121,7 @@ build_template_decl (tree decl, tree parms, bool member_template_p) tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE); DECL_TEMPLATE_PARMS (tmpl) = parms; DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); + DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl); DECL_MEMBER_TEMPLATE_P (tmpl) = member_template_p; return tmpl; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash60.C b/gcc/testsuite/g++.old-deja/g++.pt/crash60.C index 747af9b..1be4678 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash60.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash60.C @@ -5,9 +5,9 @@ // We ICE'd rather than fail to instantiate. template< typename SID, class SDR > -void k( SID sid, SDR* p, +void k( SID sid, SDR* p, // { dg-error "no type named 'T'" } void (SDR::*) - ( typename SID::T ) ); // { dg-error "no type named 'T'" } + ( typename SID::T ) ); struct E { }; struct S { void f( int ); }; diff --git a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc index df18712..6eecc2d 100644 --- a/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc +++ b/libstdc++-v3/testsuite/20_util/weak_ptr/comparison/cmp_neg.cc @@ -44,16 +44,16 @@ main() // { dg-warning "note" "" { target *-*-* } 370 } // { dg-warning "note" "" { target *-*-* } 365 } -// { dg-warning "note" "" { target *-*-* } 357 } +// { dg-warning "note" "" { target *-*-* } 356 } // { dg-warning "note" "" { target *-*-* } 1103 } // { dg-warning "note" "" { target *-*-* } 1098 } -// { dg-warning "note" "" { target *-*-* } 1090 } +// { dg-warning "note" "" { target *-*-* } 1089 } // { dg-warning "note" "" { target *-*-* } 485 } // { dg-warning "note" "" { target *-*-* } 479 } -// { dg-warning "note" "" { target *-*-* } 469 } -// { dg-warning "note" "" { target *-*-* } 814 } -// { dg-warning "note" "" { target *-*-* } 1056 } -// { dg-warning "note" "" { target *-*-* } 1050 } -// { dg-warning "note" "" { target *-*-* } 342 } -// { dg-warning "note" "" { target *-*-* } 292 } +// { dg-warning "note" "" { target *-*-* } 468 } +// { dg-warning "note" "" { target *-*-* } 813 } +// { dg-warning "note" "" { target *-*-* } 1055 } +// { dg-warning "note" "" { target *-*-* } 1049 } +// { dg-warning "note" "" { target *-*-* } 341 } +// { dg-warning "note" "" { target *-*-* } 291 } // { dg-warning "note" "" { target *-*-* } 224 }