On 20.09.2013 18:47, Jason Merrill wrote:
Why is canonical_type_parameter not doing the right thing here? I
don't see a reason we should need to treat these differently from
normal template parms.
The issue only happens with indirect parms. The type 'auto' is given a
canonical type in make_auto_1. When the parm type is plain unqualified
'auto', the implicit template code replaces it with the generated type
and all's well. When the parm is 'auto&' the implicit template code
only replaces the template_type_parm 'auto' with the generated type, the
wrapping reference_type is left with the canonical type of 'auto&'.
Example of two parm types in the same list (chain field removed):
<reference_type 0x7f27b2ff32a0
type <template_type_parm 0x7f27b2ff31f8 auto VOID
align 8 symtab 0 alias set -1
canonical type 0x7f27b2fe0f18
index 0 level 1 orig_level 1
reference_to_this <reference_type 0x7f27b2ff32a0>>
unsigned DI
size <...> unit size <...>
align 64 symtab 0 alias set -1
canonical type 0x7f27b2ff3150>
<reference_type 0x7f27b2ff33f0
type <template_type_parm 0x7f27b2ff3348 auto VOID
align 8 symtab 0 alias set -1
canonical type 0x7f27b2fe0f18
index 0 level 1 orig_level 1
reference_to_this <reference_type 0x7f27b2ff33f0>>
unsigned DI
size <...> unit size <...>
align 64 symtab 0 alias set -1
canonical type 0x7f27b2ff3150>
After replacement:
<reference_type 0x7f27b2ff32a0
type <template_type_parm 0x7f27b2ff3540 <auto2> VOID
align 8 symtab 0 alias set -1
canonical type 0x7f27b2ff3540
index 1 level 1 orig_level 1>>
unsigned DI
size <...> unit size <...>
align 64 symtab 0 alias set -1
canonical type 0x7f27b2ff3150>
<reference_type 0x7f27b2ff33f0
type <template_type_parm 0x7f27b2ff35e8 <auto3> VOID
align 8 symtab 0 alias set -1
canonical type 0x7f27b2ff35e8
index 2 level 1 orig_level 1>>
unsigned DI
size <...> unit size <...>
align 64 symtab 0 alias set -1
canonical type 0x7f27b2ff3150>
Looks like I'll need to expose canonical_type_parameter and push it
through from the top of the parameter rather than just replace the
template_type_parm. Or leave this as is and arrange for this scenario
to never occur.
I guess this wouldn't happen if we were replacing on the fly. Maybe
make_auto_1 could differ in behavior when in a parameter list (would not
setting a canonical type get us anywhere?) or just call a different
function?
I'll have a further look when I get some more time.
Cheers,
Adam