Bug 58080 - internal compiler error, decltype in function declaration (for SFINAE purposes)
Summary: internal compiler error, decltype in function declaration (for SFINAE purposes)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.3
: P3 normal
Target Milestone: 4.9.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-04 18:46 UTC by Nickolay Merkin
Modified: 2013-08-06 01:09 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-08-04 00:00:00


Attachments
preprocessed source code that leads to the ICE (317 bytes, text/x-csrc)
2013-08-04 18:46 UTC, Nickolay Merkin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nickolay Merkin 2013-08-04 18:46:05 UTC
Created attachment 30609 [details]
preprocessed source code that leads to the ICE

Here is minimal example that reproduces the ICE:

g++ version 4.7.3 (Ubuntu/Linaro 4.7.3-2ubuntu1~12.04)
commandline: g++ std=c++11 x.cpp
(also crashes with std=gnu++11)

// /usr/lib/gcc/i686-linux-gnu/4.7/cc1plus -quiet -imultilib . -imultiarch i386-linux-gnu -D_GNU_SOURCE x.cpp -quiet -dumpbase x.cpp -mtune=generic -march=i686 -auxbase x -std=c++11 -fstack-protector -o - -frandom-seed=0
# 1 "x.cpp"
# 1 "<command-line>"
# 1 "x.cpp"
template<class A, class B>
struct Eval
{
 void foo(A a, B b) { bar(a,b, 0); }
 auto bar(A a, B b, decltype(a+b)* _) -> decltype(a+b) { return a+b; }
};

int main()
{
 Eval<int,void*> eiv; eiv.foo(0,0);
}

I intended to write a multimethod that does a+b for integral, pointer, string, etc. types, -- and immediately met ICE.
Of course, operator+(void*,int) is not defined, but it is not a reason to crash.
The compiler prepends the crash report with three warnings about VOID* in arithmetic expression.
Comment 1 Paolo Carlini 2013-08-04 18:56:43 UTC
Note that strictly speaking arithmetic on a pointer to void would be even invalid.
Comment 2 Nickolay Merkin 2013-08-04 18:58:22 UTC
(In reply to Paolo Carlini from comment #1)
> Note that strictly speaking arithmetic on a pointer to void would be even
> invalid.

Yes of course, and the compiler has notified that... and then it crashed.
Comment 3 Paolo Carlini 2013-08-04 19:07:45 UTC
I meant something else: I meant that on a different compiler, your code could be hardly rejected, you should not use arithmetic on void * in the first place.
Comment 4 Nickolay Merkin 2013-08-04 19:26:43 UTC
(In reply to Paolo Carlini from comment #3)
> I meant something else: I meant that on a different compiler, your code
> could be hardly rejected, you should not use arithmetic on void * in the
> first place.

I understand that.
My multimethod is intended to take 'good' combinations from 'bad', so that
int+int or int+char* are good,
char*+char* is bad,
and int+void* should be bad, too.

Say,

template<class A, class B>
auto plus_impl(A a, B b) -> decltype(a+b) { return a+b; }
int plus_impl(...) { throw bad_operands(); }

template<class A, class B>
variant_type plus(A a, B b)
{ return variant_type(plus_impl(a,b)); }

To bypass the ICE, I'd like just to add overloads of plus_impl those receive void* as left or right operand and throw the exception as well.
But this is a bypass.

Tomorrow I'll explore how VC2010 behaves, maybe it is common problem, and the bypass is strongly required.
Comment 5 Paolo Carlini 2013-08-04 19:31:23 UTC
Current clang++, for example, simply errors out, no warning.
Comment 6 Evgeny Panasyuk 2013-08-04 20:56:30 UTC
Several variations of original code shows differences in results of GCC 4.8.1 and Clang (3.4 trunk 184460):

Case 1: Both compile OK, but different overloads are selected
GCC: http://coliru.stacked-crooked.com/view?id=58ca6a0268281fda26a36db4e5d50bbd-3ea7fded292aff0f460de2fb646b584a
Clang: http://coliru.stacked-crooked.com/view?id=58ca6a0268281fda26a36db4e5d50bbd-80c199070668c72f0a5e12e38239d72b

Case 2: Clang compiles OK, without errors, while GCC shows "Internal compiler error"
GCC: http://coliru.stacked-crooked.com/view?id=7defec6f0288a8d72255a652e1baf439-3ea7fded292aff0f460de2fb646b584a
Clang: http://coliru.stacked-crooked.com/view?id=7defec6f0288a8d72255a652e1baf439-80c199070668c72f0a5e12e38239d72b
Comment 7 Paolo Carlini 2013-08-04 21:00:35 UTC
The ICE is of course wrong, I already sent a patch for it. If there are other issues, let's handle one at a time, in different bugs, after having checked that mainline GCC is still affected and that there are no dups in Bugzilla. Thanks.
Comment 8 Paolo Carlini 2013-08-04 21:05:11 UTC
By the way, with my patch installed, all the new testcases seem fine, consistent with clang.
Comment 9 Paolo Carlini 2013-08-05 22:05:05 UTC
Fixed for 4.9.0.
Comment 10 Nickolay Merkin 2013-08-05 22:11:59 UTC
(In reply to Paolo Carlini from comment #9)
> Fixed for 4.9.0.
Thank you!

Will it be fixed for 4.7.3, or this version is frozen?
Comment 11 Paolo Carlini 2013-08-05 22:18:59 UTC
The issue isn't about entire branches frozen, the issue is that this is an ICE after sensible diagnostics, which moreover isn't a regression. If you feel strongly about backports to 4.7.x and 4.8.x, just send a message to the release managers.
Comment 12 niXman 2013-08-05 22:19:26 UTC
(In reply to Paolo Carlini from comment #9)
> Fixed for 4.9.0.

Can you provide a commit number, please?
Comment 13 Paolo Carlini 2013-08-05 22:58:41 UTC
If you need help, luckily today Jason provided a nice HOWTO here (the only difference is that you want trunk, not 4_8-branch): http://gcc.gnu.org/ml/gcc-bugs/2013-08/msg00320.html
Comment 14 niXman 2013-08-06 01:09:33 UTC
(In reply to Paolo Carlini from comment #13)

http://gcc.gnu.org/viewcvs/gcc?view=revision&sortby=date&revision=201512

thank you