Bug 34774 - [4.1/4.2 Regression] templates, enumerations, overflow, ice
Summary: [4.1/4.2 Regression] templates, enumerations, overflow, ice
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.0
: P2 normal
Target Milestone: 4.1.3
Assignee: Jason Merrill
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks: 31714
  Show dependency treegraph
 
Reported: 2008-01-13 18:49 UTC by tbp
Modified: 2008-02-14 07:52 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.6 4.3.0
Known to fail: 3.4.6 4.1.3
Last reconfirmed: 2008-02-13 06:08:21


Attachments
preprocessed offender (10.30 KB, application/octet-stream)
2008-01-13 18:50 UTC, tbp
Details
unincluded testcase (3.62 KB, text/plain)
2008-01-13 19:29 UTC, Richard Biener
Details

Note You need to log in before you can comment on or make changes to this bug.
Description tbp 2008-01-13 18:49:14 UTC
While trying to pinpoint an *intermitent* warning/error with g++ 4.3 "mf/unit.h:84: error: no integral type can represent all of the enumerator values for `metafloat::core::helpers::details::aligner<7u, metafloat::core::float_t<0l, 0l, 0ul,  CAT_NRM> >::<anonymous enum>'" i finally got it to ice with the attached version. Even better, the venerable g++ 3.4 as shipped by Cygwin also craps out.


$ g++ tf.ii -o tf
In file included from metafloat.h:13,
                 from tf.cc:14:
mf/significand.h:37: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://cygwin.com/problems.html> for instructions.
$ /usr/local/gcc-4.3-20080104/bin/g++ tf.ii -o tf
In file included from metafloat.h:14,
                 from tf.cc:15:
mf/significand.h:35: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
$ g++ -v
Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libe
xecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --
enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-thre
ads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
Thread model: posix
gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
$ /usr/local/gcc-4.3-20080104/bin/g++ -v
Using built-in specs.
Target: i686-pc-cygwin
Configured with: ../configure --prefix=/usr/local/gcc-4.3-20080104 --enable-languages=c,c++ --enable-threads=posix --disable-checking --disable-libmudflap --dis
able-nls --disable-shared --disable-win32-registry --disable-multilib --enable-sjlj-exceptions --with-system-zlib --with-gnu-ld --with-gnu-as --verbose --enable
-checking=none --disable-bootstrap
Thread model: posix
gcc version 4.3.0 20080104 (experimental) (GCC)
Comment 1 tbp 2008-01-13 18:50:13 UTC
Created attachment 14936 [details]
preprocessed offender
Comment 2 Richard Biener 2008-01-13 19:17:46 UTC
This is the same issue as PR31714 (which occurs only on the 4.1 branch).

#0  0x084c1ddd in operand_equal_p (arg0=0xb7d275b0, arg1=0xb7d275cc, flags=0)
    at /home/richard/src/trunk/gcc/fold-const.c:3015
#1  0x084c4664 in operand_equal_p (arg0=0xb7d23be0, arg1=0xb7d23c20, flags=0)
    at /home/richard/src/trunk/gcc/fold-const.c:3157
#2  0x084c48d0 in operand_equal_p (arg0=0xb7d2806c, arg1=0xb7d28090, flags=0)
    at /home/richard/src/trunk/gcc/fold-const.c:3162
#3  0x0853fcb1 in fold_ternary (code=COND_EXPR, type=0xb7c84548, 
    op0=0xb7d25550, op1=0xb7d2806c, op2=0xb7d28090)
    at /home/richard/src/trunk/gcc/fold-const.c:13018
#4  0x08543a00 in fold_build3_stat (code=COND_EXPR, type=0xb7c84548, 
    op0=0xb7d25550, op1=0xb7d2806c, op2=0xb7d28090)
    at /home/richard/src/trunk/gcc/fold-const.c:13717
#5  0x084e1cc7 in fold_binary_op_with_conditional_arg (code=GT_EXPR, 
    type=0xb7c84548, op0=0xb7c7f280, op1=0xb7d2747c, cond=0xb7c7f280, 
    arg=0xb7d2747c, cond_first_p=1)
    at /home/richard/src/trunk/gcc/fold-const.c:6398
#6  0x08506c18 in fold_binary (code=GT_EXPR, type=0xb7c84548, op0=0xb7c7f280, 
    op1=0xb7d2747c) at /home/richard/src/trunk/gcc/fold-const.c:9532
#7  0x08543530 in fold (expr=0xb7d28048)
    at /home/richard/src/trunk/gcc/fold-const.c:13331
#8  0x0826d088 in fold_if_not_in_template (expr=0xb7d28048)
    at /home/richard/src/trunk/gcc/cp/tree.c:2728
#9  0x081f7043 in build_binary_op (code=GT_EXPR, orig_op0=0xb7c7f280,

(gdb) call debug_tree (arg0)
 <tree_list 0xb7d275b0
    value <negate_expr 0xb7d23c00
        type <integer_type 0xb7c842d8 int public type_6 SI
            size <integer_cst 0xb7c73620 constant invariant 32>
            unit size <integer_cst 0xb7c7340c constant invariant 4>
            align 32 symtab 0 alias set -1 canonical type 0xb7c842d8 precision 32 min <integer_cst 0xb7c735cc -2147483648> max <integer_cst 0xb7c735e8 2147483647>
            pointer_to_this <pointer_type 0xb7c8d8f0>>
       
        arg 0 <template_parm_index 0xb7c78e34 type <integer_type 0xb7c842d8 int>
            readonly constant invariant
           index 0 level 1 orig_level 1>>>

we leak template args to middle-end fold.

3.3 emits an error:

mf/unit.h: In instantiation of `metafloat::core::helpers::details::aligner<7, metafloat::core::float_t<0, 0, 0, CAT_NRM> >':
mf/unit.h:108:   instantiated from `metafloat::core::helpers::details::normalizer<7, metafloat::core::helpers::details::aligner<7, metafloat::core::float_t<0, 0, 0, CAT_NRM> > >'
metafloat.h:135:   instantiated from `metafloat::core::helpers::normalizer<7, metafloat::core::float_t<0, 0, 0, CAT_NRM>, true>'
metafloat.h:135:   instantiated from `metafloat::core::ops::add<F0, F1>'
tf.cc:59:   instantiated from here
mf/unit.h:84: error: no integral type can represent all of the enumerator 
   values for `metafloat::core::helpers::details::aligner<7, 
   metafloat::core::float_t<0, 0, 0, CAT_NRM> >::<anonymous enum>'

reducing.
Comment 3 Richard Biener 2008-01-13 19:24:37 UTC
Reduced testcase that is accepted by 3.3 and 3.4 w/o diagnostic but ICEs
starting with 4.0.

typedef unsigned int op_type_u_t;
typedef op_type_u_t op_type_t;
template<int shifts, op_type_u_t sig>
struct shift {
  enum {
    num_bits = op_type_u_t(sizeof(op_type_t) * 8),
    max_shift = num_bits - 1u,
    is_left = shifts < 0 ? true : false,
    n0 = is_left ? op_type_u_t(-shifts) : op_type_u_t(shifts),
    n = n0 > max_shift ? max_shift : n0,
    n_comp = max_shift - n
  } x;
};
Comment 4 Richard Biener 2008-01-13 19:29:42 UTC
Created attachment 14938 [details]
unincluded testcase
Comment 5 tbp 2008-01-13 19:47:07 UTC
Thanks a lot for your investigations.
May i ask if the apparent 'quenching' of sign mismatch - and related - warnings (that is if you pile enough templates, due warning are never emitted), is in any way related to this bug?
Comment 6 rguenther@suse.de 2008-01-13 21:06:07 UTC
Subject: Re:  [4.1/4.2/4.3 Regression] templates, enumerations,
 overflow, ice

On Sun, 13 Jan 2008, tbptbp at gmail dot com wrote:

> ------- Comment #5 from tbptbp at gmail dot com  2008-01-13 19:47 -------
> Thanks a lot for your investigations.
> May i ask if the apparent 'quenching' of sign mismatch - and related - warnings
> (that is if you pile enough templates, due warning are never emitted), is in
> any way related to this bug?

No idea, but I doubt so ;)

Richard.
Comment 7 tbp 2008-01-13 21:20:07 UTC
Subject: Re:  [4.1/4.2/4.3 Regression] templates, enumerations, overflow, ice

On 13 Jan 2008 21:06:07 -0000, rguenther at suse dot de
<gcc-bugzilla@gcc.gnu.org> wrote:
> No idea, but I doubt so ;)
Fantastic.
Now i also see the ldexp sometimes not being folded. I know what i'm
doing is kinda evil, but why so much hatred. Snif.
Comment 8 Manuel López-Ibáñez 2008-01-14 01:01:39 UTC
This is confirmed, isn't it?
Comment 9 Richard Biener 2008-01-14 12:35:51 UTC
The testcase in comment #3 looks valid(?), at least EDG accepts it.  The
problem is we try to fold_non_dependent_expr

   n = n0 > max_shift ? max_shift : n0,

but substituting n0 makes this expression dependent and we leak template
param lists to fold.
Comment 10 Richard Biener 2008-01-14 12:45:53 UTC
Reduced testcase:

template<int shifts>
struct shift {
  enum {
    n0 = (unsigned)shifts,
    n = n0 ? 0 : n0,
    n_comp = -n
  } x;
};

it looks like we substitute n into -n but do not stop substituting once
we hit a dependent expression (n0).
Comment 11 Richard Biener 2008-01-14 12:46:11 UTC
Paolo, can you have a look here? ;)
Comment 12 tbp 2008-01-14 12:47:26 UTC
Subject: Re:  [4.1/4.2/4.3 Regression] templates, enumerations, overflow, ice

On 14 Jan 2008 12:35:51 -0000, rguenth at gcc dot gnu dot org
<gcc-bugzilla@gcc.gnu.org> wrote:
> The testcase in comment #3 looks valid(?), at least EDG accepts it.  The
> problem is we try to fold_non_dependent_expr
>
>    n = n0 > max_shift ? max_shift : n0,
>
> but substituting n0 makes this expression dependent and we leak template
> param lists to fold.
I'm no language lawyer, but the whole exercise is supposed to be
valid. It has been mutilated for msvc2k5, and it works there. It also
works with g++ when it doesn't fault (that is when i use an
alternative implementation). Icc 10.1 doesn't complain either before
crashing ;)
So, to me, with my rosy teinted glasses strapped on, it has never been
an ice-on-invalid.
Comment 13 Paolo Carlini 2008-01-14 13:29:05 UTC
I will, but I don't make promises...
Comment 14 tbp 2008-01-15 20:07:02 UTC
I keep bumping into this issue and i'd really appreciate a clue about how to workaround for the time being.
Comment 15 rguenther@suse.de 2008-01-16 09:23:43 UTC
Subject: Re:  [4.1/4.2/4.3 Regression] templates, enumerations,
 overflow, ice

On Tue, 15 Jan 2008, tbptbp at gmail dot com wrote:

> ------- Comment #14 from tbptbp at gmail dot com  2008-01-15 20:07 -------
> I keep bumping into this issue and i'd really appreciate a clue about how to
> workaround for the time being.

As of the analysis, try to avoid non-dependent enum members that
double- (or more) -indirectly depends on a dependent enum member.
For example by propagating the value manually.

Like instead of

template <int i>
struct foo {
  enum { a = i, b = a+1, c = b+2 }

do

  enum { a = i, b = i+1, c = i+3 }

Richard.
Comment 16 tbp 2008-01-16 13:04:43 UTC
Much helpful, many thanks.
Comment 17 Jason Merrill 2008-02-13 07:08:59 UTC
Subject: Bug 34774

Author: jason
Date: Wed Feb 13 07:08:11 2008
New Revision: 132283

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132283
Log:
        PR c++/34774
        * pt.c (value_dependent_expression_p): Look into DECL_INITIAL
        of enumerators, too.

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

Comment 18 tbp 2008-02-13 17:21:54 UTC
Ah ah!
[svn pull... build...]
Sadly it makes no difference yet, most certainly because of all the kludges i had to stuff in: out of the 2213 tests (from the ucb-corpus for +,-,*,/,sqrt) there's still 3 of them (all additions) that g++ refuses to 'fold' completly
mov    0x200627(%rip),%edx        # 600c88 <metafloat::float_t<2097152u, 131, 0u, (metafloat::category_t)0>::fp32>
mov    0x200626(%rip),%esi        # 600c90 <metafloat::float_t<8353000u, 147, 0u, (metafloat::category_t)0>::fp32>
mov    0x200616(%rip),%edx        # 600c8c <metafloat::float_t<11400u, 147, 0u, (metafloat::category_t)0>::fp32>
So close to perfection...
And then the compile-time 'raytracer' is still fubar :)
Compilation is definitely faster, but i only have a debian 4.3 snapshot to compare against and i suppose some checkings are enabled.

I guess i'll have to get back to it, remove all those ugly workarounds and see if it can handle it now.

Many thanks for your efforts.

PS:
  http://ompf.org/stuff/metafloat/
  http://ompf.org/stuff/metafloat/dist/ <-- tarball here
Comment 19 Jason Merrill 2008-02-13 18:44:21 UTC
Subject: Bug 34774

Author: jason
Date: Wed Feb 13 18:43:34 2008
New Revision: 132292

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132292
Log:
        PR c++/34774
        * pt.c (value_dependent_expression_p): Look into DECL_INITIAL
        of enumerators, too.

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

Comment 20 Jason Merrill 2008-02-13 19:30:05 UTC
Please submit a separate bug report for the folding issue, with a reduced testcase if possible.

Incidentally, the "no integral type can represent" issue is due to one of the enumerators being -31, and one being (unsigned long long)-31, which is a very large positive number.
Comment 21 tbp 2008-02-14 07:52:38 UTC
I've already submitted PR34864 for the folding but apparently i've overdone the reduction; it's actually slightly tricky to trigger the issue (i mean i've obviously hit another problem in that PR).

Right now i'm out of inspiration as to how to can convey my point :) 
Comment 22 Jason Merrill 2008-02-20 04:48:17 UTC
Subject: Bug 34774

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