Bug 34950 - [4.2/4.3/4.4 Regression] ICE in svn boost math toolkit
Summary: [4.2/4.3/4.4 Regression] ICE in svn boost math toolkit
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.2.3
: P1 normal
Target Milestone: 4.2.4
Assignee: Jason Merrill
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 35255
  Show dependency treegraph
 
Reported: 2008-01-24 01:26 UTC by Andreas Kloeckner
Modified: 2008-02-20 04:48 UTC (History)
7 users (show)

See Also:
Host:
Target: x86_64-linux-gnu
Build:
Known to work: 2.95.3 3.3.6
Known to fail: 4.2.3 4.3.0
Last reconfirmed: 2008-02-19 20:17:21


Attachments
ICE'ing preprocessed source (363.64 KB, application/octet-stream)
2008-01-24 01:27 UTC, Andreas Kloeckner
Details
unincluded testcase (237.61 KB, application/octet-stream)
2008-01-24 10:56 UTC, Richard Biener
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Kloeckner 2008-01-24 01:26:32 UTC
The attached preprocessed source causes the following ICE:
---------------------------------------------------------------------
/home/andreas/pool/include/boost-1_35/boost/math/policies/policy.hpp: In instantiation of ‘boost::math::policies::precision<double, Policy>’:
/home/andreas/pool/include/boost-1_35/boost/math/special_functions/math_fwd.hpp:544:   instantiated from ‘boost::math::detail::bessel_traits<int, double, Policy>’
src/wrapper/wrap_special_function.cpp:107:   instantiated from here
/home/andreas/pool/include/boost-1_35/boost/math/policies/policy.hpp:734: internal compiler error: in dependent_type_p, at cp/pt.c:12855
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
---------------------------------------------------------------------
gcc -v:
---------------------------------------------------------------------
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)
---------------------------------------------------------------------
Comment 1 Andreas Kloeckner 2008-01-24 01:27:16 UTC
Created attachment 15012 [details]
ICE'ing preprocessed source
Comment 2 Richard Biener 2008-01-24 10:56:55 UTC
Created attachment 15015 [details]
unincluded testcase

I think this is somehow an invalid testcase as I cannot find a single compiler
to build it without errors ;)
Comment 3 Richard Biener 2008-01-24 11:03:13 UTC
reducing anyway
Comment 4 Andrew Pinski 2008-01-24 11:03:57 UTC
I had to use -fpermissive to get no errors.  I am reducing too.
Comment 5 Richard Biener 2008-01-24 15:52:12 UTC
Reduced (invalid?) testcase:

template <class Real, class Policy> struct precision {
    typedef typename Policy::precision_type precision_type;
};
template <class T1, class T2, class Policy>
struct bessel_traits {
    typedef T1 result_type;
    typedef typename precision<result_type, Policy>::type precision_type;
};

template <class Fn>
void
def(char const* name, Fn fn);

template <class T1, class T2, class Policy>
typename bessel_traits<T1, T2, Policy>::result_type
cyl_bessel_j(T1 v, T2 x, const Policy& pol);

void hedge_expose_polynomial()
{
    def("cyl_bessel_j", cyl_bessel_j<int, double>);
}


EDG says

ice.1.min.cpp(20): error: no instance of function template "def" matches the argument list
            argument types are: (const char [13], <unknown-type>)
      def("cyl_bessel_j", cyl_bessel_j<int, double>);
      ^

compilation aborted for ice.1.min.cpp (code 2)

4.1 errors with

ice.1.min.cpp: In instantiation of 'precision<int, Policy>':
ice.1.min.cpp:7:   instantiated from 'bessel_traits<int, double, Policy>'
ice.1.min.cpp:20:   instantiated from here
ice.1.min.cpp:2: error: no type named 'precision_type' in 'Policy'
ice.1.min.cpp: In instantiation of 'bessel_traits<int, double, Policy>':
ice.1.min.cpp:20:   instantiated from here
ice.1.min.cpp:7: error: no type named 'type' in 'struct precision<int, Policy>'
ice.1.min.cpp: In function 'void hedge_expose_polynomial()':
ice.1.min.cpp:20: error: no matching function for call to 'def(const char [13], <unresolved overloaded function type>)'
Comment 6 Andrew Pinski 2008-01-24 19:04:57 UTC
This code is invalid as you don't have a third template argument for cyl_bessel_j.
Comment 7 Andreas Kloeckner 2008-01-24 21:03:35 UTC
In the original ice.cpp, there is a declaration of cyl_bessel_j of two template arguments. So there are two different issues:

1. gcc ICEs on Richard's reduced code
2. it doesn't find the two-argument version of cyl_bessel_j.
Comment 8 Richard Biener 2008-01-25 09:50:16 UTC
EDG accepts this one where we still ICE the same:

struct default_policy {};
template <class T = default_policy>
struct policy
{
    typedef int precision_type;
};
template <class Real, class Policy> struct precision {
    typedef Real type;
    typedef typename Policy::precision_type precision_type;
};
template <class T1, class T2, class Policy>
struct bessel_traits {
    typedef T1 result_type;
    typedef typename precision<result_type, Policy>::type precision_type;
};

template <class Fn>
void
def(char const* name, Fn fn);

template <class T1, class T2, class Policy>
typename bessel_traits<T1, T2, Policy>::result_type
cyl_bessel_j(T1 v, T2 x, const Policy& pol);

template <class T1, class T2>
typename bessel_traits<T1, T2, policy<> >::result_type
cyl_bessel_j(T1 v, T2 x);

void hedge_expose_polynomial()
{
    def("cyl_bessel_j", cyl_bessel_j<int, double>);
}


3.3 rejects this with
t.ii: In function `void hedge_expose_polynomial()':
t.ii:31: error: no matching function for call to `def(const char[13], <unknown 
   type>)'

4.1 rejects it with
t.ii: In instantiation of 'precision<int, Policy>':
t.ii:14:   instantiated from 'bessel_traits<int, double, Policy>'
t.ii:31:   instantiated from here
t.ii:9: error: no type named 'precision_type' in 'Policy'
t.ii: In function 'void hedge_expose_polynomial()':
t.ii:31: error: no matching function for call to 'def(const char [13], <unresolved overloaded function type>)'

and 4.2 and 4.3 ICE.
Comment 9 Richard Biener 2008-01-25 21:30:27 UTC
It's unclear if this is valid or not and the testcase should be able to be reduced further.
Comment 10 Joseph S. Myers 2008-02-01 16:55:16 UTC
4.2.3 is being released now, changing milestones of open bugs to 4.2.4.
Comment 11 Richard Biener 2008-02-06 20:52:41 UTC
Before we make this anything but P3 I'd like to know whether this is ice-on-valid
or ice-on-invalid (at least the original testcase never built without errors for
me).
Comment 12 Wolfgang Bangerth 2008-02-12 08:17:03 UTC
The following variant of the testcase in comment #8 is definitely
valid but produces an ICE:
---------------------------------
template <class T = int> struct policy {
    typedef int unnecessary;
};

template <class Policy> struct A {
    typedef int type;
    typedef typename Policy::unnecessary unused;
};

template <class T> struct S {
    typedef int type;
    typedef typename A<T>::type unused;
};

template <class, class T> typename S<T>::type         foo();
template <class>                   S<policy<> >::type foo();

template <typename T> int def(T);
const int i = def(foo<int>);
-------------------------------

tmp/g> /home/bangerth/bin/x86/bin/c++ -c x.cc
x.cc: In instantiation of 'A<T>':
x.cc:12:   instantiated from 'S<T>'
x.cc:19:   instantiated from here
x.cc:7: internal compiler error: in dependent_type_p, at cp/pt.c:15553
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

This is a regression introduced in gcc3.4.x.

W.
Comment 13 Richard Biener 2008-02-12 23:13:52 UTC
Ok, so based on comment #12 this is ice-on-valid-code, and that testcase
"works" for me with 4.0 and 4.1 which produce:

g++-4.1 -S t.ii
t.ii: In instantiation of ‘A<T>’:
t.ii:12:   instantiated from ‘S<T>’
t.ii:19:   instantiated from here
t.ii:7: error: no type named ‘unnecessary’ in ‘T’

with 3.4 it ICEs with

g++-3.4 -S t.ii
t.ii: In instantiation of `A<T>':
t.ii:12:   instantiated from `S<T>'
t.ii:19:   instantiated from here
t.ii:7: internal compiler error: in lookup_member, at cp/search.c:1300
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.
For Debian GNU/Linux specific bug reporting instructions,
see <URL:file:///usr/share/doc/gcc-3.4/README.Bugs>.

while 3.3 and 2.95 accept it.

No idea if we have a PR for 4.1 and the rejects-valid.  Janis, can you
hunt at where we started to go from the error with 4.1 to the ICE we now see?
Comment 14 Richard Biener 2008-02-12 23:19:10 UTC
It looks like simply deleting from dependent_type_p:

  /* If there are no template parameters in scope, then there can't be
     any dependent types.  */
  if (!processing_template_decl)
    {
      /* If we are not processing a template, then nobody should be
         providing us with a dependent type.  */
      gcc_assert (type);
      gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM);
      return false;
    }

fixes the testcase - so we are probably not setting processing_template_decl
correctly(?).  Or is it even correct and the check in the context of
the caller make_typename_type is simply bogus?
Comment 15 Mark Mitchell 2008-02-19 06:15:39 UTC
Subject: Re:  [4.2/4.3 Regression] ICE in svn boost math toolkit

rguenth at gcc dot gnu dot org wrote:
> ------- Comment #14 from rguenth at gcc dot gnu dot org  2008-02-12 23:19 -------
> It looks like simply deleting from dependent_type_p:
> 
>   /* If there are no template parameters in scope, then there can't be
>      any dependent types.  */
>   if (!processing_template_decl)
>     {
>       /* If we are not processing a template, then nobody should be
>          providing us with a dependent type.  */
>       gcc_assert (type);
>       gcc_assert (TREE_CODE (type) != TEMPLATE_TYPE_PARM);
>       return false;
>     }
> 
> fixes the testcase - so we are probably not setting processing_template_decl
> correctly(?).  Or is it even correct and the check in the context of
> the caller make_typename_type is simply bogus?

We definitely don't want to delete that from dependent_type_p; it's a 
vital optimization.  I think the usage in make_typename_type is correct; 
when CONTEXT is a dependent type, we have to make a real TYPENAME_TYPE; 
when it's not, we can figure out what's being referenced immediately.

What does the stack trace look like at the point we're crashing?  What 
typename type are trying to simplify?

Comment 16 Richard Biener 2008-02-19 10:28:30 UTC
It's way down

#1  0x00000000004f94ac in dependent_type_p (type=0x2aea625cd180)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:15553
#2  0x000000000043e9fe in make_typename_type (context=0x2aea625cd180, 
    name=0x2aea625c7e40, tag_type=typename_type, complain=9)
    at /space/rguenther/src/svn/trunk/gcc/cp/decl.c:2979
#3  0x00000000004c2671 in tsubst (t=0x2aea625cb180, args=0x2aea625d22a0, 
    complain=tf_warning_or_error, in_decl=0x2aea625cb300)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:9376
#4  0x00000000004bb079 in tsubst_decl (t=0x2aea625cb300, args=0x2aea625d22a0, 
    complain=tf_warning_or_error)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:8396
#5  0x00000000004bd402 in tsubst (t=0x2aea625cb300, args=0x2aea625d22a0, 
    complain=tf_warning_or_error, in_decl=0x0)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:8797
#6  0x00000000004adbdf in instantiate_class_template (type=0x2aea625d3180)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:7011
#7  0x000000000059d34e in complete_type (type=0x2aea625d3180)
    at /space/rguenther/src/svn/trunk/gcc/cp/typeck.c:127
#8  0x00000000005fd6d9 in lookup_member (xbasetype=0x0, name=0x2aea625c7f60, 
    protect=0, want_type=1 '\001')
#9  0x00000000005fda92 in lookup_field (xbasetype=0x2aea625d3180, 
    name=0x2aea625c7f60, protect=0, want_type=1 '\001')
    at /space/rguenther/src/svn/trunk/gcc/cp/search.c:1302
#10 0x000000000043eb4c in make_typename_type (context=0x2aea625d3180, 
    name=0x2aea625c7f60, tag_type=typename_type, complain=9)
    at /space/rguenther/src/svn/trunk/gcc/cp/decl.c:2993
#11 0x00000000004c2671 in tsubst (t=0x2aea625cbcc0, args=0x2aea625ca960, 
    complain=tf_warning_or_error, in_decl=0x2aea625cbe40)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:9376
#12 0x00000000004bb079 in tsubst_decl (t=0x2aea625cbe40, args=0x2aea625ca960, 
    complain=tf_warning_or_error)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:8396
#13 0x00000000004bd402 in tsubst (t=0x2aea625cbe40, args=0x2aea625ca960, 
    complain=tf_warning_or_error, in_decl=0x0)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:8797
#14 0x00000000004adbdf in instantiate_class_template (type=0x2aea625cd300)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:7011
#15 0x000000000059d34e in complete_type (type=0x2aea625cd300)
    at /space/rguenther/src/svn/trunk/gcc/cp/typeck.c:127
#16 0x00000000005fd6d9 in lookup_member (xbasetype=0x0, name=0x2aea625c7f60, 
    protect=0, want_type=1 '\001')
    at /space/rguenther/src/svn/trunk/gcc/cp/search.c:1221
#17 0x00000000005fda92 in lookup_field (xbasetype=0x2aea625cd300, 
    name=0x2aea625c7f60, protect=0, want_type=1 '\001')
    at /space/rguenther/src/svn/trunk/gcc/cp/search.c:1302
#18 0x000000000043eb4c in make_typename_type (context=0x2aea625cd300, 
    name=0x2aea625c7f60, tag_type=typename_type, complain=tf_keep_type_decl)
    at /space/rguenther/src/svn/trunk/gcc/cp/decl.c:2993
#19 0x00000000004c2671 in tsubst (t=0x2aea625cd480, args=0x2aea625ce540, 
    complain=tf_none, in_decl=0x0)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:9376
#20 0x00000000004bc688 in tsubst_function_type (t=0x2aea625cd600, 
    args=0x2aea625ce540, complain=tf_none, in_decl=0x0)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:8634
#21 0x00000000004c1884 in tsubst (t=0x2aea625cd600, args=0x2aea625ce540, 
    complain=tf_none, in_decl=0x0)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:9259
#22 0x00000000004ed155 in get_bindings (fn=0x2aea625cd6c0, 
    decl=0x2aea625bf820, explicit_args=0x2aea625cfcf0, check_rettype=0 '\0')
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:13830
#23 0x00000000004de19e in resolve_overloaded_unification (
    tparms=0x2aea625cfb70, targs=0x2aea625cfdb0, parm=0x2aea625d1780, 
    arg=0x2aea625caa20, strict=DEDUCE_CALL, sub_strict=21)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:12140
#24 0x00000000004dc9de in type_unification_real (tparms=0x2aea625cfb70, 
    targs=0x2aea625cfdb0, xparms=0x2aea625cfbd0, xargs=0x2aea625cfd20, subr=0, 
    strict=DEDUCE_CALL, flags=3)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:11951
#25 0x00000000004dba28 in fn_type_unification (fn=0x2aea625d1a80, 
    explicit_targs=0x0, targs=0x2aea625cfdb0, args=0x2aea625cfd20, 
    return_type=0x0, strict=DEDUCE_CALL, flags=3)
    at /space/rguenther/src/svn/trunk/gcc/cp/pt.c:11687
#26 0x000000000041087c in add_template_candidate_real (
    candidates=0x7fff48f101f8, tmpl=0x2aea625d1a80, ctype=0x0, 
    explicit_targs=0x0, arglist=0x2aea625cfd20, return_type=0x0, 
    access_path=0x0, conversion_path=0x0, flags=3, obj=0x0, strict=DEDUCE_CALL)
    at /space/rguenther/src/svn/trunk/gcc/cp/call.c:2260
#27 0x0000000000410de8 in add_template_candidate (candidates=0x7fff48f101f8, 
    tmpl=0x2aea625d1a80, ctype=0x0, explicit_targs=0x0, 
    arglist=0x2aea625cfd20, return_type=0x0, access_path=0x0, 
    conversion_path=0x0, flags=3, strict=DEDUCE_CALL)
    at /space/rguenther/src/svn/trunk/gcc/cp/call.c:2341
#28 0x000000000041796c in add_candidates (fns=0x2aea625cfd80, 
    args=0x2aea625cfd20, explicit_targs=0x0, template_only=0 '\0', 
    conversion_path=0x0, access_path=0x0, flags=3, candidates=0x7fff48f101f8)
    at /space/rguenther/src/svn/trunk/gcc/cp/call.c:3684
#29 0x00000000004130c3 in perform_overload_resolution (fn=0x2aea625cfd80, 
    args=0x2aea625cfd20, candidates=0x7fff48f101f8, 
    any_viable_p=0x7fff48f101f7 "\001")
    at /space/rguenther/src/svn/trunk/gcc/cp/call.c:2820
#30 0x00000000004132bb in build_new_function_call (fn=0x2aea625cfd80, 
    args=0x2aea625cfd20, koenig_p=1 '\001')
    at /space/rguenther/src/svn/trunk/gcc/cp/call.c:2868
#31 0x000000000060fa88 in finish_call_expr (fn=0x2aea625cfd80, 
    args=0x2aea625cfd20, disallow_virtual=0 '\0', koenig_p=1 '\001')
    at /space/rguenther/src/svn/trunk/gcc/cp/semantics.c:1946

processing the call to def in

const int i = def(foo<int>);

I don't know why we have an overload for def here at all.
Comment 17 Jakub Jelinek 2008-02-19 17:50:46 UTC
instantiate_type_decl calls tsubst on
 <type_decl 0x2aaaaea83300 unused
    type <typename_type 0x2aaaaea83180 unnecessary VOID
        align 8 symtab 0 alias set -1 structural equality context <template_type_parm 0x2aaaaea78a80 Policy>
        chain <type_decl 0x2aaaaea83240 unnecessary>>
    nonlocal VOID file pr34950.C line 7 col 42
    align 1 context <record_type 0x2aaaaea78c00 A>
and as TYPE_DECL isn't TEMPLATE_DECL, it doesn't bump processing_template_decl
around the tsubst call.
Comment 18 Jason Merrill 2008-02-19 21:21:10 UTC
The problem comes when we deal with templates from non-template code.  In this case, we are substituting some parameters but not all into a function template declaration, so we end up building up new typename types with dependent scopes.

Changing make_typename_type to call uses_template_parms fixes the testcase, but it seems that other similar issues may be hiding, and it may be better to bump processing_template_decl at a higher level, perhaps resolve_overloaded_unification.  But that may also leave other similar problems elsewhere.
Comment 19 Jason Merrill 2008-02-19 21:39:40 UTC
(In reply to comment #18)
> it may be better to bump processing_template_decl at a higher level, perhaps
> resolve_overloaded_unification.

This seems to be the approach taken in the partial ordering code, so it seems like the right answer.
Comment 20 Jason Merrill 2008-02-19 21:45:59 UTC
Incidentally, the error that 3.3 gave for the testcase in comment #8 seems to be correct: after we substitute the explicit args into the two function templates, we are left with one which still has an unbound argument, which I believe makes it an undeduced context under [temp.deduct.type] paragraph 5 ("the set of functions provided as an argument contains one or more function templates").  The EDG compiler seems to disagree, so this should probably become a core language issue.
Comment 21 Jason Merrill 2008-02-19 22:13:56 UTC
On second thought, the testcase seems to be well-formed; we should do partial ordering and  determine that the second template is more specialized than the first.
Comment 22 Jason Merrill 2008-02-19 22:53:51 UTC
Subject: Bug 34950

Author: jason
Date: Tue Feb 19 22:53:07 2008
New Revision: 132455

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132455
Log:
        PR c++/34950
        * pt.c (resolve_overloaded_unification): Set processing_template_decl
        while we look for possible bindings.

Added:
    trunk/gcc/testsuite/g++.dg/template/explicit-args1.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c

Comment 23 Jason Merrill 2008-02-19 22:54:08 UTC
Subject: Bug 34950

Author: jason
Date: Tue Feb 19 22:53:25 2008
New Revision: 132456

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132456
Log:
        PR c++/34950
        * pt.c (resolve_overloaded_unification): Set processing_template_decl
        while we look for possible bindings.

Modified:
    branches/gcc-4_3-branch/gcc/cp/ChangeLog
    branches/gcc-4_3-branch/gcc/cp/pt.c

Comment 24 Jason Merrill 2008-02-20 04:48:06 UTC
Fixed in all open branches.
Comment 25 Jason Merrill 2008-02-20 04:48:17 UTC
Subject: Bug 34950

Author: jason
Date: Wed Feb 20 04:47:28 2008
New Revision: 132469

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132469
Log:
        PR c++/34950
        * pt.c (resolve_overloaded_unification): Set processing_template_decl
        while we look for possible bindings.

        PR c++/34774
        * pt.c (value_dependent_expression_p): Look into DECL_INITIAL
        of enumerators, too.

Modified:
    branches/gcc-4_1-branch/gcc/cp/ChangeLog
    branches/gcc-4_1-branch/gcc/cp/pt.c

Comment 26 Jason Merrill 2008-02-20 04:48:33 UTC
Subject: Bug 34950

Author: jason
Date: Wed Feb 20 04:47:47 2008
New Revision: 132470

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132470
Log:
        PR c++/34950
        * pt.c (resolve_overloaded_unification): Set processing_template_decl
        while we look for possible bindings.

Modified:
    branches/gcc-4_2-branch/gcc/cp/ChangeLog
    branches/gcc-4_2-branch/gcc/cp/pt.c