Description of problem: g++ 4.1.x chokes on the attached code when using -fabi-version=1. It works with abi versions 0 and 2, and g++ 3.x and 4.2 and newer work with all abi versions. $ g++ -fabi-version=1 templtest.cc templtest.cc: In constructor ‘S::S(U) [with U = int]’: templtest.cc:27: instantiated from here templtest.cc:21: error: no matching function for call to ‘T::f(char [12])’ templtest.cc:6: note: candidates are: int T::f(char (&)[N]) const [with long unsigned int N = 12ul] Version-Release number of selected component (if applicable): gcc-4.1.2-44.el5.x86_64 gcc-c++-4.1.2-44.el5.x86_64 How reproducible: every time Steps to Reproduce: 1. g++ -fabi-version=1 templtest.cc Actual results: fails to compile and prints above errors Expected results: success in compiling Additional info: also fails on RHEL 4.7 with gcc4-c++-4.1.2-42.EL4 tech preview packages
Created attachment 335155 [details] demo program
also, this code works when not called from a class constructor. struct T { template<size_t N> int f(char (&s)[N]) const { return N; } }; class S { char str[12]; T t; public: template<class U> S(U x) { printf("%dn", t.f(str)); } }; int main() { S s(1); T t; char q[15]; t.f(q); } yeilds the same error message: templtest.cc: In constructor ‘S::S(U) [with U = int]’: templtest.cc:27: instantiated from here templtest.cc:21: error: no matching function for call to ‘T::f(char [12])’ templtest.cc:6: note: candidates are: int T::f(char (&)[N]) const [with long unsigned int N = 12ul]
This shows up in the array dimension checking code: /* Check that the dimensions are the same. */ if (!cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))) return false; max1 = TYPE_MAX_VALUE (d1); max2 = TYPE_MAX_VALUE (d2); if (processing_template_decl && !abi_version_at_least (2) && !value_dependent_expression_p (max1) && !value_dependent_expression_p (max2)) { /* With abi-1 we do not fold non-dependent array bounds, (and consequently mangle them incorrectly). We must therefore fold them here, to verify the domains have the same value. */ max1 = fold (max1); max2 = fold (max2); } if (!cp_tree_equal (max1, max2)) return false; Here cp_tree_equal fails when using -fabi-version=1 . The comment about abi-1 is interesting, though I don't know if it has anything to do with it. The differing values for max1 and max2 is: (gdb) p t1.common.code $79 = MINUS_EXPR (gdb) p t2.common.code $80 = INTEGER_CST
This has been fixed by fix for http://gcc.gnu.org/PR27640 in 4.2 and above and backport of that patch fixes this on 4.1 branch as well. Except for small comment changes the patched 4.1 instantiate_template is identical to the one in 4.4, so at least in that function no follow-ups were needed. I haven't tried to fully bootstrap/regtest this patch yet.
Created attachment 335355 [details] gcc41-pr27640.patch Backported patch.
I've tested and confirmed that the patch does enable compiling w/o error with -fabi-version=1
I've bootstrapped/regtested the patch and it caused no regressions.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2009-1376.html