This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] make excessive template instantiation depth a fatal error
- From: Manuel López-Ibáñez <lopezibanez at gmail dot com>
- To: Gcc Patch List <gcc-patches at gcc dot gnu dot org>
- Cc: Jason Merrill <jason at redhat dot com>
- Date: Sun, 24 Aug 2014 12:11:05 +0200
- Subject: Re: [PATCH] make excessive template instantiation depth a fatal error
- Authentication-results: sourceware.org; auth=none
- References: <CAESRpQCHSNjYBRdRgopQvQv9L150AKR+GrORvvmyv8ZitP0Yeg at mail dot gmail dot com>
PING: https://gcc.gnu.org/ml/gcc-patches/2014-08/msg01709.html
On 18 August 2014 00:03, Manuel López-Ibáñez <lopezibanez@gmail.com> wrote:
> Following a suggestion in PR16564, this patch makes excessive template
> instantiation depth a fatal error. In fact, this allows simplifying
> the code a lot, just by printing first the context (like we do for
> every other diagnostic) instead of printing it after (which is not
> possible for a fatal error).
>
> This changes the output of quite a few testcases, so before modifying
> those I would like to know whether the idea is OK.
>
> Examples of changed output are:
>
> [Before]
> g++.dg/cpp0x/decltype26.C:6:15: error: template instantiation depth
> exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
> substituting 'template<class T> decltype (f(T())) f(T) [with T =
> <missing>]'
> g++.dg/cpp0x/decltype26.C:6:15: recursively required by substitution
> of 'template<class T> decltype (f(T())) f(T) [with T = A]'
> g++.dg/cpp0x/decltype26.C:6:15: required by substitution of
> 'template<class T> decltype (f(T())) f(T) [with T = A]'
> g++.dg/cpp0x/decltype26.C:13:8: required from here
>
> g++.dg/cpp0x/decltype26.C: In function 'int main()':
> g++.dg/cpp0x/decltype26.C:13:8: error: no matching function for call to 'f(A)'
> g++.dg/cpp0x/decltype26.C:6:18: note: candidate: template<class T>
> decltype (f(T())) f(T)
> g++.dg/cpp0x/decltype26.C:6:18: note: substitution of deduced
> template arguments resulted in errors seen above
>
> [After]
>
> g++.dg/cpp0x/decltype26.C: In substitution of 'template<class T>
> decltype (f(T())) f(T) [with T = A]':
> g++.dg/cpp0x/decltype26.C:6:15: recursively required by substitution
> of 'template<class T> decltype (f(T())) f(T) [with T = A]'
> g++.dg/cpp0x/decltype26.C:6:15: required by substitution of
> 'template<class T> decltype (f(T())) f(T) [with T = A]'
> g++.dg/cpp0x/decltype26.C:13:8: required from here
> g++.dg/cpp0x/decltype26.C:6:15: fatal error: template instantiation
> depth exceeds maximum of 900 (use -ftemplate-depth= to increase the
> maximum)
>
>
> One interesting case is for operator->(). Here we have to adjust
> the location of the template instantiations so we can point the
> user to the point of recursion:
>
> [Before]
>
> g++.dg/template/arrow1.C:12:11: error: template instantiation depth
> exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
> instantiating 'a<(n + 1)> a<n>::operator->() [with int n = 900]'
> g++.dg/template/arrow1.C:12:11: recursively required from 'a<(n +
> 1)> a<n>::operator->() [with int n = 0]'
> g++.dg/template/arrow1.C:12:11: required from here
>
> g++.dg/template/arrow1.C:12:11: error: template instantiation depth
> exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
> instantiating 'struct a<901>'
> g++.dg/template/arrow1.C:12:11: recursively required from 'a<(n +
> 1)> a<n>::operator->() [with int n = 0]'
> g++.dg/template/arrow1.C:12:11: required from here
>
> g++.dg/template/arrow1.C:12:11: error: invalid use of incomplete type
> 'struct a<901>'
> g++.dg/template/arrow1.C:5:8: note: declaration of 'struct a<901>'
>
> [After]
>
> g++.dg/template/arrow1.C: In instantiation of 'a<(n + 1)>
> a<n>::operator->() [with int n = 899]':
> g++.dg/template/arrow1.C:7:2: recursively required from 'a<(n + 1)>
> a<n>::operator->() [with int n = 1]'
> g++.dg/template/arrow1.C:7:2: required from 'a<(n + 1)>
> a<n>::operator->() [with int n = 0]'
> g++.dg/template/arrow1.C:12:11: required from here
> g++.dg/template/arrow1.C:12:11: fatal error: template instantiation
> depth exceeds maximum of 900 (use -ftemplate-depth= to increase the
> maximum)
>
> The rest of testcases follow the pattern:
>
> [Before]
>
> g++.dg/template/pr23510.C:9:1: error: expected ';' after struct definition
> g++.dg/template/pr23510.C:6:27: error: template instantiation depth
> exceeds maximum of 15 (use -ftemplate-depth= to increase the maximum)
> instantiating 'struct Factorial<5u>'
> g++.dg/template/pr23510.C:6:27: recursively required from 'struct
> Factorial<19u>'
> g++.dg/template/pr23510.C:6:27: required from 'struct Factorial<20u>'
> g++.dg/template/pr23510.C:21:20: required from here
>
> [After]
>
> g++.dg/template/pr23510.C:9:1: error: expected ';' after struct definition
> g++.dg/template/pr23510.C: In instantiation of 'struct Factorial<6u>':
> g++.dg/template/pr23510.C:6:27: recursively required from 'struct
> Factorial<19u>'
> g++.dg/template/pr23510.C:6:27: required from 'struct Factorial<20u>'
> g++.dg/template/pr23510.C:21:20: required from here
> g++.dg/template/pr23510.C:6:27: fatal error: template instantiation
> depth exceeds maximum of 15 (use -ftemplate-depth= to increase the
> maximum)
>
> Apart from these changes, the patch bootstraps and passes the
> regression suite on x86_64-linux.
>
> OK with the updated testcases?
>
> gcc/cp/ChangeLog:
>
> 2014-08-17 Manuel López-Ibáñez <manu@gcc.gnu.org>
>
> * error.c (print_instantiation_context): Delete.
> * typeck2.c (build_x_arrow): Record location when pushing
> template instantiation.
> * pt.c (push_tinst_level): Make it a wrapper around ...
> (push_tinst_level_loc): ... this. New function. Make excessive
> template instantiation depth a fatal error. Record location. Use
> bool as return type.
> (instantiate_pending_templates): Make excessive
> template instantiation depth a fatal error.
> (problematic_instantiation_changed): Use bool as return type.
> * cp-tree.h (print_instantiation_context): Delete.
> (push_tinst_level): Update declaration.
> (problematic_instantiation_changed): Likewise.
> (push_tinst_level_loc): New.
>
> gcc/testsuite/ChangeLog:
>
> 2014-08-17 Manuel López-Ibáñez <manu@gcc.gnu.org>
>
> * lib/gcc.exp: Accept "fatal error:" as error prefix.
> * lib/g++.exp: Likewise.
> * lib/obj-c++.exp: Likewise.
> * lib/objc.exp: Likewise.
> * g++.dg/template/pr16564.C: New test.