On 10.09.2013 03:19, Adam Butcher wrote:
- Instantiation of generic conversion op ICEs if the call op
contains
declarations and hasn't already been instantiated.
This is not a complete enough description. It only ICEs instantiating
the call op through the decltype return of the conversion op if the
return type of the call op is a deduced one (i.e. unspecified or
specified explicitly as 'auto'). If the lambda call op is instantiated
explicitly (i.e. the lambda is called) prior to using the conversion op
then all is well. It seems to only occur if there are variables
declared within the lambda body or accessible via the lambda's 'this'.
Specifically, the ICE is in tsubst_decl (cp/pt.c:10839) asserting
'gcc_unreachable' due to being 'cp_unevaluated_operand'. The
instantiation chain starts from attempting to 'mark_used' the call op in
the decltype expression.
The same ICE can be caused in user code by attempting to take get
decltype of a generic lambda call having a deduced return type and
declarations:
This is fine:
auto f = [] <typename T> (T) {};
decltype (f (4.f)) *p;
This is not; it ICEs doing 'tsubst_decl' on the declaration 'x'.
auto f = [] <typename T> (T) { int x; };
decltype (f (4.f)) *p;
The conversion op is clearly not a factor here but can be removed from
the equation completely by adding a capture. The ICE still occurs. In
this case it occurs trying to do 'tsubst_decl' on the capture decl 'i'.
int i = 0;
auto f = [i] <typename T> (T) {};
decltype (f (4.f)) *p;
ice.cpp: In instantiation of ‘main()::<lambda(T)> [with T = float]’:
ice.cpp:5:20: required from here
ice.cpp:4:34: internal compiler error: in tsubst_decl, at cp/pt.c:10839
auto f = [i] <typename T> (T) {};
^
Any ideas? Looks like it's something to do with how the call operator
is defined. Is there some flag I'm missing in the generic case?
Cheers,
Adam