aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.cc
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2022-01-14 16:56:44 +0100
committerMartin Liska <mliska@suse.cz>2022-01-17 22:12:04 +0100
commit5c69acb32329d49e58c26fa41ae74229a52b9106 (patch)
treeddb05f9d73afb6f998457d2ac4b720e3b3b60483 /gcc/cp/call.cc
parent490e23032baaece71f2ec09fa1805064b150fbc2 (diff)
downloadgcc-5c69acb32329d49e58c26fa41ae74229a52b9106.zip
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.gz
gcc-5c69acb32329d49e58c26fa41ae74229a52b9106.tar.bz2
Rename .c files to .cc files.
gcc/ada/ChangeLog: * adadecode.c: Moved to... * adadecode.cc: ...here. * affinity.c: Moved to... * affinity.cc: ...here. * argv-lynxos178-raven-cert.c: Moved to... * argv-lynxos178-raven-cert.cc: ...here. * argv.c: Moved to... * argv.cc: ...here. * aux-io.c: Moved to... * aux-io.cc: ...here. * cio.c: Moved to... * cio.cc: ...here. * cstreams.c: Moved to... * cstreams.cc: ...here. * env.c: Moved to... * env.cc: ...here. * exit.c: Moved to... * exit.cc: ...here. * expect.c: Moved to... * expect.cc: ...here. * final.c: Moved to... * final.cc: ...here. * gcc-interface/cuintp.c: Moved to... * gcc-interface/cuintp.cc: ...here. * gcc-interface/decl.c: Moved to... * gcc-interface/decl.cc: ...here. * gcc-interface/misc.c: Moved to... * gcc-interface/misc.cc: ...here. * gcc-interface/targtyps.c: Moved to... * gcc-interface/targtyps.cc: ...here. * gcc-interface/trans.c: Moved to... * gcc-interface/trans.cc: ...here. * gcc-interface/utils.c: Moved to... * gcc-interface/utils.cc: ...here. * gcc-interface/utils2.c: Moved to... * gcc-interface/utils2.cc: ...here. * init.c: Moved to... * init.cc: ...here. * initialize.c: Moved to... * initialize.cc: ...here. * libgnarl/thread.c: Moved to... * libgnarl/thread.cc: ...here. * link.c: Moved to... * link.cc: ...here. * locales.c: Moved to... * locales.cc: ...here. * mkdir.c: Moved to... * mkdir.cc: ...here. * raise.c: Moved to... * raise.cc: ...here. * rtfinal.c: Moved to... * rtfinal.cc: ...here. * rtinit.c: Moved to... * rtinit.cc: ...here. * seh_init.c: Moved to... * seh_init.cc: ...here. * sigtramp-armdroid.c: Moved to... * sigtramp-armdroid.cc: ...here. * sigtramp-ios.c: Moved to... * sigtramp-ios.cc: ...here. * sigtramp-qnx.c: Moved to... * sigtramp-qnx.cc: ...here. * sigtramp-vxworks.c: Moved to... * sigtramp-vxworks.cc: ...here. * socket.c: Moved to... * socket.cc: ...here. * tracebak.c: Moved to... * tracebak.cc: ...here. * version.c: Moved to... * version.cc: ...here. * vx_stack_info.c: Moved to... * vx_stack_info.cc: ...here. gcc/ChangeLog: * adjust-alignment.c: Moved to... * adjust-alignment.cc: ...here. * alias.c: Moved to... * alias.cc: ...here. * alloc-pool.c: Moved to... * alloc-pool.cc: ...here. * asan.c: Moved to... * asan.cc: ...here. * attribs.c: Moved to... * attribs.cc: ...here. * auto-inc-dec.c: Moved to... * auto-inc-dec.cc: ...here. * auto-profile.c: Moved to... * auto-profile.cc: ...here. * bb-reorder.c: Moved to... * bb-reorder.cc: ...here. * bitmap.c: Moved to... * bitmap.cc: ...here. * btfout.c: Moved to... * btfout.cc: ...here. * builtins.c: Moved to... * builtins.cc: ...here. * caller-save.c: Moved to... * caller-save.cc: ...here. * calls.c: Moved to... * calls.cc: ...here. * ccmp.c: Moved to... * ccmp.cc: ...here. * cfg.c: Moved to... * cfg.cc: ...here. * cfganal.c: Moved to... * cfganal.cc: ...here. * cfgbuild.c: Moved to... * cfgbuild.cc: ...here. * cfgcleanup.c: Moved to... * cfgcleanup.cc: ...here. * cfgexpand.c: Moved to... * cfgexpand.cc: ...here. * cfghooks.c: Moved to... * cfghooks.cc: ...here. * cfgloop.c: Moved to... * cfgloop.cc: ...here. * cfgloopanal.c: Moved to... * cfgloopanal.cc: ...here. * cfgloopmanip.c: Moved to... * cfgloopmanip.cc: ...here. * cfgrtl.c: Moved to... * cfgrtl.cc: ...here. * cgraph.c: Moved to... * cgraph.cc: ...here. * cgraphbuild.c: Moved to... * cgraphbuild.cc: ...here. * cgraphclones.c: Moved to... * cgraphclones.cc: ...here. * cgraphunit.c: Moved to... * cgraphunit.cc: ...here. * collect-utils.c: Moved to... * collect-utils.cc: ...here. * collect2-aix.c: Moved to... * collect2-aix.cc: ...here. * collect2.c: Moved to... * collect2.cc: ...here. * combine-stack-adj.c: Moved to... * combine-stack-adj.cc: ...here. * combine.c: Moved to... * combine.cc: ...here. * common/common-targhooks.c: Moved to... * common/common-targhooks.cc: ...here. * common/config/aarch64/aarch64-common.c: Moved to... * common/config/aarch64/aarch64-common.cc: ...here. * common/config/alpha/alpha-common.c: Moved to... * common/config/alpha/alpha-common.cc: ...here. * common/config/arc/arc-common.c: Moved to... * common/config/arc/arc-common.cc: ...here. * common/config/arm/arm-common.c: Moved to... * common/config/arm/arm-common.cc: ...here. * common/config/avr/avr-common.c: Moved to... * common/config/avr/avr-common.cc: ...here. * common/config/bfin/bfin-common.c: Moved to... * common/config/bfin/bfin-common.cc: ...here. * common/config/bpf/bpf-common.c: Moved to... * common/config/bpf/bpf-common.cc: ...here. * common/config/c6x/c6x-common.c: Moved to... * common/config/c6x/c6x-common.cc: ...here. * common/config/cr16/cr16-common.c: Moved to... * common/config/cr16/cr16-common.cc: ...here. * common/config/cris/cris-common.c: Moved to... * common/config/cris/cris-common.cc: ...here. * common/config/csky/csky-common.c: Moved to... * common/config/csky/csky-common.cc: ...here. * common/config/default-common.c: Moved to... * common/config/default-common.cc: ...here. * common/config/epiphany/epiphany-common.c: Moved to... * common/config/epiphany/epiphany-common.cc: ...here. * common/config/fr30/fr30-common.c: Moved to... * common/config/fr30/fr30-common.cc: ...here. * common/config/frv/frv-common.c: Moved to... * common/config/frv/frv-common.cc: ...here. * common/config/gcn/gcn-common.c: Moved to... * common/config/gcn/gcn-common.cc: ...here. * common/config/h8300/h8300-common.c: Moved to... * common/config/h8300/h8300-common.cc: ...here. * common/config/i386/i386-common.c: Moved to... * common/config/i386/i386-common.cc: ...here. * common/config/ia64/ia64-common.c: Moved to... * common/config/ia64/ia64-common.cc: ...here. * common/config/iq2000/iq2000-common.c: Moved to... * common/config/iq2000/iq2000-common.cc: ...here. * common/config/lm32/lm32-common.c: Moved to... * common/config/lm32/lm32-common.cc: ...here. * common/config/m32r/m32r-common.c: Moved to... * common/config/m32r/m32r-common.cc: ...here. * common/config/m68k/m68k-common.c: Moved to... * common/config/m68k/m68k-common.cc: ...here. * common/config/mcore/mcore-common.c: Moved to... * common/config/mcore/mcore-common.cc: ...here. * common/config/microblaze/microblaze-common.c: Moved to... * common/config/microblaze/microblaze-common.cc: ...here. * common/config/mips/mips-common.c: Moved to... * common/config/mips/mips-common.cc: ...here. * common/config/mmix/mmix-common.c: Moved to... * common/config/mmix/mmix-common.cc: ...here. * common/config/mn10300/mn10300-common.c: Moved to... * common/config/mn10300/mn10300-common.cc: ...here. * common/config/msp430/msp430-common.c: Moved to... * common/config/msp430/msp430-common.cc: ...here. * common/config/nds32/nds32-common.c: Moved to... * common/config/nds32/nds32-common.cc: ...here. * common/config/nios2/nios2-common.c: Moved to... * common/config/nios2/nios2-common.cc: ...here. * common/config/nvptx/nvptx-common.c: Moved to... * common/config/nvptx/nvptx-common.cc: ...here. * common/config/or1k/or1k-common.c: Moved to... * common/config/or1k/or1k-common.cc: ...here. * common/config/pa/pa-common.c: Moved to... * common/config/pa/pa-common.cc: ...here. * common/config/pdp11/pdp11-common.c: Moved to... * common/config/pdp11/pdp11-common.cc: ...here. * common/config/pru/pru-common.c: Moved to... * common/config/pru/pru-common.cc: ...here. * common/config/riscv/riscv-common.c: Moved to... * common/config/riscv/riscv-common.cc: ...here. * common/config/rs6000/rs6000-common.c: Moved to... * common/config/rs6000/rs6000-common.cc: ...here. * common/config/rx/rx-common.c: Moved to... * common/config/rx/rx-common.cc: ...here. * common/config/s390/s390-common.c: Moved to... * common/config/s390/s390-common.cc: ...here. * common/config/sh/sh-common.c: Moved to... * common/config/sh/sh-common.cc: ...here. * common/config/sparc/sparc-common.c: Moved to... * common/config/sparc/sparc-common.cc: ...here. * common/config/tilegx/tilegx-common.c: Moved to... * common/config/tilegx/tilegx-common.cc: ...here. * common/config/tilepro/tilepro-common.c: Moved to... * common/config/tilepro/tilepro-common.cc: ...here. * common/config/v850/v850-common.c: Moved to... * common/config/v850/v850-common.cc: ...here. * common/config/vax/vax-common.c: Moved to... * common/config/vax/vax-common.cc: ...here. * common/config/visium/visium-common.c: Moved to... * common/config/visium/visium-common.cc: ...here. * common/config/xstormy16/xstormy16-common.c: Moved to... * common/config/xstormy16/xstormy16-common.cc: ...here. * common/config/xtensa/xtensa-common.c: Moved to... * common/config/xtensa/xtensa-common.cc: ...here. * compare-elim.c: Moved to... * compare-elim.cc: ...here. * config/aarch64/aarch64-bti-insert.c: Moved to... * config/aarch64/aarch64-bti-insert.cc: ...here. * config/aarch64/aarch64-builtins.c: Moved to... * config/aarch64/aarch64-builtins.cc: ...here. * config/aarch64/aarch64-c.c: Moved to... * config/aarch64/aarch64-c.cc: ...here. * config/aarch64/aarch64-d.c: Moved to... * config/aarch64/aarch64-d.cc: ...here. * config/aarch64/aarch64.c: Moved to... * config/aarch64/aarch64.cc: ...here. * config/aarch64/cortex-a57-fma-steering.c: Moved to... * config/aarch64/cortex-a57-fma-steering.cc: ...here. * config/aarch64/driver-aarch64.c: Moved to... * config/aarch64/driver-aarch64.cc: ...here. * config/aarch64/falkor-tag-collision-avoidance.c: Moved to... * config/aarch64/falkor-tag-collision-avoidance.cc: ...here. * config/aarch64/host-aarch64-darwin.c: Moved to... * config/aarch64/host-aarch64-darwin.cc: ...here. * config/alpha/alpha.c: Moved to... * config/alpha/alpha.cc: ...here. * config/alpha/driver-alpha.c: Moved to... * config/alpha/driver-alpha.cc: ...here. * config/arc/arc-c.c: Moved to... * config/arc/arc-c.cc: ...here. * config/arc/arc.c: Moved to... * config/arc/arc.cc: ...here. * config/arc/driver-arc.c: Moved to... * config/arc/driver-arc.cc: ...here. * config/arm/aarch-common.c: Moved to... * config/arm/aarch-common.cc: ...here. * config/arm/arm-builtins.c: Moved to... * config/arm/arm-builtins.cc: ...here. * config/arm/arm-c.c: Moved to... * config/arm/arm-c.cc: ...here. * config/arm/arm-d.c: Moved to... * config/arm/arm-d.cc: ...here. * config/arm/arm.c: Moved to... * config/arm/arm.cc: ...here. * config/arm/driver-arm.c: Moved to... * config/arm/driver-arm.cc: ...here. * config/avr/avr-c.c: Moved to... * config/avr/avr-c.cc: ...here. * config/avr/avr-devices.c: Moved to... * config/avr/avr-devices.cc: ...here. * config/avr/avr-log.c: Moved to... * config/avr/avr-log.cc: ...here. * config/avr/avr.c: Moved to... * config/avr/avr.cc: ...here. * config/avr/driver-avr.c: Moved to... * config/avr/driver-avr.cc: ...here. * config/avr/gen-avr-mmcu-specs.c: Moved to... * config/avr/gen-avr-mmcu-specs.cc: ...here. * config/avr/gen-avr-mmcu-texi.c: Moved to... * config/avr/gen-avr-mmcu-texi.cc: ...here. * config/bfin/bfin.c: Moved to... * config/bfin/bfin.cc: ...here. * config/bpf/bpf.c: Moved to... * config/bpf/bpf.cc: ...here. * config/bpf/coreout.c: Moved to... * config/bpf/coreout.cc: ...here. * config/c6x/c6x.c: Moved to... * config/c6x/c6x.cc: ...here. * config/cr16/cr16.c: Moved to... * config/cr16/cr16.cc: ...here. * config/cris/cris.c: Moved to... * config/cris/cris.cc: ...here. * config/csky/csky.c: Moved to... * config/csky/csky.cc: ...here. * config/darwin-c.c: Moved to... * config/darwin-c.cc: ...here. * config/darwin-d.c: Moved to... * config/darwin-d.cc: ...here. * config/darwin-driver.c: Moved to... * config/darwin-driver.cc: ...here. * config/darwin-f.c: Moved to... * config/darwin-f.cc: ...here. * config/darwin.c: Moved to... * config/darwin.cc: ...here. * config/default-c.c: Moved to... * config/default-c.cc: ...here. * config/default-d.c: Moved to... * config/default-d.cc: ...here. * config/dragonfly-d.c: Moved to... * config/dragonfly-d.cc: ...here. * config/epiphany/epiphany.c: Moved to... * config/epiphany/epiphany.cc: ...here. * config/epiphany/mode-switch-use.c: Moved to... * config/epiphany/mode-switch-use.cc: ...here. * config/epiphany/resolve-sw-modes.c: Moved to... * config/epiphany/resolve-sw-modes.cc: ...here. * config/fr30/fr30.c: Moved to... * config/fr30/fr30.cc: ...here. * config/freebsd-d.c: Moved to... * config/freebsd-d.cc: ...here. * config/frv/frv.c: Moved to... * config/frv/frv.cc: ...here. * config/ft32/ft32.c: Moved to... * config/ft32/ft32.cc: ...here. * config/gcn/driver-gcn.c: Moved to... * config/gcn/driver-gcn.cc: ...here. * config/gcn/gcn-run.c: Moved to... * config/gcn/gcn-run.cc: ...here. * config/gcn/gcn-tree.c: Moved to... * config/gcn/gcn-tree.cc: ...here. * config/gcn/gcn.c: Moved to... * config/gcn/gcn.cc: ...here. * config/gcn/mkoffload.c: Moved to... * config/gcn/mkoffload.cc: ...here. * config/glibc-c.c: Moved to... * config/glibc-c.cc: ...here. * config/glibc-d.c: Moved to... * config/glibc-d.cc: ...here. * config/h8300/h8300.c: Moved to... * config/h8300/h8300.cc: ...here. * config/host-darwin.c: Moved to... * config/host-darwin.cc: ...here. * config/host-hpux.c: Moved to... * config/host-hpux.cc: ...here. * config/host-linux.c: Moved to... * config/host-linux.cc: ...here. * config/host-netbsd.c: Moved to... * config/host-netbsd.cc: ...here. * config/host-openbsd.c: Moved to... * config/host-openbsd.cc: ...here. * config/host-solaris.c: Moved to... * config/host-solaris.cc: ...here. * config/i386/djgpp.c: Moved to... * config/i386/djgpp.cc: ...here. * config/i386/driver-i386.c: Moved to... * config/i386/driver-i386.cc: ...here. * config/i386/driver-mingw32.c: Moved to... * config/i386/driver-mingw32.cc: ...here. * config/i386/gnu-property.c: Moved to... * config/i386/gnu-property.cc: ...here. * config/i386/host-cygwin.c: Moved to... * config/i386/host-cygwin.cc: ...here. * config/i386/host-i386-darwin.c: Moved to... * config/i386/host-i386-darwin.cc: ...here. * config/i386/host-mingw32.c: Moved to... * config/i386/host-mingw32.cc: ...here. * config/i386/i386-builtins.c: Moved to... * config/i386/i386-builtins.cc: ...here. * config/i386/i386-c.c: Moved to... * config/i386/i386-c.cc: ...here. * config/i386/i386-d.c: Moved to... * config/i386/i386-d.cc: ...here. * config/i386/i386-expand.c: Moved to... * config/i386/i386-expand.cc: ...here. * config/i386/i386-features.c: Moved to... * config/i386/i386-features.cc: ...here. * config/i386/i386-options.c: Moved to... * config/i386/i386-options.cc: ...here. * config/i386/i386.c: Moved to... * config/i386/i386.cc: ...here. * config/i386/intelmic-mkoffload.c: Moved to... * config/i386/intelmic-mkoffload.cc: ...here. * config/i386/msformat-c.c: Moved to... * config/i386/msformat-c.cc: ...here. * config/i386/winnt-cxx.c: Moved to... * config/i386/winnt-cxx.cc: ...here. * config/i386/winnt-d.c: Moved to... * config/i386/winnt-d.cc: ...here. * config/i386/winnt-stubs.c: Moved to... * config/i386/winnt-stubs.cc: ...here. * config/i386/winnt.c: Moved to... * config/i386/winnt.cc: ...here. * config/i386/x86-tune-sched-atom.c: Moved to... * config/i386/x86-tune-sched-atom.cc: ...here. * config/i386/x86-tune-sched-bd.c: Moved to... * config/i386/x86-tune-sched-bd.cc: ...here. * config/i386/x86-tune-sched-core.c: Moved to... * config/i386/x86-tune-sched-core.cc: ...here. * config/i386/x86-tune-sched.c: Moved to... * config/i386/x86-tune-sched.cc: ...here. * config/ia64/ia64-c.c: Moved to... * config/ia64/ia64-c.cc: ...here. * config/ia64/ia64.c: Moved to... * config/ia64/ia64.cc: ...here. * config/iq2000/iq2000.c: Moved to... * config/iq2000/iq2000.cc: ...here. * config/linux.c: Moved to... * config/linux.cc: ...here. * config/lm32/lm32.c: Moved to... * config/lm32/lm32.cc: ...here. * config/m32c/m32c-pragma.c: Moved to... * config/m32c/m32c-pragma.cc: ...here. * config/m32c/m32c.c: Moved to... * config/m32c/m32c.cc: ...here. * config/m32r/m32r.c: Moved to... * config/m32r/m32r.cc: ...here. * config/m68k/m68k.c: Moved to... * config/m68k/m68k.cc: ...here. * config/mcore/mcore.c: Moved to... * config/mcore/mcore.cc: ...here. * config/microblaze/microblaze-c.c: Moved to... * config/microblaze/microblaze-c.cc: ...here. * config/microblaze/microblaze.c: Moved to... * config/microblaze/microblaze.cc: ...here. * config/mips/driver-native.c: Moved to... * config/mips/driver-native.cc: ...here. * config/mips/frame-header-opt.c: Moved to... * config/mips/frame-header-opt.cc: ...here. * config/mips/mips-d.c: Moved to... * config/mips/mips-d.cc: ...here. * config/mips/mips.c: Moved to... * config/mips/mips.cc: ...here. * config/mmix/mmix.c: Moved to... * config/mmix/mmix.cc: ...here. * config/mn10300/mn10300.c: Moved to... * config/mn10300/mn10300.cc: ...here. * config/moxie/moxie.c: Moved to... * config/moxie/moxie.cc: ...here. * config/msp430/driver-msp430.c: Moved to... * config/msp430/driver-msp430.cc: ...here. * config/msp430/msp430-c.c: Moved to... * config/msp430/msp430-c.cc: ...here. * config/msp430/msp430-devices.c: Moved to... * config/msp430/msp430-devices.cc: ...here. * config/msp430/msp430.c: Moved to... * config/msp430/msp430.cc: ...here. * config/nds32/nds32-cost.c: Moved to... * config/nds32/nds32-cost.cc: ...here. * config/nds32/nds32-fp-as-gp.c: Moved to... * config/nds32/nds32-fp-as-gp.cc: ...here. * config/nds32/nds32-intrinsic.c: Moved to... * config/nds32/nds32-intrinsic.cc: ...here. * config/nds32/nds32-isr.c: Moved to... * config/nds32/nds32-isr.cc: ...here. * config/nds32/nds32-md-auxiliary.c: Moved to... * config/nds32/nds32-md-auxiliary.cc: ...here. * config/nds32/nds32-memory-manipulation.c: Moved to... * config/nds32/nds32-memory-manipulation.cc: ...here. * config/nds32/nds32-pipelines-auxiliary.c: Moved to... * config/nds32/nds32-pipelines-auxiliary.cc: ...here. * config/nds32/nds32-predicates.c: Moved to... * config/nds32/nds32-predicates.cc: ...here. * config/nds32/nds32-relax-opt.c: Moved to... * config/nds32/nds32-relax-opt.cc: ...here. * config/nds32/nds32-utils.c: Moved to... * config/nds32/nds32-utils.cc: ...here. * config/nds32/nds32.c: Moved to... * config/nds32/nds32.cc: ...here. * config/netbsd-d.c: Moved to... * config/netbsd-d.cc: ...here. * config/netbsd.c: Moved to... * config/netbsd.cc: ...here. * config/nios2/nios2.c: Moved to... * config/nios2/nios2.cc: ...here. * config/nvptx/mkoffload.c: Moved to... * config/nvptx/mkoffload.cc: ...here. * config/nvptx/nvptx-c.c: Moved to... * config/nvptx/nvptx-c.cc: ...here. * config/nvptx/nvptx.c: Moved to... * config/nvptx/nvptx.cc: ...here. * config/openbsd-d.c: Moved to... * config/openbsd-d.cc: ...here. * config/or1k/or1k.c: Moved to... * config/or1k/or1k.cc: ...here. * config/pa/pa-d.c: Moved to... * config/pa/pa-d.cc: ...here. * config/pa/pa.c: Moved to... * config/pa/pa.cc: ...here. * config/pdp11/pdp11.c: Moved to... * config/pdp11/pdp11.cc: ...here. * config/pru/pru-passes.c: Moved to... * config/pru/pru-passes.cc: ...here. * config/pru/pru-pragma.c: Moved to... * config/pru/pru-pragma.cc: ...here. * config/pru/pru.c: Moved to... * config/pru/pru.cc: ...here. * config/riscv/riscv-builtins.c: Moved to... * config/riscv/riscv-builtins.cc: ...here. * config/riscv/riscv-c.c: Moved to... * config/riscv/riscv-c.cc: ...here. * config/riscv/riscv-d.c: Moved to... * config/riscv/riscv-d.cc: ...here. * config/riscv/riscv-shorten-memrefs.c: Moved to... * config/riscv/riscv-shorten-memrefs.cc: ...here. * config/riscv/riscv-sr.c: Moved to... * config/riscv/riscv-sr.cc: ...here. * config/riscv/riscv.c: Moved to... * config/riscv/riscv.cc: ...here. * config/rl78/rl78-c.c: Moved to... * config/rl78/rl78-c.cc: ...here. * config/rl78/rl78.c: Moved to... * config/rl78/rl78.cc: ...here. * config/rs6000/driver-rs6000.c: Moved to... * config/rs6000/driver-rs6000.cc: ...here. * config/rs6000/host-darwin.c: Moved to... * config/rs6000/host-darwin.cc: ...here. * config/rs6000/host-ppc64-darwin.c: Moved to... * config/rs6000/host-ppc64-darwin.cc: ...here. * config/rs6000/rbtree.c: Moved to... * config/rs6000/rbtree.cc: ...here. * config/rs6000/rs6000-c.c: Moved to... * config/rs6000/rs6000-c.cc: ...here. * config/rs6000/rs6000-call.c: Moved to... * config/rs6000/rs6000-call.cc: ...here. * config/rs6000/rs6000-d.c: Moved to... * config/rs6000/rs6000-d.cc: ...here. * config/rs6000/rs6000-gen-builtins.c: Moved to... * config/rs6000/rs6000-gen-builtins.cc: ...here. * config/rs6000/rs6000-linux.c: Moved to... * config/rs6000/rs6000-linux.cc: ...here. * config/rs6000/rs6000-logue.c: Moved to... * config/rs6000/rs6000-logue.cc: ...here. * config/rs6000/rs6000-p8swap.c: Moved to... * config/rs6000/rs6000-p8swap.cc: ...here. * config/rs6000/rs6000-pcrel-opt.c: Moved to... * config/rs6000/rs6000-pcrel-opt.cc: ...here. * config/rs6000/rs6000-string.c: Moved to... * config/rs6000/rs6000-string.cc: ...here. * config/rs6000/rs6000.c: Moved to... * config/rs6000/rs6000.cc: ...here. * config/rx/rx.c: Moved to... * config/rx/rx.cc: ...here. * config/s390/driver-native.c: Moved to... * config/s390/driver-native.cc: ...here. * config/s390/s390-c.c: Moved to... * config/s390/s390-c.cc: ...here. * config/s390/s390-d.c: Moved to... * config/s390/s390-d.cc: ...here. * config/s390/s390.c: Moved to... * config/s390/s390.cc: ...here. * config/sh/divtab-sh4-300.c: Moved to... * config/sh/divtab-sh4-300.cc: ...here. * config/sh/divtab-sh4.c: Moved to... * config/sh/divtab-sh4.cc: ...here. * config/sh/divtab.c: Moved to... * config/sh/divtab.cc: ...here. * config/sh/sh-c.c: Moved to... * config/sh/sh-c.cc: ...here. * config/sh/sh.c: Moved to... * config/sh/sh.cc: ...here. * config/sol2-c.c: Moved to... * config/sol2-c.cc: ...here. * config/sol2-cxx.c: Moved to... * config/sol2-cxx.cc: ...here. * config/sol2-d.c: Moved to... * config/sol2-d.cc: ...here. * config/sol2-stubs.c: Moved to... * config/sol2-stubs.cc: ...here. * config/sol2.c: Moved to... * config/sol2.cc: ...here. * config/sparc/driver-sparc.c: Moved to... * config/sparc/driver-sparc.cc: ...here. * config/sparc/sparc-c.c: Moved to... * config/sparc/sparc-c.cc: ...here. * config/sparc/sparc-d.c: Moved to... * config/sparc/sparc-d.cc: ...here. * config/sparc/sparc.c: Moved to... * config/sparc/sparc.cc: ...here. * config/stormy16/stormy16.c: Moved to... * config/stormy16/stormy16.cc: ...here. * config/tilegx/mul-tables.c: Moved to... * config/tilegx/mul-tables.cc: ...here. * config/tilegx/tilegx-c.c: Moved to... * config/tilegx/tilegx-c.cc: ...here. * config/tilegx/tilegx.c: Moved to... * config/tilegx/tilegx.cc: ...here. * config/tilepro/mul-tables.c: Moved to... * config/tilepro/mul-tables.cc: ...here. * config/tilepro/tilepro-c.c: Moved to... * config/tilepro/tilepro-c.cc: ...here. * config/tilepro/tilepro.c: Moved to... * config/tilepro/tilepro.cc: ...here. * config/v850/v850-c.c: Moved to... * config/v850/v850-c.cc: ...here. * config/v850/v850.c: Moved to... * config/v850/v850.cc: ...here. * config/vax/vax.c: Moved to... * config/vax/vax.cc: ...here. * config/visium/visium.c: Moved to... * config/visium/visium.cc: ...here. * config/vms/vms-c.c: Moved to... * config/vms/vms-c.cc: ...here. * config/vms/vms-f.c: Moved to... * config/vms/vms-f.cc: ...here. * config/vms/vms.c: Moved to... * config/vms/vms.cc: ...here. * config/vxworks-c.c: Moved to... * config/vxworks-c.cc: ...here. * config/vxworks.c: Moved to... * config/vxworks.cc: ...here. * config/winnt-c.c: Moved to... * config/winnt-c.cc: ...here. * config/xtensa/xtensa.c: Moved to... * config/xtensa/xtensa.cc: ...here. * context.c: Moved to... * context.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * coverage.c: Moved to... * coverage.cc: ...here. * cppbuiltin.c: Moved to... * cppbuiltin.cc: ...here. * cppdefault.c: Moved to... * cppdefault.cc: ...here. * cprop.c: Moved to... * cprop.cc: ...here. * cse.c: Moved to... * cse.cc: ...here. * cselib.c: Moved to... * cselib.cc: ...here. * ctfc.c: Moved to... * ctfc.cc: ...here. * ctfout.c: Moved to... * ctfout.cc: ...here. * data-streamer-in.c: Moved to... * data-streamer-in.cc: ...here. * data-streamer-out.c: Moved to... * data-streamer-out.cc: ...here. * data-streamer.c: Moved to... * data-streamer.cc: ...here. * dbgcnt.c: Moved to... * dbgcnt.cc: ...here. * dbxout.c: Moved to... * dbxout.cc: ...here. * dce.c: Moved to... * dce.cc: ...here. * ddg.c: Moved to... * ddg.cc: ...here. * debug.c: Moved to... * debug.cc: ...here. * df-core.c: Moved to... * df-core.cc: ...here. * df-problems.c: Moved to... * df-problems.cc: ...here. * df-scan.c: Moved to... * df-scan.cc: ...here. * dfp.c: Moved to... * dfp.cc: ...here. * diagnostic-color.c: Moved to... * diagnostic-color.cc: ...here. * diagnostic-show-locus.c: Moved to... * diagnostic-show-locus.cc: ...here. * diagnostic-spec.c: Moved to... * diagnostic-spec.cc: ...here. * diagnostic.c: Moved to... * diagnostic.cc: ...here. * dojump.c: Moved to... * dojump.cc: ...here. * dominance.c: Moved to... * dominance.cc: ...here. * domwalk.c: Moved to... * domwalk.cc: ...here. * double-int.c: Moved to... * double-int.cc: ...here. * dse.c: Moved to... * dse.cc: ...here. * dumpfile.c: Moved to... * dumpfile.cc: ...here. * dwarf2asm.c: Moved to... * dwarf2asm.cc: ...here. * dwarf2cfi.c: Moved to... * dwarf2cfi.cc: ...here. * dwarf2ctf.c: Moved to... * dwarf2ctf.cc: ...here. * dwarf2out.c: Moved to... * dwarf2out.cc: ...here. * early-remat.c: Moved to... * early-remat.cc: ...here. * edit-context.c: Moved to... * edit-context.cc: ...here. * emit-rtl.c: Moved to... * emit-rtl.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * et-forest.c: Moved to... * et-forest.cc: ...here. * except.c: Moved to... * except.cc: ...here. * explow.c: Moved to... * explow.cc: ...here. * expmed.c: Moved to... * expmed.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * fibonacci_heap.c: Moved to... * fibonacci_heap.cc: ...here. * file-find.c: Moved to... * file-find.cc: ...here. * file-prefix-map.c: Moved to... * file-prefix-map.cc: ...here. * final.c: Moved to... * final.cc: ...here. * fixed-value.c: Moved to... * fixed-value.cc: ...here. * fold-const-call.c: Moved to... * fold-const-call.cc: ...here. * fold-const.c: Moved to... * fold-const.cc: ...here. * fp-test.c: Moved to... * fp-test.cc: ...here. * function-tests.c: Moved to... * function-tests.cc: ...here. * function.c: Moved to... * function.cc: ...here. * fwprop.c: Moved to... * fwprop.cc: ...here. * gcc-ar.c: Moved to... * gcc-ar.cc: ...here. * gcc-main.c: Moved to... * gcc-main.cc: ...here. * gcc-rich-location.c: Moved to... * gcc-rich-location.cc: ...here. * gcc.c: Moved to... * gcc.cc: ...here. * gcov-dump.c: Moved to... * gcov-dump.cc: ...here. * gcov-io.c: Moved to... * gcov-io.cc: ...here. * gcov-tool.c: Moved to... * gcov-tool.cc: ...here. * gcov.c: Moved to... * gcov.cc: ...here. * gcse-common.c: Moved to... * gcse-common.cc: ...here. * gcse.c: Moved to... * gcse.cc: ...here. * genattr-common.c: Moved to... * genattr-common.cc: ...here. * genattr.c: Moved to... * genattr.cc: ...here. * genattrtab.c: Moved to... * genattrtab.cc: ...here. * genautomata.c: Moved to... * genautomata.cc: ...here. * gencfn-macros.c: Moved to... * gencfn-macros.cc: ...here. * gencheck.c: Moved to... * gencheck.cc: ...here. * genchecksum.c: Moved to... * genchecksum.cc: ...here. * gencodes.c: Moved to... * gencodes.cc: ...here. * genconditions.c: Moved to... * genconditions.cc: ...here. * genconfig.c: Moved to... * genconfig.cc: ...here. * genconstants.c: Moved to... * genconstants.cc: ...here. * genemit.c: Moved to... * genemit.cc: ...here. * genenums.c: Moved to... * genenums.cc: ...here. * generic-match-head.c: Moved to... * generic-match-head.cc: ...here. * genextract.c: Moved to... * genextract.cc: ...here. * genflags.c: Moved to... * genflags.cc: ...here. * gengenrtl.c: Moved to... * gengenrtl.cc: ...here. * gengtype-parse.c: Moved to... * gengtype-parse.cc: ...here. * gengtype-state.c: Moved to... * gengtype-state.cc: ...here. * gengtype.c: Moved to... * gengtype.cc: ...here. * genhooks.c: Moved to... * genhooks.cc: ...here. * genmatch.c: Moved to... * genmatch.cc: ...here. * genmddeps.c: Moved to... * genmddeps.cc: ...here. * genmddump.c: Moved to... * genmddump.cc: ...here. * genmodes.c: Moved to... * genmodes.cc: ...here. * genopinit.c: Moved to... * genopinit.cc: ...here. * genoutput.c: Moved to... * genoutput.cc: ...here. * genpeep.c: Moved to... * genpeep.cc: ...here. * genpreds.c: Moved to... * genpreds.cc: ...here. * genrecog.c: Moved to... * genrecog.cc: ...here. * gensupport.c: Moved to... * gensupport.cc: ...here. * gentarget-def.c: Moved to... * gentarget-def.cc: ...here. * genversion.c: Moved to... * genversion.cc: ...here. * ggc-common.c: Moved to... * ggc-common.cc: ...here. * ggc-none.c: Moved to... * ggc-none.cc: ...here. * ggc-page.c: Moved to... * ggc-page.cc: ...here. * ggc-tests.c: Moved to... * ggc-tests.cc: ...here. * gimple-builder.c: Moved to... * gimple-builder.cc: ...here. * gimple-expr.c: Moved to... * gimple-expr.cc: ...here. * gimple-fold.c: Moved to... * gimple-fold.cc: ...here. * gimple-iterator.c: Moved to... * gimple-iterator.cc: ...here. * gimple-laddress.c: Moved to... * gimple-laddress.cc: ...here. * gimple-loop-jam.c: Moved to... * gimple-loop-jam.cc: ...here. * gimple-low.c: Moved to... * gimple-low.cc: ...here. * gimple-match-head.c: Moved to... * gimple-match-head.cc: ...here. * gimple-pretty-print.c: Moved to... * gimple-pretty-print.cc: ...here. * gimple-ssa-backprop.c: Moved to... * gimple-ssa-backprop.cc: ...here. * gimple-ssa-evrp-analyze.c: Moved to... * gimple-ssa-evrp-analyze.cc: ...here. * gimple-ssa-evrp.c: Moved to... * gimple-ssa-evrp.cc: ...here. * gimple-ssa-isolate-paths.c: Moved to... * gimple-ssa-isolate-paths.cc: ...here. * gimple-ssa-nonnull-compare.c: Moved to... * gimple-ssa-nonnull-compare.cc: ...here. * gimple-ssa-split-paths.c: Moved to... * gimple-ssa-split-paths.cc: ...here. * gimple-ssa-sprintf.c: Moved to... * gimple-ssa-sprintf.cc: ...here. * gimple-ssa-store-merging.c: Moved to... * gimple-ssa-store-merging.cc: ...here. * gimple-ssa-strength-reduction.c: Moved to... * gimple-ssa-strength-reduction.cc: ...here. * gimple-ssa-warn-alloca.c: Moved to... * gimple-ssa-warn-alloca.cc: ...here. * gimple-ssa-warn-restrict.c: Moved to... * gimple-ssa-warn-restrict.cc: ...here. * gimple-streamer-in.c: Moved to... * gimple-streamer-in.cc: ...here. * gimple-streamer-out.c: Moved to... * gimple-streamer-out.cc: ...here. * gimple-walk.c: Moved to... * gimple-walk.cc: ...here. * gimple-warn-recursion.c: Moved to... * gimple-warn-recursion.cc: ...here. * gimple.c: Moved to... * gimple.cc: ...here. * gimplify-me.c: Moved to... * gimplify-me.cc: ...here. * gimplify.c: Moved to... * gimplify.cc: ...here. * godump.c: Moved to... * godump.cc: ...here. * graph.c: Moved to... * graph.cc: ...here. * graphds.c: Moved to... * graphds.cc: ...here. * graphite-dependences.c: Moved to... * graphite-dependences.cc: ...here. * graphite-isl-ast-to-gimple.c: Moved to... * graphite-isl-ast-to-gimple.cc: ...here. * graphite-optimize-isl.c: Moved to... * graphite-optimize-isl.cc: ...here. * graphite-poly.c: Moved to... * graphite-poly.cc: ...here. * graphite-scop-detection.c: Moved to... * graphite-scop-detection.cc: ...here. * graphite-sese-to-poly.c: Moved to... * graphite-sese-to-poly.cc: ...here. * graphite.c: Moved to... * graphite.cc: ...here. * haifa-sched.c: Moved to... * haifa-sched.cc: ...here. * hash-map-tests.c: Moved to... * hash-map-tests.cc: ...here. * hash-set-tests.c: Moved to... * hash-set-tests.cc: ...here. * hash-table.c: Moved to... * hash-table.cc: ...here. * hooks.c: Moved to... * hooks.cc: ...here. * host-default.c: Moved to... * host-default.cc: ...here. * hw-doloop.c: Moved to... * hw-doloop.cc: ...here. * hwint.c: Moved to... * hwint.cc: ...here. * ifcvt.c: Moved to... * ifcvt.cc: ...here. * inchash.c: Moved to... * inchash.cc: ...here. * incpath.c: Moved to... * incpath.cc: ...here. * init-regs.c: Moved to... * init-regs.cc: ...here. * input.c: Moved to... * input.cc: ...here. * internal-fn.c: Moved to... * internal-fn.cc: ...here. * intl.c: Moved to... * intl.cc: ...here. * ipa-comdats.c: Moved to... * ipa-comdats.cc: ...here. * ipa-cp.c: Moved to... * ipa-cp.cc: ...here. * ipa-devirt.c: Moved to... * ipa-devirt.cc: ...here. * ipa-fnsummary.c: Moved to... * ipa-fnsummary.cc: ...here. * ipa-icf-gimple.c: Moved to... * ipa-icf-gimple.cc: ...here. * ipa-icf.c: Moved to... * ipa-icf.cc: ...here. * ipa-inline-analysis.c: Moved to... * ipa-inline-analysis.cc: ...here. * ipa-inline-transform.c: Moved to... * ipa-inline-transform.cc: ...here. * ipa-inline.c: Moved to... * ipa-inline.cc: ...here. * ipa-modref-tree.c: Moved to... * ipa-modref-tree.cc: ...here. * ipa-modref.c: Moved to... * ipa-modref.cc: ...here. * ipa-param-manipulation.c: Moved to... * ipa-param-manipulation.cc: ...here. * ipa-polymorphic-call.c: Moved to... * ipa-polymorphic-call.cc: ...here. * ipa-predicate.c: Moved to... * ipa-predicate.cc: ...here. * ipa-profile.c: Moved to... * ipa-profile.cc: ...here. * ipa-prop.c: Moved to... * ipa-prop.cc: ...here. * ipa-pure-const.c: Moved to... * ipa-pure-const.cc: ...here. * ipa-ref.c: Moved to... * ipa-ref.cc: ...here. * ipa-reference.c: Moved to... * ipa-reference.cc: ...here. * ipa-split.c: Moved to... * ipa-split.cc: ...here. * ipa-sra.c: Moved to... * ipa-sra.cc: ...here. * ipa-utils.c: Moved to... * ipa-utils.cc: ...here. * ipa-visibility.c: Moved to... * ipa-visibility.cc: ...here. * ipa.c: Moved to... * ipa.cc: ...here. * ira-build.c: Moved to... * ira-build.cc: ...here. * ira-color.c: Moved to... * ira-color.cc: ...here. * ira-conflicts.c: Moved to... * ira-conflicts.cc: ...here. * ira-costs.c: Moved to... * ira-costs.cc: ...here. * ira-emit.c: Moved to... * ira-emit.cc: ...here. * ira-lives.c: Moved to... * ira-lives.cc: ...here. * ira.c: Moved to... * ira.cc: ...here. * jump.c: Moved to... * jump.cc: ...here. * langhooks.c: Moved to... * langhooks.cc: ...here. * lcm.c: Moved to... * lcm.cc: ...here. * lists.c: Moved to... * lists.cc: ...here. * loop-doloop.c: Moved to... * loop-doloop.cc: ...here. * loop-init.c: Moved to... * loop-init.cc: ...here. * loop-invariant.c: Moved to... * loop-invariant.cc: ...here. * loop-iv.c: Moved to... * loop-iv.cc: ...here. * loop-unroll.c: Moved to... * loop-unroll.cc: ...here. * lower-subreg.c: Moved to... * lower-subreg.cc: ...here. * lra-assigns.c: Moved to... * lra-assigns.cc: ...here. * lra-coalesce.c: Moved to... * lra-coalesce.cc: ...here. * lra-constraints.c: Moved to... * lra-constraints.cc: ...here. * lra-eliminations.c: Moved to... * lra-eliminations.cc: ...here. * lra-lives.c: Moved to... * lra-lives.cc: ...here. * lra-remat.c: Moved to... * lra-remat.cc: ...here. * lra-spills.c: Moved to... * lra-spills.cc: ...here. * lra.c: Moved to... * lra.cc: ...here. * lto-cgraph.c: Moved to... * lto-cgraph.cc: ...here. * lto-compress.c: Moved to... * lto-compress.cc: ...here. * lto-opts.c: Moved to... * lto-opts.cc: ...here. * lto-section-in.c: Moved to... * lto-section-in.cc: ...here. * lto-section-out.c: Moved to... * lto-section-out.cc: ...here. * lto-streamer-in.c: Moved to... * lto-streamer-in.cc: ...here. * lto-streamer-out.c: Moved to... * lto-streamer-out.cc: ...here. * lto-streamer.c: Moved to... * lto-streamer.cc: ...here. * lto-wrapper.c: Moved to... * lto-wrapper.cc: ...here. * main.c: Moved to... * main.cc: ...here. * mcf.c: Moved to... * mcf.cc: ...here. * mode-switching.c: Moved to... * mode-switching.cc: ...here. * modulo-sched.c: Moved to... * modulo-sched.cc: ...here. * multiple_target.c: Moved to... * multiple_target.cc: ...here. * omp-expand.c: Moved to... * omp-expand.cc: ...here. * omp-general.c: Moved to... * omp-general.cc: ...here. * omp-low.c: Moved to... * omp-low.cc: ...here. * omp-offload.c: Moved to... * omp-offload.cc: ...here. * omp-simd-clone.c: Moved to... * omp-simd-clone.cc: ...here. * opt-suggestions.c: Moved to... * opt-suggestions.cc: ...here. * optabs-libfuncs.c: Moved to... * optabs-libfuncs.cc: ...here. * optabs-query.c: Moved to... * optabs-query.cc: ...here. * optabs-tree.c: Moved to... * optabs-tree.cc: ...here. * optabs.c: Moved to... * optabs.cc: ...here. * opts-common.c: Moved to... * opts-common.cc: ...here. * opts-global.c: Moved to... * opts-global.cc: ...here. * opts.c: Moved to... * opts.cc: ...here. * passes.c: Moved to... * passes.cc: ...here. * plugin.c: Moved to... * plugin.cc: ...here. * postreload-gcse.c: Moved to... * postreload-gcse.cc: ...here. * postreload.c: Moved to... * postreload.cc: ...here. * predict.c: Moved to... * predict.cc: ...here. * prefix.c: Moved to... * prefix.cc: ...here. * pretty-print.c: Moved to... * pretty-print.cc: ...here. * print-rtl-function.c: Moved to... * print-rtl-function.cc: ...here. * print-rtl.c: Moved to... * print-rtl.cc: ...here. * print-tree.c: Moved to... * print-tree.cc: ...here. * profile-count.c: Moved to... * profile-count.cc: ...here. * profile.c: Moved to... * profile.cc: ...here. * read-md.c: Moved to... * read-md.cc: ...here. * read-rtl-function.c: Moved to... * read-rtl-function.cc: ...here. * read-rtl.c: Moved to... * read-rtl.cc: ...here. * real.c: Moved to... * real.cc: ...here. * realmpfr.c: Moved to... * realmpfr.cc: ...here. * recog.c: Moved to... * recog.cc: ...here. * ree.c: Moved to... * ree.cc: ...here. * reg-stack.c: Moved to... * reg-stack.cc: ...here. * regcprop.c: Moved to... * regcprop.cc: ...here. * reginfo.c: Moved to... * reginfo.cc: ...here. * regrename.c: Moved to... * regrename.cc: ...here. * regstat.c: Moved to... * regstat.cc: ...here. * reload.c: Moved to... * reload.cc: ...here. * reload1.c: Moved to... * reload1.cc: ...here. * reorg.c: Moved to... * reorg.cc: ...here. * resource.c: Moved to... * resource.cc: ...here. * rtl-error.c: Moved to... * rtl-error.cc: ...here. * rtl-tests.c: Moved to... * rtl-tests.cc: ...here. * rtl.c: Moved to... * rtl.cc: ...here. * rtlanal.c: Moved to... * rtlanal.cc: ...here. * rtlhash.c: Moved to... * rtlhash.cc: ...here. * rtlhooks.c: Moved to... * rtlhooks.cc: ...here. * rtx-vector-builder.c: Moved to... * rtx-vector-builder.cc: ...here. * run-rtl-passes.c: Moved to... * run-rtl-passes.cc: ...here. * sancov.c: Moved to... * sancov.cc: ...here. * sanopt.c: Moved to... * sanopt.cc: ...here. * sbitmap.c: Moved to... * sbitmap.cc: ...here. * sched-deps.c: Moved to... * sched-deps.cc: ...here. * sched-ebb.c: Moved to... * sched-ebb.cc: ...here. * sched-rgn.c: Moved to... * sched-rgn.cc: ...here. * sel-sched-dump.c: Moved to... * sel-sched-dump.cc: ...here. * sel-sched-ir.c: Moved to... * sel-sched-ir.cc: ...here. * sel-sched.c: Moved to... * sel-sched.cc: ...here. * selftest-diagnostic.c: Moved to... * selftest-diagnostic.cc: ...here. * selftest-rtl.c: Moved to... * selftest-rtl.cc: ...here. * selftest-run-tests.c: Moved to... * selftest-run-tests.cc: ...here. * selftest.c: Moved to... * selftest.cc: ...here. * sese.c: Moved to... * sese.cc: ...here. * shrink-wrap.c: Moved to... * shrink-wrap.cc: ...here. * simplify-rtx.c: Moved to... * simplify-rtx.cc: ...here. * sparseset.c: Moved to... * sparseset.cc: ...here. * spellcheck-tree.c: Moved to... * spellcheck-tree.cc: ...here. * spellcheck.c: Moved to... * spellcheck.cc: ...here. * sreal.c: Moved to... * sreal.cc: ...here. * stack-ptr-mod.c: Moved to... * stack-ptr-mod.cc: ...here. * statistics.c: Moved to... * statistics.cc: ...here. * stmt.c: Moved to... * stmt.cc: ...here. * stor-layout.c: Moved to... * stor-layout.cc: ...here. * store-motion.c: Moved to... * store-motion.cc: ...here. * streamer-hooks.c: Moved to... * streamer-hooks.cc: ...here. * stringpool.c: Moved to... * stringpool.cc: ...here. * substring-locations.c: Moved to... * substring-locations.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * target-globals.c: Moved to... * target-globals.cc: ...here. * targhooks.c: Moved to... * targhooks.cc: ...here. * timevar.c: Moved to... * timevar.cc: ...here. * toplev.c: Moved to... * toplev.cc: ...here. * tracer.c: Moved to... * tracer.cc: ...here. * trans-mem.c: Moved to... * trans-mem.cc: ...here. * tree-affine.c: Moved to... * tree-affine.cc: ...here. * tree-call-cdce.c: Moved to... * tree-call-cdce.cc: ...here. * tree-cfg.c: Moved to... * tree-cfg.cc: ...here. * tree-cfgcleanup.c: Moved to... * tree-cfgcleanup.cc: ...here. * tree-chrec.c: Moved to... * tree-chrec.cc: ...here. * tree-complex.c: Moved to... * tree-complex.cc: ...here. * tree-data-ref.c: Moved to... * tree-data-ref.cc: ...here. * tree-dfa.c: Moved to... * tree-dfa.cc: ...here. * tree-diagnostic.c: Moved to... * tree-diagnostic.cc: ...here. * tree-dump.c: Moved to... * tree-dump.cc: ...here. * tree-eh.c: Moved to... * tree-eh.cc: ...here. * tree-emutls.c: Moved to... * tree-emutls.cc: ...here. * tree-if-conv.c: Moved to... * tree-if-conv.cc: ...here. * tree-inline.c: Moved to... * tree-inline.cc: ...here. * tree-into-ssa.c: Moved to... * tree-into-ssa.cc: ...here. * tree-iterator.c: Moved to... * tree-iterator.cc: ...here. * tree-loop-distribution.c: Moved to... * tree-loop-distribution.cc: ...here. * tree-nested.c: Moved to... * tree-nested.cc: ...here. * tree-nrv.c: Moved to... * tree-nrv.cc: ...here. * tree-object-size.c: Moved to... * tree-object-size.cc: ...here. * tree-outof-ssa.c: Moved to... * tree-outof-ssa.cc: ...here. * tree-parloops.c: Moved to... * tree-parloops.cc: ...here. * tree-phinodes.c: Moved to... * tree-phinodes.cc: ...here. * tree-predcom.c: Moved to... * tree-predcom.cc: ...here. * tree-pretty-print.c: Moved to... * tree-pretty-print.cc: ...here. * tree-profile.c: Moved to... * tree-profile.cc: ...here. * tree-scalar-evolution.c: Moved to... * tree-scalar-evolution.cc: ...here. * tree-sra.c: Moved to... * tree-sra.cc: ...here. * tree-ssa-address.c: Moved to... * tree-ssa-address.cc: ...here. * tree-ssa-alias.c: Moved to... * tree-ssa-alias.cc: ...here. * tree-ssa-ccp.c: Moved to... * tree-ssa-ccp.cc: ...here. * tree-ssa-coalesce.c: Moved to... * tree-ssa-coalesce.cc: ...here. * tree-ssa-copy.c: Moved to... * tree-ssa-copy.cc: ...here. * tree-ssa-dce.c: Moved to... * tree-ssa-dce.cc: ...here. * tree-ssa-dom.c: Moved to... * tree-ssa-dom.cc: ...here. * tree-ssa-dse.c: Moved to... * tree-ssa-dse.cc: ...here. * tree-ssa-forwprop.c: Moved to... * tree-ssa-forwprop.cc: ...here. * tree-ssa-ifcombine.c: Moved to... * tree-ssa-ifcombine.cc: ...here. * tree-ssa-live.c: Moved to... * tree-ssa-live.cc: ...here. * tree-ssa-loop-ch.c: Moved to... * tree-ssa-loop-ch.cc: ...here. * tree-ssa-loop-im.c: Moved to... * tree-ssa-loop-im.cc: ...here. * tree-ssa-loop-ivcanon.c: Moved to... * tree-ssa-loop-ivcanon.cc: ...here. * tree-ssa-loop-ivopts.c: Moved to... * tree-ssa-loop-ivopts.cc: ...here. * tree-ssa-loop-manip.c: Moved to... * tree-ssa-loop-manip.cc: ...here. * tree-ssa-loop-niter.c: Moved to... * tree-ssa-loop-niter.cc: ...here. * tree-ssa-loop-prefetch.c: Moved to... * tree-ssa-loop-prefetch.cc: ...here. * tree-ssa-loop-split.c: Moved to... * tree-ssa-loop-split.cc: ...here. * tree-ssa-loop-unswitch.c: Moved to... * tree-ssa-loop-unswitch.cc: ...here. * tree-ssa-loop.c: Moved to... * tree-ssa-loop.cc: ...here. * tree-ssa-math-opts.c: Moved to... * tree-ssa-math-opts.cc: ...here. * tree-ssa-operands.c: Moved to... * tree-ssa-operands.cc: ...here. * tree-ssa-phiopt.c: Moved to... * tree-ssa-phiopt.cc: ...here. * tree-ssa-phiprop.c: Moved to... * tree-ssa-phiprop.cc: ...here. * tree-ssa-pre.c: Moved to... * tree-ssa-pre.cc: ...here. * tree-ssa-propagate.c: Moved to... * tree-ssa-propagate.cc: ...here. * tree-ssa-reassoc.c: Moved to... * tree-ssa-reassoc.cc: ...here. * tree-ssa-sccvn.c: Moved to... * tree-ssa-sccvn.cc: ...here. * tree-ssa-scopedtables.c: Moved to... * tree-ssa-scopedtables.cc: ...here. * tree-ssa-sink.c: Moved to... * tree-ssa-sink.cc: ...here. * tree-ssa-strlen.c: Moved to... * tree-ssa-strlen.cc: ...here. * tree-ssa-structalias.c: Moved to... * tree-ssa-structalias.cc: ...here. * tree-ssa-tail-merge.c: Moved to... * tree-ssa-tail-merge.cc: ...here. * tree-ssa-ter.c: Moved to... * tree-ssa-ter.cc: ...here. * tree-ssa-threadbackward.c: Moved to... * tree-ssa-threadbackward.cc: ...here. * tree-ssa-threadedge.c: Moved to... * tree-ssa-threadedge.cc: ...here. * tree-ssa-threadupdate.c: Moved to... * tree-ssa-threadupdate.cc: ...here. * tree-ssa-uncprop.c: Moved to... * tree-ssa-uncprop.cc: ...here. * tree-ssa-uninit.c: Moved to... * tree-ssa-uninit.cc: ...here. * tree-ssa.c: Moved to... * tree-ssa.cc: ...here. * tree-ssanames.c: Moved to... * tree-ssanames.cc: ...here. * tree-stdarg.c: Moved to... * tree-stdarg.cc: ...here. * tree-streamer-in.c: Moved to... * tree-streamer-in.cc: ...here. * tree-streamer-out.c: Moved to... * tree-streamer-out.cc: ...here. * tree-streamer.c: Moved to... * tree-streamer.cc: ...here. * tree-switch-conversion.c: Moved to... * tree-switch-conversion.cc: ...here. * tree-tailcall.c: Moved to... * tree-tailcall.cc: ...here. * tree-vect-data-refs.c: Moved to... * tree-vect-data-refs.cc: ...here. * tree-vect-generic.c: Moved to... * tree-vect-generic.cc: ...here. * tree-vect-loop-manip.c: Moved to... * tree-vect-loop-manip.cc: ...here. * tree-vect-loop.c: Moved to... * tree-vect-loop.cc: ...here. * tree-vect-patterns.c: Moved to... * tree-vect-patterns.cc: ...here. * tree-vect-slp-patterns.c: Moved to... * tree-vect-slp-patterns.cc: ...here. * tree-vect-slp.c: Moved to... * tree-vect-slp.cc: ...here. * tree-vect-stmts.c: Moved to... * tree-vect-stmts.cc: ...here. * tree-vector-builder.c: Moved to... * tree-vector-builder.cc: ...here. * tree-vectorizer.c: Moved to... * tree-vectorizer.cc: ...here. * tree-vrp.c: Moved to... * tree-vrp.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * tsan.c: Moved to... * tsan.cc: ...here. * typed-splay-tree.c: Moved to... * typed-splay-tree.cc: ...here. * ubsan.c: Moved to... * ubsan.cc: ...here. * valtrack.c: Moved to... * valtrack.cc: ...here. * value-prof.c: Moved to... * value-prof.cc: ...here. * var-tracking.c: Moved to... * var-tracking.cc: ...here. * varasm.c: Moved to... * varasm.cc: ...here. * varpool.c: Moved to... * varpool.cc: ...here. * vec-perm-indices.c: Moved to... * vec-perm-indices.cc: ...here. * vec.c: Moved to... * vec.cc: ...here. * vmsdbgout.c: Moved to... * vmsdbgout.cc: ...here. * vr-values.c: Moved to... * vr-values.cc: ...here. * vtable-verify.c: Moved to... * vtable-verify.cc: ...here. * web.c: Moved to... * web.cc: ...here. * xcoffout.c: Moved to... * xcoffout.cc: ...here. gcc/c-family/ChangeLog: * c-ada-spec.c: Moved to... * c-ada-spec.cc: ...here. * c-attribs.c: Moved to... * c-attribs.cc: ...here. * c-common.c: Moved to... * c-common.cc: ...here. * c-cppbuiltin.c: Moved to... * c-cppbuiltin.cc: ...here. * c-dump.c: Moved to... * c-dump.cc: ...here. * c-format.c: Moved to... * c-format.cc: ...here. * c-gimplify.c: Moved to... * c-gimplify.cc: ...here. * c-indentation.c: Moved to... * c-indentation.cc: ...here. * c-lex.c: Moved to... * c-lex.cc: ...here. * c-omp.c: Moved to... * c-omp.cc: ...here. * c-opts.c: Moved to... * c-opts.cc: ...here. * c-pch.c: Moved to... * c-pch.cc: ...here. * c-ppoutput.c: Moved to... * c-ppoutput.cc: ...here. * c-pragma.c: Moved to... * c-pragma.cc: ...here. * c-pretty-print.c: Moved to... * c-pretty-print.cc: ...here. * c-semantics.c: Moved to... * c-semantics.cc: ...here. * c-ubsan.c: Moved to... * c-ubsan.cc: ...here. * c-warn.c: Moved to... * c-warn.cc: ...here. * cppspec.c: Moved to... * cppspec.cc: ...here. * stub-objc.c: Moved to... * stub-objc.cc: ...here. gcc/c/ChangeLog: * c-aux-info.c: Moved to... * c-aux-info.cc: ...here. * c-convert.c: Moved to... * c-convert.cc: ...here. * c-decl.c: Moved to... * c-decl.cc: ...here. * c-errors.c: Moved to... * c-errors.cc: ...here. * c-fold.c: Moved to... * c-fold.cc: ...here. * c-lang.c: Moved to... * c-lang.cc: ...here. * c-objc-common.c: Moved to... * c-objc-common.cc: ...here. * c-parser.c: Moved to... * c-parser.cc: ...here. * c-typeck.c: Moved to... * c-typeck.cc: ...here. * gccspec.c: Moved to... * gccspec.cc: ...here. * gimple-parser.c: Moved to... * gimple-parser.cc: ...here. gcc/cp/ChangeLog: * call.c: Moved to... * call.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constexpr.c: Moved to... * constexpr.cc: ...here. * cp-gimplify.c: Moved to... * cp-gimplify.cc: ...here. * cp-lang.c: Moved to... * cp-lang.cc: ...here. * cp-objcp-common.c: Moved to... * cp-objcp-common.cc: ...here. * cp-ubsan.c: Moved to... * cp-ubsan.cc: ...here. * cvt.c: Moved to... * cvt.cc: ...here. * cxx-pretty-print.c: Moved to... * cxx-pretty-print.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * decl2.c: Moved to... * decl2.cc: ...here. * dump.c: Moved to... * dump.cc: ...here. * error.c: Moved to... * error.cc: ...here. * except.c: Moved to... * except.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * friend.c: Moved to... * friend.cc: ...here. * g++spec.c: Moved to... * g++spec.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lambda.c: Moved to... * lambda.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * mangle.c: Moved to... * mangle.cc: ...here. * method.c: Moved to... * method.cc: ...here. * name-lookup.c: Moved to... * name-lookup.cc: ...here. * optimize.c: Moved to... * optimize.cc: ...here. * parser.c: Moved to... * parser.cc: ...here. * pt.c: Moved to... * pt.cc: ...here. * ptree.c: Moved to... * ptree.cc: ...here. * rtti.c: Moved to... * rtti.cc: ...here. * search.c: Moved to... * search.cc: ...here. * semantics.c: Moved to... * semantics.cc: ...here. * tree.c: Moved to... * tree.cc: ...here. * typeck.c: Moved to... * typeck.cc: ...here. * typeck2.c: Moved to... * typeck2.cc: ...here. * vtable-class-hierarchy.c: Moved to... * vtable-class-hierarchy.cc: ...here. gcc/fortran/ChangeLog: * arith.c: Moved to... * arith.cc: ...here. * array.c: Moved to... * array.cc: ...here. * bbt.c: Moved to... * bbt.cc: ...here. * check.c: Moved to... * check.cc: ...here. * class.c: Moved to... * class.cc: ...here. * constructor.c: Moved to... * constructor.cc: ...here. * convert.c: Moved to... * convert.cc: ...here. * cpp.c: Moved to... * cpp.cc: ...here. * data.c: Moved to... * data.cc: ...here. * decl.c: Moved to... * decl.cc: ...here. * dependency.c: Moved to... * dependency.cc: ...here. * dump-parse-tree.c: Moved to... * dump-parse-tree.cc: ...here. * error.c: Moved to... * error.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * f95-lang.c: Moved to... * f95-lang.cc: ...here. * frontend-passes.c: Moved to... * frontend-passes.cc: ...here. * gfortranspec.c: Moved to... * gfortranspec.cc: ...here. * interface.c: Moved to... * interface.cc: ...here. * intrinsic.c: Moved to... * intrinsic.cc: ...here. * io.c: Moved to... * io.cc: ...here. * iresolve.c: Moved to... * iresolve.cc: ...here. * match.c: Moved to... * match.cc: ...here. * matchexp.c: Moved to... * matchexp.cc: ...here. * misc.c: Moved to... * misc.cc: ...here. * module.c: Moved to... * module.cc: ...here. * openmp.c: Moved to... * openmp.cc: ...here. * options.c: Moved to... * options.cc: ...here. * parse.c: Moved to... * parse.cc: ...here. * primary.c: Moved to... * primary.cc: ...here. * resolve.c: Moved to... * resolve.cc: ...here. * scanner.c: Moved to... * scanner.cc: ...here. * simplify.c: Moved to... * simplify.cc: ...here. * st.c: Moved to... * st.cc: ...here. * symbol.c: Moved to... * symbol.cc: ...here. * target-memory.c: Moved to... * target-memory.cc: ...here. * trans-array.c: Moved to... * trans-array.cc: ...here. * trans-common.c: Moved to... * trans-common.cc: ...here. * trans-const.c: Moved to... * trans-const.cc: ...here. * trans-decl.c: Moved to... * trans-decl.cc: ...here. * trans-expr.c: Moved to... * trans-expr.cc: ...here. * trans-intrinsic.c: Moved to... * trans-intrinsic.cc: ...here. * trans-io.c: Moved to... * trans-io.cc: ...here. * trans-openmp.c: Moved to... * trans-openmp.cc: ...here. * trans-stmt.c: Moved to... * trans-stmt.cc: ...here. * trans-types.c: Moved to... * trans-types.cc: ...here. * trans.c: Moved to... * trans.cc: ...here. gcc/go/ChangeLog: * go-backend.c: Moved to... * go-backend.cc: ...here. * go-lang.c: Moved to... * go-lang.cc: ...here. * gospec.c: Moved to... * gospec.cc: ...here. gcc/jit/ChangeLog: * dummy-frontend.c: Moved to... * dummy-frontend.cc: ...here. * jit-builtins.c: Moved to... * jit-builtins.cc: ...here. * jit-logging.c: Moved to... * jit-logging.cc: ...here. * jit-playback.c: Moved to... * jit-playback.cc: ...here. * jit-recording.c: Moved to... * jit-recording.cc: ...here. * jit-result.c: Moved to... * jit-result.cc: ...here. * jit-spec.c: Moved to... * jit-spec.cc: ...here. * jit-tempdir.c: Moved to... * jit-tempdir.cc: ...here. * jit-w32.c: Moved to... * jit-w32.cc: ...here. * libgccjit.c: Moved to... * libgccjit.cc: ...here. gcc/lto/ChangeLog: * common.c: Moved to... * common.cc: ...here. * lto-common.c: Moved to... * lto-common.cc: ...here. * lto-dump.c: Moved to... * lto-dump.cc: ...here. * lto-lang.c: Moved to... * lto-lang.cc: ...here. * lto-object.c: Moved to... * lto-object.cc: ...here. * lto-partition.c: Moved to... * lto-partition.cc: ...here. * lto-symtab.c: Moved to... * lto-symtab.cc: ...here. * lto.c: Moved to... * lto.cc: ...here. gcc/objc/ChangeLog: * objc-act.c: Moved to... * objc-act.cc: ...here. * objc-encoding.c: Moved to... * objc-encoding.cc: ...here. * objc-gnu-runtime-abi-01.c: Moved to... * objc-gnu-runtime-abi-01.cc: ...here. * objc-lang.c: Moved to... * objc-lang.cc: ...here. * objc-map.c: Moved to... * objc-map.cc: ...here. * objc-next-runtime-abi-01.c: Moved to... * objc-next-runtime-abi-01.cc: ...here. * objc-next-runtime-abi-02.c: Moved to... * objc-next-runtime-abi-02.cc: ...here. * objc-runtime-shared-support.c: Moved to... * objc-runtime-shared-support.cc: ...here. gcc/objcp/ChangeLog: * objcp-decl.c: Moved to... * objcp-decl.cc: ...here. * objcp-lang.c: Moved to... * objcp-lang.cc: ...here. libcpp/ChangeLog: * charset.c: Moved to... * charset.cc: ...here. * directives.c: Moved to... * directives.cc: ...here. * errors.c: Moved to... * errors.cc: ...here. * expr.c: Moved to... * expr.cc: ...here. * files.c: Moved to... * files.cc: ...here. * identifiers.c: Moved to... * identifiers.cc: ...here. * init.c: Moved to... * init.cc: ...here. * lex.c: Moved to... * lex.cc: ...here. * line-map.c: Moved to... * line-map.cc: ...here. * macro.c: Moved to... * macro.cc: ...here. * makeucnid.c: Moved to... * makeucnid.cc: ...here. * mkdeps.c: Moved to... * mkdeps.cc: ...here. * pch.c: Moved to... * pch.cc: ...here. * symtab.c: Moved to... * symtab.cc: ...here. * traditional.c: Moved to... * traditional.cc: ...here.
Diffstat (limited to 'gcc/cp/call.cc')
-rw-r--r--gcc/cp/call.cc13272
1 files changed, 13272 insertions, 0 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
new file mode 100644
index 0000000..d4a07a7
--- /dev/null
+++ b/gcc/cp/call.cc
@@ -0,0 +1,13272 @@
+/* Functions related to invoking -*- C++ -*- methods and overloaded functions.
+ Copyright (C) 1987-2022 Free Software Foundation, Inc.
+ Contributed by Michael Tiemann (tiemann@cygnus.com) and
+ modified by Brendan Kehoe (brendan@cygnus.com).
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+
+/* High-level class interface. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "cp-tree.h"
+#include "timevar.h"
+#include "stringpool.h"
+#include "cgraph.h"
+#include "stor-layout.h"
+#include "trans-mem.h"
+#include "flags.h"
+#include "toplev.h"
+#include "intl.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "c-family/c-objc.h"
+#include "internal-fn.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "gcc-rich-location.h"
+
+/* The various kinds of conversion. */
+
+enum conversion_kind {
+ ck_identity,
+ ck_lvalue,
+ ck_fnptr,
+ ck_qual,
+ ck_std,
+ ck_ptr,
+ ck_pmem,
+ ck_base,
+ ck_ref_bind,
+ ck_user,
+ ck_ambig,
+ ck_list,
+ ck_aggr,
+ ck_rvalue
+};
+
+/* The rank of the conversion. Order of the enumerals matters; better
+ conversions should come earlier in the list. */
+
+enum conversion_rank {
+ cr_identity,
+ cr_exact,
+ cr_promotion,
+ cr_std,
+ cr_pbool,
+ cr_user,
+ cr_ellipsis,
+ cr_bad
+};
+
+/* An implicit conversion sequence, in the sense of [over.best.ics].
+ The first conversion to be performed is at the end of the chain.
+ That conversion is always a cr_identity conversion. */
+
+struct conversion {
+ /* The kind of conversion represented by this step. */
+ conversion_kind kind;
+ /* The rank of this conversion. */
+ conversion_rank rank;
+ BOOL_BITFIELD user_conv_p : 1;
+ BOOL_BITFIELD ellipsis_p : 1;
+ BOOL_BITFIELD this_p : 1;
+ /* True if this conversion would be permitted with a bending of
+ language standards, e.g. disregarding pointer qualifiers or
+ converting integers to pointers. */
+ BOOL_BITFIELD bad_p : 1;
+ /* If KIND is ck_ref_bind or ck_base, true to indicate that a
+ temporary should be created to hold the result of the
+ conversion. If KIND is ck_ambig or ck_user, true means force
+ copy-initialization. */
+ BOOL_BITFIELD need_temporary_p : 1;
+ /* If KIND is ck_ptr or ck_pmem, true to indicate that a conversion
+ from a pointer-to-derived to pointer-to-base is being performed. */
+ BOOL_BITFIELD base_p : 1;
+ /* If KIND is ck_ref_bind, true when either an lvalue reference is
+ being bound to an lvalue expression or an rvalue reference is
+ being bound to an rvalue expression. If KIND is ck_rvalue or ck_base,
+ true when we are treating an lvalue as an rvalue (12.8p33). If
+ ck_identity, we will be binding a reference directly or decaying to
+ a pointer. */
+ BOOL_BITFIELD rvaluedness_matches_p: 1;
+ BOOL_BITFIELD check_narrowing: 1;
+ /* Whether check_narrowing should only check TREE_CONSTANTs; used
+ in build_converted_constant_expr. */
+ BOOL_BITFIELD check_narrowing_const_only: 1;
+ /* True if this conversion is taking place in a copy-initialization context
+ and we should only consider converting constructors. Only set in
+ ck_base and ck_rvalue. */
+ BOOL_BITFIELD copy_init_p : 1;
+ /* The type of the expression resulting from the conversion. */
+ tree type;
+ union {
+ /* The next conversion in the chain. Since the conversions are
+ arranged from outermost to innermost, the NEXT conversion will
+ actually be performed before this conversion. This variant is
+ used only when KIND is neither ck_identity, ck_aggr, ck_ambig nor
+ ck_list. Please use the next_conversion function instead
+ of using this field directly. */
+ conversion *next;
+ /* The expression at the beginning of the conversion chain. This
+ variant is used only if KIND is ck_identity, ck_aggr, or ck_ambig.
+ You can use conv_get_original_expr to get this expression. */
+ tree expr;
+ /* The array of conversions for an initializer_list, so this
+ variant is used only when KIN D is ck_list. */
+ conversion **list;
+ } u;
+ /* The function candidate corresponding to this conversion
+ sequence. This field is only used if KIND is ck_user. */
+ struct z_candidate *cand;
+};
+
+#define CONVERSION_RANK(NODE) \
+ ((NODE)->bad_p ? cr_bad \
+ : (NODE)->ellipsis_p ? cr_ellipsis \
+ : (NODE)->user_conv_p ? cr_user \
+ : (NODE)->rank)
+
+#define BAD_CONVERSION_RANK(NODE) \
+ ((NODE)->ellipsis_p ? cr_ellipsis \
+ : (NODE)->user_conv_p ? cr_user \
+ : (NODE)->rank)
+
+static struct obstack conversion_obstack;
+static bool conversion_obstack_initialized;
+struct rejection_reason;
+
+static struct z_candidate * tourney (struct z_candidate *, tsubst_flags_t);
+static int equal_functions (tree, tree);
+static int joust (struct z_candidate *, struct z_candidate *, bool,
+ tsubst_flags_t);
+static int compare_ics (conversion *, conversion *);
+static void maybe_warn_class_memaccess (location_t, tree,
+ const vec<tree, va_gc> *);
+static tree build_over_call (struct z_candidate *, int, tsubst_flags_t);
+static tree convert_like (conversion *, tree, tsubst_flags_t);
+static tree convert_like_with_context (conversion *, tree, tree, int,
+ tsubst_flags_t);
+static void op_error (const op_location_t &, enum tree_code, enum tree_code,
+ tree, tree, tree, bool);
+static struct z_candidate *build_user_type_conversion_1 (tree, tree, int,
+ tsubst_flags_t);
+static void print_z_candidate (location_t, const char *, struct z_candidate *);
+static void print_z_candidates (location_t, struct z_candidate *);
+static tree build_this (tree);
+static struct z_candidate *splice_viable (struct z_candidate *, bool, bool *);
+static bool any_strictly_viable (struct z_candidate *);
+static struct z_candidate *add_template_candidate
+ (struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
+ tree, tree, tree, int, unification_kind_t, bool, tsubst_flags_t);
+static struct z_candidate *add_template_candidate_real
+ (struct z_candidate **, tree, tree, tree, tree, const vec<tree, va_gc> *,
+ tree, tree, tree, int, tree, unification_kind_t, bool, tsubst_flags_t);
+static bool is_complete (tree);
+static struct z_candidate *add_conv_candidate
+ (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, tree,
+ tree, tsubst_flags_t);
+static struct z_candidate *add_function_candidate
+ (struct z_candidate **, tree, tree, tree, const vec<tree, va_gc> *, tree,
+ tree, int, conversion**, bool, tsubst_flags_t);
+static conversion *implicit_conversion (tree, tree, tree, bool, int,
+ tsubst_flags_t);
+static conversion *reference_binding (tree, tree, tree, bool, int,
+ tsubst_flags_t);
+static conversion *build_conv (conversion_kind, tree, conversion *);
+static conversion *build_list_conv (tree, tree, int, tsubst_flags_t);
+static conversion *next_conversion (conversion *);
+static bool is_subseq (conversion *, conversion *);
+static conversion *maybe_handle_ref_bind (conversion **);
+static void maybe_handle_implicit_object (conversion **);
+static struct z_candidate *add_candidate
+ (struct z_candidate **, tree, tree, const vec<tree, va_gc> *, size_t,
+ conversion **, tree, tree, int, struct rejection_reason *, int);
+static tree source_type (conversion *);
+static void add_warning (struct z_candidate *, struct z_candidate *);
+static conversion *direct_reference_binding (tree, conversion *);
+static bool promoted_arithmetic_type_p (tree);
+static conversion *conditional_conversion (tree, tree, tsubst_flags_t);
+static char *name_as_c_string (tree, tree, bool *);
+static tree prep_operand (tree);
+static void add_candidates (tree, tree, const vec<tree, va_gc> *, tree, tree,
+ bool, tree, tree, int, struct z_candidate **,
+ tsubst_flags_t);
+static conversion *merge_conversion_sequences (conversion *, conversion *);
+static tree build_temp (tree, tree, int, diagnostic_t *, tsubst_flags_t);
+static conversion *build_identity_conv (tree, tree);
+static inline bool conv_binds_to_array_of_unknown_bound (conversion *);
+static bool conv_is_prvalue (conversion *);
+static tree prevent_lifetime_extension (tree);
+
+/* Returns nonzero iff the destructor name specified in NAME matches BASETYPE.
+ NAME can take many forms... */
+
+bool
+check_dtor_name (tree basetype, tree name)
+{
+ /* Just accept something we've already complained about. */
+ if (name == error_mark_node)
+ return true;
+
+ if (TREE_CODE (name) == TYPE_DECL)
+ name = TREE_TYPE (name);
+ else if (TYPE_P (name))
+ /* OK */;
+ else if (identifier_p (name))
+ {
+ if ((MAYBE_CLASS_TYPE_P (basetype)
+ || TREE_CODE (basetype) == ENUMERAL_TYPE)
+ && name == constructor_name (basetype))
+ return true;
+
+ /* Otherwise lookup the name, it could be an unrelated typedef
+ of the correct type. */
+ name = lookup_name (name, LOOK_want::TYPE);
+ if (!name)
+ return false;
+ name = TREE_TYPE (name);
+ if (name == error_mark_node)
+ return false;
+ }
+ else
+ {
+ /* In the case of:
+
+ template <class T> struct S { ~S(); };
+ int i;
+ i.~S();
+
+ NAME will be a class template. */
+ gcc_assert (DECL_CLASS_TEMPLATE_P (name));
+ return false;
+ }
+
+ return same_type_p (TYPE_MAIN_VARIANT (basetype), TYPE_MAIN_VARIANT (name));
+}
+
+/* We want the address of a function or method. We avoid creating a
+ pointer-to-member function. */
+
+tree
+build_addr_func (tree function, tsubst_flags_t complain)
+{
+ tree type = TREE_TYPE (function);
+
+ /* We have to do these by hand to avoid real pointer to member
+ functions. */
+ if (TREE_CODE (type) == METHOD_TYPE)
+ {
+ if (TREE_CODE (function) == OFFSET_REF)
+ {
+ tree object = build_address (TREE_OPERAND (function, 0));
+ return get_member_function_from_ptrfunc (&object,
+ TREE_OPERAND (function, 1),
+ complain);
+ }
+ function = build_address (function);
+ }
+ else if (TREE_CODE (function) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (function))
+ function = build_address (function);
+ else
+ function = decay_conversion (function, complain, /*reject_builtin=*/false);
+
+ return function;
+}
+
+/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or
+ POINTER_TYPE to those. Note, pointer to member function types
+ (TYPE_PTRMEMFUNC_P) must be handled by our callers. There are
+ two variants. build_call_a is the primitive taking an array of
+ arguments, while build_call_n is a wrapper that handles varargs. */
+
+tree
+build_call_n (tree function, int n, ...)
+{
+ if (n == 0)
+ return build_call_a (function, 0, NULL);
+ else
+ {
+ tree *argarray = XALLOCAVEC (tree, n);
+ va_list ap;
+ int i;
+
+ va_start (ap, n);
+ for (i = 0; i < n; i++)
+ argarray[i] = va_arg (ap, tree);
+ va_end (ap);
+ return build_call_a (function, n, argarray);
+ }
+}
+
+/* Update various flags in cfun and the call itself based on what is being
+ called. Split out of build_call_a so that bot_manip can use it too. */
+
+void
+set_flags_from_callee (tree call)
+{
+ /* Handle both CALL_EXPRs and AGGR_INIT_EXPRs. */
+ tree decl = cp_get_callee_fndecl_nofold (call);
+
+ /* We check both the decl and the type; a function may be known not to
+ throw without being declared throw(). */
+ bool nothrow = decl && TREE_NOTHROW (decl);
+ tree callee = cp_get_callee (call);
+ if (callee)
+ nothrow |= TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (callee)));
+ else if (TREE_CODE (call) == CALL_EXPR
+ && internal_fn_flags (CALL_EXPR_IFN (call)) & ECF_NOTHROW)
+ nothrow = true;
+
+ if (cfun && cp_function_chain && !cp_unevaluated_operand)
+ {
+ if (!nothrow && at_function_scope_p ())
+ cp_function_chain->can_throw = 1;
+
+ if (decl && TREE_THIS_VOLATILE (decl))
+ current_function_returns_abnormally = 1;
+ }
+
+ TREE_NOTHROW (call) = nothrow;
+}
+
+tree
+build_call_a (tree function, int n, tree *argarray)
+{
+ tree decl;
+ tree result_type;
+ tree fntype;
+ int i;
+
+ function = build_addr_func (function, tf_warning_or_error);
+
+ gcc_assert (TYPE_PTR_P (TREE_TYPE (function)));
+ fntype = TREE_TYPE (TREE_TYPE (function));
+ gcc_assert (FUNC_OR_METHOD_TYPE_P (fntype));
+ result_type = TREE_TYPE (fntype);
+ /* An rvalue has no cv-qualifiers. */
+ if (SCALAR_TYPE_P (result_type) || VOID_TYPE_P (result_type))
+ result_type = cv_unqualified (result_type);
+
+ function = build_call_array_loc (input_location,
+ result_type, function, n, argarray);
+ set_flags_from_callee (function);
+
+ decl = get_callee_fndecl (function);
+
+ if (decl && !TREE_USED (decl))
+ {
+ /* We invoke build_call directly for several library
+ functions. These may have been declared normally if
+ we're building libgcc, so we can't just check
+ DECL_ARTIFICIAL. */
+ gcc_assert (DECL_ARTIFICIAL (decl)
+ || !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)),
+ "__", 2));
+ mark_used (decl);
+ }
+
+ require_complete_eh_spec_types (fntype, decl);
+
+ TREE_HAS_CONSTRUCTOR (function) = (decl && DECL_CONSTRUCTOR_P (decl));
+
+ /* Don't pass empty class objects by value. This is useful
+ for tags in STL, which are used to control overload resolution.
+ We don't need to handle other cases of copying empty classes. */
+ if (!decl || !fndecl_built_in_p (decl))
+ for (i = 0; i < n; i++)
+ {
+ tree arg = CALL_EXPR_ARG (function, i);
+ if (is_empty_class (TREE_TYPE (arg))
+ && simple_empty_class_p (TREE_TYPE (arg), arg, INIT_EXPR))
+ {
+ while (TREE_CODE (arg) == TARGET_EXPR)
+ /* We're disconnecting the initializer from its target,
+ don't create a temporary. */
+ arg = TARGET_EXPR_INITIAL (arg);
+ tree t = build0 (EMPTY_CLASS_EXPR, TREE_TYPE (arg));
+ arg = build2 (COMPOUND_EXPR, TREE_TYPE (t), arg, t);
+ CALL_EXPR_ARG (function, i) = arg;
+ }
+ }
+
+ return function;
+}
+
+/* New overloading code. */
+
+struct z_candidate;
+
+struct candidate_warning {
+ z_candidate *loser;
+ candidate_warning *next;
+};
+
+/* Information for providing diagnostics about why overloading failed. */
+
+enum rejection_reason_code {
+ rr_none,
+ rr_arity,
+ rr_explicit_conversion,
+ rr_template_conversion,
+ rr_arg_conversion,
+ rr_bad_arg_conversion,
+ rr_template_unification,
+ rr_invalid_copy,
+ rr_inherited_ctor,
+ rr_constraint_failure
+};
+
+struct conversion_info {
+ /* The index of the argument, 0-based. */
+ int n_arg;
+ /* The actual argument or its type. */
+ tree from;
+ /* The type of the parameter. */
+ tree to_type;
+ /* The location of the argument. */
+ location_t loc;
+};
+
+struct rejection_reason {
+ enum rejection_reason_code code;
+ union {
+ /* Information about an arity mismatch. */
+ struct {
+ /* The expected number of arguments. */
+ int expected;
+ /* The actual number of arguments in the call. */
+ int actual;
+ /* Whether EXPECTED should be treated as a lower bound. */
+ bool least_p;
+ } arity;
+ /* Information about an argument conversion mismatch. */
+ struct conversion_info conversion;
+ /* Same, but for bad argument conversions. */
+ struct conversion_info bad_conversion;
+ /* Information about template unification failures. These are the
+ parameters passed to fn_type_unification. */
+ struct {
+ tree tmpl;
+ tree explicit_targs;
+ int num_targs;
+ const tree *args;
+ unsigned int nargs;
+ tree return_type;
+ unification_kind_t strict;
+ int flags;
+ } template_unification;
+ /* Information about template instantiation failures. These are the
+ parameters passed to instantiate_template. */
+ struct {
+ tree tmpl;
+ tree targs;
+ } template_instantiation;
+ } u;
+};
+
+struct z_candidate {
+ /* The FUNCTION_DECL that will be called if this candidate is
+ selected by overload resolution. */
+ tree fn;
+ /* If not NULL_TREE, the first argument to use when calling this
+ function. */
+ tree first_arg;
+ /* The rest of the arguments to use when calling this function. If
+ there are no further arguments this may be NULL or it may be an
+ empty vector. */
+ const vec<tree, va_gc> *args;
+ /* The implicit conversion sequences for each of the arguments to
+ FN. */
+ conversion **convs;
+ /* The number of implicit conversion sequences. */
+ size_t num_convs;
+ /* If FN is a user-defined conversion, the standard conversion
+ sequence from the type returned by FN to the desired destination
+ type. */
+ conversion *second_conv;
+ struct rejection_reason *reason;
+ /* If FN is a member function, the binfo indicating the path used to
+ qualify the name of FN at the call site. This path is used to
+ determine whether or not FN is accessible if it is selected by
+ overload resolution. The DECL_CONTEXT of FN will always be a
+ (possibly improper) base of this binfo. */
+ tree access_path;
+ /* If FN is a non-static member function, the binfo indicating the
+ subobject to which the `this' pointer should be converted if FN
+ is selected by overload resolution. The type pointed to by
+ the `this' pointer must correspond to the most derived class
+ indicated by the CONVERSION_PATH. */
+ tree conversion_path;
+ tree template_decl;
+ tree explicit_targs;
+ candidate_warning *warnings;
+ z_candidate *next;
+ int viable;
+
+ /* The flags active in add_candidate. */
+ int flags;
+
+ bool rewritten () const { return (flags & LOOKUP_REWRITTEN); }
+ bool reversed () const { return (flags & LOOKUP_REVERSED); }
+};
+
+/* Returns true iff T is a null pointer constant in the sense of
+ [conv.ptr]. */
+
+bool
+null_ptr_cst_p (tree t)
+{
+ tree type = TREE_TYPE (t);
+
+ /* [conv.ptr]
+
+ A null pointer constant is an integer literal ([lex.icon]) with value
+ zero or a prvalue of type std::nullptr_t. */
+ if (NULLPTR_TYPE_P (type))
+ return true;
+
+ if (cxx_dialect >= cxx11)
+ {
+ STRIP_ANY_LOCATION_WRAPPER (t);
+
+ /* Core issue 903 says only literal 0 is a null pointer constant. */
+ if (TREE_CODE (t) == INTEGER_CST
+ && !TREE_OVERFLOW (t)
+ && TREE_CODE (type) == INTEGER_TYPE
+ && integer_zerop (t)
+ && !char_type_p (type))
+ return true;
+ }
+ else if (CP_INTEGRAL_TYPE_P (type))
+ {
+ t = fold_non_dependent_expr (t, tf_none);
+ STRIP_NOPS (t);
+ if (integer_zerop (t) && !TREE_OVERFLOW (t))
+ return true;
+ }
+
+ return false;
+}
+
+/* Returns true iff T is a null member pointer value (4.11). */
+
+bool
+null_member_pointer_value_p (tree t)
+{
+ tree type = TREE_TYPE (t);
+ if (!type)
+ return false;
+ else if (TYPE_PTRMEMFUNC_P (type))
+ return (TREE_CODE (t) == CONSTRUCTOR
+ && CONSTRUCTOR_NELTS (t)
+ && integer_zerop (CONSTRUCTOR_ELT (t, 0)->value));
+ else if (TYPE_PTRDATAMEM_P (type))
+ return integer_all_onesp (t);
+ else
+ return false;
+}
+
+/* Returns nonzero if PARMLIST consists of only default parms,
+ ellipsis, and/or undeduced parameter packs. */
+
+bool
+sufficient_parms_p (const_tree parmlist)
+{
+ for (; parmlist && parmlist != void_list_node;
+ parmlist = TREE_CHAIN (parmlist))
+ if (!TREE_PURPOSE (parmlist)
+ && !PACK_EXPANSION_P (TREE_VALUE (parmlist)))
+ return false;
+ return true;
+}
+
+/* Allocate N bytes of memory from the conversion obstack. The memory
+ is zeroed before being returned. */
+
+static void *
+conversion_obstack_alloc (size_t n)
+{
+ void *p;
+ if (!conversion_obstack_initialized)
+ {
+ gcc_obstack_init (&conversion_obstack);
+ conversion_obstack_initialized = true;
+ }
+ p = obstack_alloc (&conversion_obstack, n);
+ memset (p, 0, n);
+ return p;
+}
+
+/* Allocate rejection reasons. */
+
+static struct rejection_reason *
+alloc_rejection (enum rejection_reason_code code)
+{
+ struct rejection_reason *p;
+ p = (struct rejection_reason *) conversion_obstack_alloc (sizeof *p);
+ p->code = code;
+ return p;
+}
+
+static struct rejection_reason *
+arity_rejection (tree first_arg, int expected, int actual, bool least_p = false)
+{
+ struct rejection_reason *r = alloc_rejection (rr_arity);
+ int adjust = first_arg != NULL_TREE;
+ r->u.arity.expected = expected - adjust;
+ r->u.arity.actual = actual - adjust;
+ r->u.arity.least_p = least_p;
+ return r;
+}
+
+static struct rejection_reason *
+arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to,
+ location_t loc)
+{
+ struct rejection_reason *r = alloc_rejection (rr_arg_conversion);
+ int adjust = first_arg != NULL_TREE;
+ r->u.conversion.n_arg = n_arg - adjust;
+ r->u.conversion.from = from;
+ r->u.conversion.to_type = to;
+ r->u.conversion.loc = loc;
+ return r;
+}
+
+static struct rejection_reason *
+bad_arg_conversion_rejection (tree first_arg, int n_arg, tree from, tree to,
+ location_t loc)
+{
+ struct rejection_reason *r = alloc_rejection (rr_bad_arg_conversion);
+ int adjust = first_arg != NULL_TREE;
+ r->u.bad_conversion.n_arg = n_arg - adjust;
+ r->u.bad_conversion.from = from;
+ r->u.bad_conversion.to_type = to;
+ r->u.bad_conversion.loc = loc;
+ return r;
+}
+
+static struct rejection_reason *
+explicit_conversion_rejection (tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_explicit_conversion);
+ r->u.conversion.n_arg = 0;
+ r->u.conversion.from = from;
+ r->u.conversion.to_type = to;
+ r->u.conversion.loc = UNKNOWN_LOCATION;
+ return r;
+}
+
+static struct rejection_reason *
+template_conversion_rejection (tree from, tree to)
+{
+ struct rejection_reason *r = alloc_rejection (rr_template_conversion);
+ r->u.conversion.n_arg = 0;
+ r->u.conversion.from = from;
+ r->u.conversion.to_type = to;
+ r->u.conversion.loc = UNKNOWN_LOCATION;
+ return r;
+}
+
+static struct rejection_reason *
+template_unification_rejection (tree tmpl, tree explicit_targs, tree targs,
+ const tree *args, unsigned int nargs,
+ tree return_type, unification_kind_t strict,
+ int flags)
+{
+ size_t args_n_bytes = sizeof (*args) * nargs;
+ tree *args1 = (tree *) conversion_obstack_alloc (args_n_bytes);
+ struct rejection_reason *r = alloc_rejection (rr_template_unification);
+ r->u.template_unification.tmpl = tmpl;
+ r->u.template_unification.explicit_targs = explicit_targs;
+ r->u.template_unification.num_targs = TREE_VEC_LENGTH (targs);
+ /* Copy args to our own storage. */
+ memcpy (args1, args, args_n_bytes);
+ r->u.template_unification.args = args1;
+ r->u.template_unification.nargs = nargs;
+ r->u.template_unification.return_type = return_type;
+ r->u.template_unification.strict = strict;
+ r->u.template_unification.flags = flags;
+ return r;
+}
+
+static struct rejection_reason *
+template_unification_error_rejection (void)
+{
+ return alloc_rejection (rr_template_unification);
+}
+
+static struct rejection_reason *
+invalid_copy_with_fn_template_rejection (void)
+{
+ struct rejection_reason *r = alloc_rejection (rr_invalid_copy);
+ return r;
+}
+
+static struct rejection_reason *
+inherited_ctor_rejection (void)
+{
+ struct rejection_reason *r = alloc_rejection (rr_inherited_ctor);
+ return r;
+}
+
+/* Build a constraint failure record. */
+
+static struct rejection_reason *
+constraint_failure (void)
+{
+ struct rejection_reason *r = alloc_rejection (rr_constraint_failure);
+ return r;
+}
+
+/* Dynamically allocate a conversion. */
+
+static conversion *
+alloc_conversion (conversion_kind kind)
+{
+ conversion *c;
+ c = (conversion *) conversion_obstack_alloc (sizeof (conversion));
+ c->kind = kind;
+ return c;
+}
+
+/* Make sure that all memory on the conversion obstack has been
+ freed. */
+
+void
+validate_conversion_obstack (void)
+{
+ if (conversion_obstack_initialized)
+ gcc_assert ((obstack_next_free (&conversion_obstack)
+ == obstack_base (&conversion_obstack)));
+}
+
+/* Dynamically allocate an array of N conversions. */
+
+static conversion **
+alloc_conversions (size_t n)
+{
+ return (conversion **) conversion_obstack_alloc (n * sizeof (conversion *));
+}
+
+/* True iff the active member of conversion::u for code CODE is NEXT. */
+
+static inline bool
+has_next (conversion_kind code)
+{
+ return !(code == ck_identity
+ || code == ck_ambig
+ || code == ck_list
+ || code == ck_aggr);
+}
+
+static conversion *
+build_conv (conversion_kind code, tree type, conversion *from)
+{
+ conversion *t;
+ conversion_rank rank = CONVERSION_RANK (from);
+
+ /* Only call this function for conversions that use u.next. */
+ gcc_assert (from == NULL || has_next (code));
+
+ /* Note that the caller is responsible for filling in t->cand for
+ user-defined conversions. */
+ t = alloc_conversion (code);
+ t->type = type;
+ t->u.next = from;
+
+ switch (code)
+ {
+ case ck_ptr:
+ case ck_pmem:
+ case ck_base:
+ case ck_std:
+ if (rank < cr_std)
+ rank = cr_std;
+ break;
+
+ case ck_qual:
+ case ck_fnptr:
+ if (rank < cr_exact)
+ rank = cr_exact;
+ break;
+
+ default:
+ break;
+ }
+ t->rank = rank;
+ t->user_conv_p = (code == ck_user || from->user_conv_p);
+ t->bad_p = from->bad_p;
+ t->base_p = false;
+ return t;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+ specialization of std::initializer_list<T>, if such a conversion is
+ possible. */
+
+static conversion *
+build_list_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (type), 0);
+ unsigned len = CONSTRUCTOR_NELTS (ctor);
+ conversion **subconvs = alloc_conversions (len);
+ conversion *t;
+ unsigned i;
+ tree val;
+
+ /* Within a list-initialization we can have more user-defined
+ conversions. */
+ flags &= ~LOOKUP_NO_CONVERSION;
+ /* But no narrowing conversions. */
+ flags |= LOOKUP_NO_NARROWING;
+
+ /* Can't make an array of these types. */
+ if (TYPE_REF_P (elttype)
+ || TREE_CODE (elttype) == FUNCTION_TYPE
+ || VOID_TYPE_P (elttype))
+ return NULL;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (ctor), i, val)
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (val), val,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ subconvs[i] = sub;
+ }
+
+ t = alloc_conversion (ck_list);
+ t->type = type;
+ t->u.list = subconvs;
+ t->rank = cr_exact;
+
+ for (i = 0; i < len; ++i)
+ {
+ conversion *sub = subconvs[i];
+ if (sub->rank > t->rank)
+ t->rank = sub->rank;
+ if (sub->user_conv_p)
+ t->user_conv_p = true;
+ if (sub->bad_p)
+ t->bad_p = true;
+ }
+
+ return t;
+}
+
+/* Return the next conversion of the conversion chain (if applicable),
+ or NULL otherwise. Please use this function instead of directly
+ accessing fields of struct conversion. */
+
+static conversion *
+next_conversion (conversion *conv)
+{
+ if (conv == NULL
+ || !has_next (conv->kind))
+ return NULL;
+ return conv->u.next;
+}
+
+/* Strip to the first ck_user, ck_ambig, ck_list, ck_aggr or ck_identity
+ encountered. */
+
+static conversion *
+strip_standard_conversion (conversion *conv)
+{
+ while (conv
+ && conv->kind != ck_user
+ && has_next (conv->kind))
+ conv = next_conversion (conv);
+ return conv;
+}
+
+/* Subroutine of build_aggr_conv: check whether FROM is a valid aggregate
+ initializer for array type ATYPE. */
+
+static bool
+can_convert_array (tree atype, tree from, int flags, tsubst_flags_t complain)
+{
+ tree elttype = TREE_TYPE (atype);
+ unsigned i;
+
+ if (TREE_CODE (from) == CONSTRUCTOR)
+ {
+ for (i = 0; i < CONSTRUCTOR_NELTS (from); ++i)
+ {
+ tree val = CONSTRUCTOR_ELT (from, i)->value;
+ bool ok;
+ if (TREE_CODE (elttype) == ARRAY_TYPE)
+ ok = can_convert_array (elttype, val, flags, complain);
+ else
+ ok = can_convert_arg (elttype, TREE_TYPE (val), val, flags,
+ complain);
+ if (!ok)
+ return false;
+ }
+ return true;
+ }
+
+ if (char_type_p (TYPE_MAIN_VARIANT (elttype))
+ && TREE_CODE (tree_strip_any_location_wrapper (from)) == STRING_CST)
+ return array_string_literal_compatible_p (atype, from);
+
+ /* No other valid way to aggregate initialize an array. */
+ return false;
+}
+
+/* Helper for build_aggr_conv. Return true if FIELD is in PSET, or if
+ FIELD has ANON_AGGR_TYPE_P and any initializable field in there recursively
+ is in PSET. */
+
+static bool
+field_in_pset (hash_set<tree, true> &pset, tree field)
+{
+ if (pset.contains (field))
+ return true;
+ if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
+ for (field = TYPE_FIELDS (TREE_TYPE (field));
+ field; field = DECL_CHAIN (field))
+ {
+ field = next_initializable_field (field);
+ if (field == NULL_TREE)
+ break;
+ if (field_in_pset (pset, field))
+ return true;
+ }
+ return false;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+ aggregate class, if such a conversion is possible. */
+
+static conversion *
+build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ unsigned HOST_WIDE_INT i = 0;
+ conversion *c;
+ tree field = next_initializable_field (TYPE_FIELDS (type));
+ tree empty_ctor = NULL_TREE;
+ hash_set<tree, true> pset;
+
+ /* We already called reshape_init in implicit_conversion. */
+
+ /* The conversions within the init-list aren't affected by the enclosing
+ context; they're always simple copy-initialization. */
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
+ /* For designated initializers, verify that each initializer is convertible
+ to corresponding TREE_TYPE (ce->index) and mark those FIELD_DECLs as
+ visited. In the following loop then ignore already visited
+ FIELD_DECLs. */
+ if (CONSTRUCTOR_IS_DESIGNATED_INIT (ctor))
+ {
+ tree idx, val;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), i, idx, val)
+ {
+ if (idx && TREE_CODE (idx) == FIELD_DECL)
+ {
+ tree ftype = TREE_TYPE (idx);
+ bool ok;
+
+ if (TREE_CODE (ftype) == ARRAY_TYPE)
+ ok = can_convert_array (ftype, val, flags, complain);
+ else
+ ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+ complain);
+
+ if (!ok)
+ return NULL;
+ /* For unions, there should be just one initializer. */
+ if (TREE_CODE (type) == UNION_TYPE)
+ {
+ field = NULL_TREE;
+ i = 1;
+ break;
+ }
+ pset.add (idx);
+ }
+ else
+ return NULL;
+ }
+ }
+
+ for (; field; field = next_initializable_field (DECL_CHAIN (field)))
+ {
+ tree ftype = TREE_TYPE (field);
+ tree val;
+ bool ok;
+
+ if (!pset.is_empty () && field_in_pset (pset, field))
+ continue;
+ if (i < CONSTRUCTOR_NELTS (ctor))
+ {
+ val = CONSTRUCTOR_ELT (ctor, i)->value;
+ ++i;
+ }
+ else if (DECL_INITIAL (field))
+ val = get_nsdmi (field, /*ctor*/false, complain);
+ else if (TYPE_REF_P (ftype))
+ /* Value-initialization of reference is ill-formed. */
+ return NULL;
+ else
+ {
+ if (empty_ctor == NULL_TREE)
+ empty_ctor = build_constructor (init_list_type_node, NULL);
+ val = empty_ctor;
+ }
+
+ if (TREE_CODE (ftype) == ARRAY_TYPE)
+ ok = can_convert_array (ftype, val, flags, complain);
+ else
+ ok = can_convert_arg (ftype, TREE_TYPE (val), val, flags,
+ complain);
+
+ if (!ok)
+ return NULL;
+
+ if (TREE_CODE (type) == UNION_TYPE)
+ break;
+ }
+
+ if (i < CONSTRUCTOR_NELTS (ctor))
+ return NULL;
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = cr_exact;
+ c->user_conv_p = true;
+ c->check_narrowing = true;
+ c->u.expr = ctor;
+ return c;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, an
+ array type, if such a conversion is possible. */
+
+static conversion *
+build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
+{
+ conversion *c;
+ unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
+ tree elttype = TREE_TYPE (type);
+ bool bad = false;
+ bool user = false;
+ enum conversion_rank rank = cr_exact;
+
+ /* We might need to propagate the size from the element to the array. */
+ complete_type (type);
+
+ if (TYPE_DOMAIN (type)
+ && !variably_modified_type_p (TYPE_DOMAIN (type), NULL_TREE))
+ {
+ unsigned HOST_WIDE_INT alen = tree_to_uhwi (array_type_nelts_top (type));
+ if (alen < len)
+ return NULL;
+ }
+
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
+ for (auto &e: CONSTRUCTOR_ELTS (ctor))
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (e.value), e.value,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ if (sub->rank > rank)
+ rank = sub->rank;
+ if (sub->user_conv_p)
+ user = true;
+ if (sub->bad_p)
+ bad = true;
+ }
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = rank;
+ c->user_conv_p = user;
+ c->bad_p = bad;
+ c->u.expr = ctor;
+ return c;
+}
+
+/* Represent a conversion from CTOR, a braced-init-list, to TYPE, a
+ complex type, if such a conversion is possible. */
+
+static conversion *
+build_complex_conv (tree type, tree ctor, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *c;
+ unsigned HOST_WIDE_INT len = CONSTRUCTOR_NELTS (ctor);
+ tree elttype = TREE_TYPE (type);
+ bool bad = false;
+ bool user = false;
+ enum conversion_rank rank = cr_exact;
+
+ if (len != 2)
+ return NULL;
+
+ flags = LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING;
+
+ for (auto &e: CONSTRUCTOR_ELTS (ctor))
+ {
+ conversion *sub
+ = implicit_conversion (elttype, TREE_TYPE (e.value), e.value,
+ false, flags, complain);
+ if (sub == NULL)
+ return NULL;
+
+ if (sub->rank > rank)
+ rank = sub->rank;
+ if (sub->user_conv_p)
+ user = true;
+ if (sub->bad_p)
+ bad = true;
+ }
+
+ c = alloc_conversion (ck_aggr);
+ c->type = type;
+ c->rank = rank;
+ c->user_conv_p = user;
+ c->bad_p = bad;
+ c->u.expr = ctor;
+ return c;
+}
+
+/* Build a representation of the identity conversion from EXPR to
+ itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */
+
+static conversion *
+build_identity_conv (tree type, tree expr)
+{
+ conversion *c;
+
+ c = alloc_conversion (ck_identity);
+ c->type = type;
+ c->u.expr = expr;
+
+ return c;
+}
+
+/* Converting from EXPR to TYPE was ambiguous in the sense that there
+ were multiple user-defined conversions to accomplish the job.
+ Build a conversion that indicates that ambiguity. */
+
+static conversion *
+build_ambiguous_conv (tree type, tree expr)
+{
+ conversion *c;
+
+ c = alloc_conversion (ck_ambig);
+ c->type = type;
+ c->u.expr = expr;
+
+ return c;
+}
+
+tree
+strip_top_quals (tree t)
+{
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ return t;
+ return cp_build_qualified_type (t, 0);
+}
+
+/* Returns the standard conversion path (see [conv]) from type FROM to type
+ TO, if any. For proper handling of null pointer constants, you must
+ also pass the expression EXPR to convert from. If C_CAST_P is true,
+ this conversion is coming from a C-style cast. */
+
+static conversion *
+standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
+{
+ enum tree_code fcode, tcode;
+ conversion *conv;
+ bool fromref = false;
+ tree qualified_to;
+
+ to = non_reference (to);
+ if (TYPE_REF_P (from))
+ {
+ fromref = true;
+ from = TREE_TYPE (from);
+ }
+ qualified_to = to;
+ to = strip_top_quals (to);
+ from = strip_top_quals (from);
+
+ if (expr && type_unknown_p (expr))
+ {
+ if (TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to))
+ {
+ tsubst_flags_t tflags = tf_conv;
+ expr = instantiate_type (to, expr, tflags);
+ if (expr == error_mark_node)
+ return NULL;
+ from = TREE_TYPE (expr);
+ }
+ else if (TREE_CODE (to) == BOOLEAN_TYPE)
+ {
+ /* Necessary for eg, TEMPLATE_ID_EXPRs (c++/50961). */
+ expr = resolve_nondeduced_context (expr, complain);
+ from = TREE_TYPE (expr);
+ }
+ }
+
+ fcode = TREE_CODE (from);
+ tcode = TREE_CODE (to);
+
+ conv = build_identity_conv (from, expr);
+ if (fcode == FUNCTION_TYPE || fcode == ARRAY_TYPE)
+ {
+ from = type_decays_to (from);
+ fcode = TREE_CODE (from);
+ /* Tell convert_like that we're using the address. */
+ conv->rvaluedness_matches_p = true;
+ conv = build_conv (ck_lvalue, from, conv);
+ }
+ /* Wrapping a ck_rvalue around a class prvalue (as a result of using
+ obvalue_p) seems odd, since it's already a prvalue, but that's how we
+ express the copy constructor call required by copy-initialization. */
+ else if (fromref || (expr && obvalue_p (expr)))
+ {
+ if (expr)
+ {
+ tree bitfield_type;
+ bitfield_type = is_bitfield_expr_with_lowered_type (expr);
+ if (bitfield_type)
+ {
+ from = strip_top_quals (bitfield_type);
+ fcode = TREE_CODE (from);
+ }
+ }
+ conv = build_conv (ck_rvalue, from, conv);
+ if (flags & LOOKUP_PREFER_RVALUE)
+ /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */
+ conv->rvaluedness_matches_p = true;
+ /* If we're performing copy-initialization, remember to skip
+ explicit constructors. */
+ if (flags & LOOKUP_ONLYCONVERTING)
+ conv->copy_init_p = true;
+ }
+
+ /* Allow conversion between `__complex__' data types. */
+ if (tcode == COMPLEX_TYPE && fcode == COMPLEX_TYPE)
+ {
+ /* The standard conversion sequence to convert FROM to TO is
+ the standard conversion sequence to perform componentwise
+ conversion. */
+ conversion *part_conv = standard_conversion
+ (TREE_TYPE (to), TREE_TYPE (from), NULL_TREE, c_cast_p, flags,
+ complain);
+
+ if (!part_conv)
+ conv = NULL;
+ else if (part_conv->kind == ck_identity)
+ /* Leave conv alone. */;
+ else
+ {
+ conv = build_conv (part_conv->kind, to, conv);
+ conv->rank = part_conv->rank;
+ }
+
+ return conv;
+ }
+
+ if (same_type_p (from, to))
+ {
+ if (CLASS_TYPE_P (to) && conv->kind == ck_rvalue)
+ conv->type = qualified_to;
+ return conv;
+ }
+
+ /* [conv.ptr]
+ A null pointer constant can be converted to a pointer type; ... A
+ null pointer constant of integral type can be converted to an
+ rvalue of type std::nullptr_t. */
+ if ((tcode == POINTER_TYPE || TYPE_PTRMEM_P (to)
+ || NULLPTR_TYPE_P (to))
+ && ((expr && null_ptr_cst_p (expr))
+ || NULLPTR_TYPE_P (from)))
+ conv = build_conv (ck_std, to, conv);
+ else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
+ || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
+ {
+ /* For backwards brain damage compatibility, allow interconversion of
+ pointers and integers with a pedwarn. */
+ conv = build_conv (ck_std, to, conv);
+ conv->bad_p = true;
+ }
+ else if (UNSCOPED_ENUM_P (to) && fcode == INTEGER_TYPE)
+ {
+ /* For backwards brain damage compatibility, allow interconversion of
+ enums and integers with a pedwarn. */
+ conv = build_conv (ck_std, to, conv);
+ conv->bad_p = true;
+ }
+ else if ((tcode == POINTER_TYPE && fcode == POINTER_TYPE)
+ || (TYPE_PTRDATAMEM_P (to) && TYPE_PTRDATAMEM_P (from)))
+ {
+ tree to_pointee;
+ tree from_pointee;
+
+ if (tcode == POINTER_TYPE)
+ {
+ to_pointee = TREE_TYPE (to);
+ from_pointee = TREE_TYPE (from);
+
+ /* Since this is the target of a pointer, it can't have function
+ qualifiers, so any TYPE_QUALS must be for attributes const or
+ noreturn. Strip them. */
+ if (TREE_CODE (to_pointee) == FUNCTION_TYPE
+ && TYPE_QUALS (to_pointee))
+ to_pointee = build_qualified_type (to_pointee, TYPE_UNQUALIFIED);
+ if (TREE_CODE (from_pointee) == FUNCTION_TYPE
+ && TYPE_QUALS (from_pointee))
+ from_pointee = build_qualified_type (from_pointee, TYPE_UNQUALIFIED);
+ }
+ else
+ {
+ to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
+ from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
+ }
+
+ if (tcode == POINTER_TYPE
+ && same_type_ignoring_top_level_qualifiers_p (from_pointee,
+ to_pointee))
+ ;
+ else if (VOID_TYPE_P (to_pointee)
+ && !TYPE_PTRDATAMEM_P (from)
+ && TREE_CODE (from_pointee) != FUNCTION_TYPE)
+ {
+ tree nfrom = TREE_TYPE (from);
+ /* Don't try to apply restrict to void. */
+ int quals = cp_type_quals (nfrom) & ~TYPE_QUAL_RESTRICT;
+ from_pointee = cp_build_qualified_type (void_type_node, quals);
+ from = build_pointer_type (from_pointee);
+ conv = build_conv (ck_ptr, from, conv);
+ }
+ else if (TYPE_PTRDATAMEM_P (from))
+ {
+ tree fbase = TYPE_PTRMEM_CLASS_TYPE (from);
+ tree tbase = TYPE_PTRMEM_CLASS_TYPE (to);
+
+ if (same_type_p (fbase, tbase))
+ /* No base conversion needed. */;
+ else if (DERIVED_FROM_P (fbase, tbase)
+ && (same_type_ignoring_top_level_qualifiers_p
+ (from_pointee, to_pointee)))
+ {
+ from = build_ptrmem_type (tbase, from_pointee);
+ conv = build_conv (ck_pmem, from, conv);
+ }
+ else
+ return NULL;
+ }
+ else if (CLASS_TYPE_P (from_pointee)
+ && CLASS_TYPE_P (to_pointee)
+ /* [conv.ptr]
+
+ An rvalue of type "pointer to cv D," where D is a
+ class type, can be converted to an rvalue of type
+ "pointer to cv B," where B is a base class (clause
+ _class.derived_) of D. If B is an inaccessible
+ (clause _class.access_) or ambiguous
+ (_class.member.lookup_) base class of D, a program
+ that necessitates this conversion is ill-formed.
+ Therefore, we use DERIVED_FROM_P, and do not check
+ access or uniqueness. */
+ && DERIVED_FROM_P (to_pointee, from_pointee))
+ {
+ from_pointee
+ = cp_build_qualified_type (to_pointee,
+ cp_type_quals (from_pointee));
+ from = build_pointer_type (from_pointee);
+ conv = build_conv (ck_ptr, from, conv);
+ conv->base_p = true;
+ }
+
+ if (same_type_p (from, to))
+ /* OK */;
+ else if (c_cast_p && comp_ptr_ttypes_const (to, from, bounds_either))
+ /* In a C-style cast, we ignore CV-qualification because we
+ are allowed to perform a static_cast followed by a
+ const_cast. */
+ conv = build_conv (ck_qual, to, conv);
+ else if (!c_cast_p && comp_ptr_ttypes (to_pointee, from_pointee))
+ conv = build_conv (ck_qual, to, conv);
+ else if (expr && string_conv_p (to, expr, 0))
+ /* converting from string constant to char *. */
+ conv = build_conv (ck_qual, to, conv);
+ else if (fnptr_conv_p (to, from))
+ conv = build_conv (ck_fnptr, to, conv);
+ /* Allow conversions among compatible ObjC pointer types (base
+ conversions have been already handled above). */
+ else if (c_dialect_objc ()
+ && objc_compare_types (to, from, -4, NULL_TREE))
+ conv = build_conv (ck_ptr, to, conv);
+ else if (ptr_reasonably_similar (to_pointee, from_pointee))
+ {
+ conv = build_conv (ck_ptr, to, conv);
+ conv->bad_p = true;
+ }
+ else
+ return NULL;
+
+ from = to;
+ }
+ else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from))
+ {
+ tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from));
+ tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to));
+ tree fbase = class_of_this_parm (fromfn);
+ tree tbase = class_of_this_parm (tofn);
+
+ /* If FBASE and TBASE are equivalent but incomplete, DERIVED_FROM_P
+ yields false. But a pointer to member of incomplete class is OK. */
+ if (!same_type_p (fbase, tbase) && !DERIVED_FROM_P (fbase, tbase))
+ return NULL;
+
+ tree fstat = static_fn_type (fromfn);
+ tree tstat = static_fn_type (tofn);
+ if (same_type_p (tstat, fstat)
+ || fnptr_conv_p (tstat, fstat))
+ /* OK */;
+ else
+ return NULL;
+
+ if (!same_type_p (fbase, tbase))
+ {
+ from = build_memfn_type (fstat,
+ tbase,
+ cp_type_quals (tbase),
+ type_memfn_rqual (tofn));
+ from = build_ptrmemfunc_type (build_pointer_type (from));
+ conv = build_conv (ck_pmem, from, conv);
+ conv->base_p = true;
+ }
+ if (fnptr_conv_p (tstat, fstat))
+ conv = build_conv (ck_fnptr, to, conv);
+ }
+ else if (tcode == BOOLEAN_TYPE)
+ {
+ /* [conv.bool]
+
+ A prvalue of arithmetic, unscoped enumeration, pointer, or pointer
+ to member type can be converted to a prvalue of type bool. ...
+ For direct-initialization (8.5 [dcl.init]), a prvalue of type
+ std::nullptr_t can be converted to a prvalue of type bool; */
+ if (ARITHMETIC_TYPE_P (from)
+ || UNSCOPED_ENUM_P (from)
+ || fcode == POINTER_TYPE
+ || TYPE_PTRMEM_P (from)
+ || NULLPTR_TYPE_P (from))
+ {
+ conv = build_conv (ck_std, to, conv);
+ if (fcode == POINTER_TYPE
+ || TYPE_PTRDATAMEM_P (from)
+ || (TYPE_PTRMEMFUNC_P (from)
+ && conv->rank < cr_pbool)
+ || NULLPTR_TYPE_P (from))
+ conv->rank = cr_pbool;
+ if (NULLPTR_TYPE_P (from) && (flags & LOOKUP_ONLYCONVERTING))
+ conv->bad_p = true;
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+ return conv;
+ }
+
+ return NULL;
+ }
+ /* We don't check for ENUMERAL_TYPE here because there are no standard
+ conversions to enum type. */
+ /* As an extension, allow conversion to complex type. */
+ else if (ARITHMETIC_TYPE_P (to))
+ {
+ if (! (INTEGRAL_CODE_P (fcode)
+ || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
+ || SCOPED_ENUM_P (from))
+ return NULL;
+
+ /* If we're parsing an enum with no fixed underlying type, we're
+ dealing with an incomplete type, which renders the conversion
+ ill-formed. */
+ if (!COMPLETE_TYPE_P (from))
+ return NULL;
+
+ conv = build_conv (ck_std, to, conv);
+
+ tree underlying_type = NULL_TREE;
+ if (TREE_CODE (from) == ENUMERAL_TYPE
+ && ENUM_FIXED_UNDERLYING_TYPE_P (from))
+ underlying_type = ENUM_UNDERLYING_TYPE (from);
+
+ /* Give this a better rank if it's a promotion.
+
+ To handle CWG 1601, also bump the rank if we are converting
+ an enumeration with a fixed underlying type to the underlying
+ type. */
+ if ((same_type_p (to, type_promotes_to (from))
+ || (underlying_type && same_type_p (to, underlying_type)))
+ && next_conversion (conv)->rank <= cr_promotion)
+ conv->rank = cr_promotion;
+ }
+ else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE
+ && vector_types_convertible_p (from, to, false))
+ return build_conv (ck_std, to, conv);
+ else if (MAYBE_CLASS_TYPE_P (to) && MAYBE_CLASS_TYPE_P (from)
+ && is_properly_derived_from (from, to))
+ {
+ if (conv->kind == ck_rvalue)
+ conv = next_conversion (conv);
+ conv = build_conv (ck_base, to, conv);
+ /* The derived-to-base conversion indicates the initialization
+ of a parameter with base type from an object of a derived
+ type. A temporary object is created to hold the result of
+ the conversion unless we're binding directly to a reference. */
+ conv->need_temporary_p = !(flags & LOOKUP_NO_TEMP_BIND);
+ if (flags & LOOKUP_PREFER_RVALUE)
+ /* Tell convert_like to set LOOKUP_PREFER_RVALUE. */
+ conv->rvaluedness_matches_p = true;
+ /* If we're performing copy-initialization, remember to skip
+ explicit constructors. */
+ if (flags & LOOKUP_ONLYCONVERTING)
+ conv->copy_init_p = true;
+ }
+ else
+ return NULL;
+
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+
+ return conv;
+}
+
+/* Returns nonzero if T1 is reference-related to T2. */
+
+bool
+reference_related_p (tree t1, tree t2)
+{
+ if (t1 == error_mark_node || t2 == error_mark_node)
+ return false;
+
+ t1 = TYPE_MAIN_VARIANT (t1);
+ t2 = TYPE_MAIN_VARIANT (t2);
+
+ /* [dcl.init.ref]
+
+ Given types "cv1 T1" and "cv2 T2," "cv1 T1" is reference-related
+ to "cv2 T2" if T1 is similar to T2, or T1 is a base class of T2. */
+ return (similar_type_p (t1, t2)
+ || (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
+ && DERIVED_FROM_P (t1, t2)));
+}
+
+/* Returns nonzero if T1 is reference-compatible with T2. */
+
+bool
+reference_compatible_p (tree t1, tree t2)
+{
+ /* [dcl.init.ref]
+
+ "cv1 T1" is reference compatible with "cv2 T2" if
+ a prvalue of type "pointer to cv2 T2" can be converted to the type
+ "pointer to cv1 T1" via a standard conversion sequence. */
+ tree ptype1 = build_pointer_type (t1);
+ tree ptype2 = build_pointer_type (t2);
+ conversion *conv = standard_conversion (ptype1, ptype2, NULL_TREE,
+ /*c_cast_p=*/false, 0, tf_none);
+ if (!conv || conv->bad_p)
+ return false;
+ return true;
+}
+
+/* Return true if converting FROM to TO would involve a qualification
+ conversion. */
+
+static bool
+involves_qualification_conversion_p (tree to, tree from)
+{
+ /* If we're not convering a pointer to another one, we won't get
+ a qualification conversion. */
+ if (!((TYPE_PTR_P (to) && TYPE_PTR_P (from))
+ || (TYPE_PTRDATAMEM_P (to) && TYPE_PTRDATAMEM_P (from))))
+ return false;
+
+ conversion *conv = standard_conversion (to, from, NULL_TREE,
+ /*c_cast_p=*/false, 0, tf_none);
+ for (conversion *t = conv; t; t = next_conversion (t))
+ if (t->kind == ck_qual)
+ return true;
+
+ return false;
+}
+
+/* A reference of the indicated TYPE is being bound directly to the
+ expression represented by the implicit conversion sequence CONV.
+ Return a conversion sequence for this binding. */
+
+static conversion *
+direct_reference_binding (tree type, conversion *conv)
+{
+ tree t;
+
+ gcc_assert (TYPE_REF_P (type));
+ gcc_assert (!TYPE_REF_P (conv->type));
+
+ t = TREE_TYPE (type);
+
+ if (conv->kind == ck_identity)
+ /* Mark the identity conv as to not decay to rvalue. */
+ conv->rvaluedness_matches_p = true;
+
+ /* [over.ics.rank]
+
+ When a parameter of reference type binds directly
+ (_dcl.init.ref_) to an argument expression, the implicit
+ conversion sequence is the identity conversion, unless the
+ argument expression has a type that is a derived class of the
+ parameter type, in which case the implicit conversion sequence is
+ a derived-to-base Conversion.
+
+ If the parameter binds directly to the result of applying a
+ conversion function to the argument expression, the implicit
+ conversion sequence is a user-defined conversion sequence
+ (_over.ics.user_), with the second standard conversion sequence
+ either an identity conversion or, if the conversion function
+ returns an entity of a type that is a derived class of the
+ parameter type, a derived-to-base conversion. */
+ if (is_properly_derived_from (conv->type, t))
+ {
+ /* Represent the derived-to-base conversion. */
+ conv = build_conv (ck_base, t, conv);
+ /* We will actually be binding to the base-class subobject in
+ the derived class, so we mark this conversion appropriately.
+ That way, convert_like knows not to generate a temporary. */
+ conv->need_temporary_p = false;
+ }
+ else if (involves_qualification_conversion_p (t, conv->type))
+ /* Represent the qualification conversion. After DR 2352
+ #1 and #2 were indistinguishable conversion sequences:
+
+ void f(int*); // #1
+ void f(const int* const &); // #2
+ void g(int* p) { f(p); }
+
+ because the types "int *" and "const int *const" are
+ reference-related and we were binding both directly and they
+ had the same rank. To break it up, we add a ck_qual under the
+ ck_ref_bind so that conversion sequence ranking chooses #1. */
+ conv = build_conv (ck_qual, t, conv);
+
+ return build_conv (ck_ref_bind, type, conv);
+}
+
+/* Returns the conversion path from type FROM to reference type TO for
+ purposes of reference binding. For lvalue binding, either pass a
+ reference type to FROM or an lvalue expression to EXPR. If the
+ reference will be bound to a temporary, NEED_TEMPORARY_P is set for
+ the conversion returned. If C_CAST_P is true, this
+ conversion is coming from a C-style cast. */
+
+static conversion *
+reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *conv = NULL;
+ tree to = TREE_TYPE (rto);
+ tree from = rfrom;
+ tree tfrom;
+ bool related_p;
+ bool compatible_p;
+ cp_lvalue_kind gl_kind;
+ bool is_lvalue;
+
+ if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr))
+ {
+ expr = instantiate_type (to, expr, tf_none);
+ if (expr == error_mark_node)
+ return NULL;
+ from = TREE_TYPE (expr);
+ }
+
+ bool copy_list_init = false;
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
+ /* DR 1288: Otherwise, if the initializer list has a single element
+ of type E and ... [T's] referenced type is reference-related to E,
+ the object or reference is initialized from that element...
+
+ ??? With P0388R4, we should bind 't' directly to U{}:
+ using U = A[2];
+ A (&&t)[] = {U{}};
+ because A[] and A[2] are reference-related. But we don't do it
+ because grok_reference_init has deduced the array size (to 1), and
+ A[1] and A[2] aren't reference-related. */
+ if (CONSTRUCTOR_NELTS (expr) == 1
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
+ {
+ tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ if (error_operand_p (elt))
+ return NULL;
+ tree etype = TREE_TYPE (elt);
+ if (reference_related_p (to, etype))
+ {
+ expr = elt;
+ from = etype;
+ goto skip;
+ }
+ }
+ /* Otherwise, if T is a reference type, a prvalue temporary of the type
+ referenced by T is copy-list-initialized, and the reference is bound
+ to that temporary. */
+ copy_list_init = true;
+ skip:;
+ }
+
+ if (TYPE_REF_P (from))
+ {
+ from = TREE_TYPE (from);
+ if (!TYPE_REF_IS_RVALUE (rfrom)
+ || TREE_CODE (from) == FUNCTION_TYPE)
+ gl_kind = clk_ordinary;
+ else
+ gl_kind = clk_rvalueref;
+ }
+ else if (expr)
+ gl_kind = lvalue_kind (expr);
+ else if (CLASS_TYPE_P (from)
+ || TREE_CODE (from) == ARRAY_TYPE)
+ gl_kind = clk_class;
+ else
+ gl_kind = clk_none;
+
+ /* Don't allow a class prvalue when LOOKUP_NO_TEMP_BIND. */
+ if ((flags & LOOKUP_NO_TEMP_BIND)
+ && (gl_kind & clk_class))
+ gl_kind = clk_none;
+
+ /* Same mask as real_lvalue_p. */
+ is_lvalue = gl_kind && !(gl_kind & (clk_rvalueref|clk_class));
+
+ tfrom = from;
+ if ((gl_kind & clk_bitfield) != 0)
+ tfrom = unlowered_expr_type (expr);
+
+ /* Figure out whether or not the types are reference-related and
+ reference compatible. We have to do this after stripping
+ references from FROM. */
+ related_p = reference_related_p (to, tfrom);
+ /* If this is a C cast, first convert to an appropriately qualified
+ type, so that we can later do a const_cast to the desired type. */
+ if (related_p && c_cast_p
+ && !at_least_as_qualified_p (to, tfrom))
+ to = cp_build_qualified_type (to, cp_type_quals (tfrom));
+ compatible_p = reference_compatible_p (to, tfrom);
+
+ /* Directly bind reference when target expression's type is compatible with
+ the reference and expression is an lvalue. In DR391, the wording in
+ [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
+ const and rvalue references to rvalues of compatible class type.
+ We should also do direct bindings for non-class xvalues. */
+ if ((related_p || compatible_p) && gl_kind)
+ {
+ /* [dcl.init.ref]
+
+ If the initializer expression
+
+ -- is an lvalue (but not an lvalue for a bit-field), and "cv1 T1"
+ is reference-compatible with "cv2 T2,"
+
+ the reference is bound directly to the initializer expression
+ lvalue.
+
+ [...]
+ If the initializer expression is an rvalue, with T2 a class type,
+ and "cv1 T1" is reference-compatible with "cv2 T2", the reference
+ is bound to the object represented by the rvalue or to a sub-object
+ within that object. */
+
+ conv = build_identity_conv (tfrom, expr);
+ conv = direct_reference_binding (rto, conv);
+
+ if (TYPE_REF_P (rfrom))
+ /* Handle rvalue reference to function properly. */
+ conv->rvaluedness_matches_p
+ = (TYPE_REF_IS_RVALUE (rto) == TYPE_REF_IS_RVALUE (rfrom));
+ else
+ conv->rvaluedness_matches_p
+ = (TYPE_REF_IS_RVALUE (rto) == !is_lvalue);
+
+ if ((gl_kind & clk_bitfield) != 0
+ || ((gl_kind & clk_packed) != 0 && !TYPE_PACKED (to)))
+ /* For the purposes of overload resolution, we ignore the fact
+ this expression is a bitfield or packed field. (In particular,
+ [over.ics.ref] says specifically that a function with a
+ non-const reference parameter is viable even if the
+ argument is a bitfield.)
+
+ However, when we actually call the function we must create
+ a temporary to which to bind the reference. If the
+ reference is volatile, or isn't const, then we cannot make
+ a temporary, so we just issue an error when the conversion
+ actually occurs. */
+ conv->need_temporary_p = true;
+
+ /* Don't allow binding of lvalues (other than function lvalues) to
+ rvalue references. */
+ if (is_lvalue && TYPE_REF_IS_RVALUE (rto)
+ && TREE_CODE (to) != FUNCTION_TYPE)
+ conv->bad_p = true;
+
+ /* Nor the reverse. */
+ if (!is_lvalue && !TYPE_REF_IS_RVALUE (rto)
+ /* Unless it's really an lvalue. */
+ && !(cxx_dialect >= cxx20
+ && (gl_kind & clk_implicit_rval))
+ && (!CP_TYPE_CONST_NON_VOLATILE_P (to)
+ || (flags & LOOKUP_NO_RVAL_BIND))
+ && TREE_CODE (to) != FUNCTION_TYPE)
+ conv->bad_p = true;
+
+ if (!compatible_p)
+ conv->bad_p = true;
+
+ return conv;
+ }
+ /* [class.conv.fct] A conversion function is never used to convert a
+ (possibly cv-qualified) object to the (possibly cv-qualified) same
+ object type (or a reference to it), to a (possibly cv-qualified) base
+ class of that type (or a reference to it).... */
+ else if (CLASS_TYPE_P (from) && !related_p
+ && !(flags & LOOKUP_NO_CONVERSION))
+ {
+ /* [dcl.init.ref]
+
+ If the initializer expression
+
+ -- has a class type (i.e., T2 is a class type) can be
+ implicitly converted to an lvalue of type "cv3 T3," where
+ "cv1 T1" is reference-compatible with "cv3 T3". (this
+ conversion is selected by enumerating the applicable
+ conversion functions (_over.match.ref_) and choosing the
+ best one through overload resolution. (_over.match_).
+
+ the reference is bound to the lvalue result of the conversion
+ in the second case. */
+ z_candidate *cand = build_user_type_conversion_1 (rto, expr, flags,
+ complain);
+ if (cand)
+ return cand->second_conv;
+ }
+
+ /* From this point on, we conceptually need temporaries, even if we
+ elide them. Only the cases above are "direct bindings". */
+ if (flags & LOOKUP_NO_TEMP_BIND)
+ return NULL;
+
+ /* [over.ics.rank]
+
+ When a parameter of reference type is not bound directly to an
+ argument expression, the conversion sequence is the one required
+ to convert the argument expression to the underlying type of the
+ reference according to _over.best.ics_. Conceptually, this
+ conversion sequence corresponds to copy-initializing a temporary
+ of the underlying type with the argument expression. Any
+ difference in top-level cv-qualification is subsumed by the
+ initialization itself and does not constitute a conversion. */
+
+ /* [dcl.init.ref]
+
+ Otherwise, the reference shall be an lvalue reference to a
+ non-volatile const type, or the reference shall be an rvalue
+ reference.
+
+ We try below to treat this as a bad conversion to improve diagnostics,
+ but if TO is an incomplete class, we need to reject this conversion
+ now to avoid unnecessary instantiation. */
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto)
+ && !COMPLETE_TYPE_P (to))
+ return NULL;
+
+ /* We're generating a temporary now, but don't bind any more in the
+ conversion (specifically, don't slice the temporary returned by a
+ conversion operator). */
+ flags |= LOOKUP_NO_TEMP_BIND;
+
+ /* Core issue 899: When [copy-]initializing a temporary to be bound
+ to the first parameter of a copy constructor (12.8) called with
+ a single argument in the context of direct-initialization,
+ explicit conversion functions are also considered.
+
+ So don't set LOOKUP_ONLYCONVERTING in that case. */
+ if (!(flags & LOOKUP_COPY_PARM))
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ if (!conv)
+ conv = implicit_conversion (to, from, expr, c_cast_p,
+ flags, complain);
+ if (!conv)
+ return NULL;
+
+ if (conv->user_conv_p)
+ {
+ if (copy_list_init)
+ /* Remember this was copy-list-initialization. */
+ conv->need_temporary_p = true;
+
+ /* If initializing the temporary used a conversion function,
+ recalculate the second conversion sequence. */
+ for (conversion *t = conv; t; t = next_conversion (t))
+ if (t->kind == ck_user
+ && DECL_CONV_FN_P (t->cand->fn))
+ {
+ tree ftype = TREE_TYPE (TREE_TYPE (t->cand->fn));
+ /* A prvalue of non-class type is cv-unqualified. */
+ if (!TYPE_REF_P (ftype) && !CLASS_TYPE_P (ftype))
+ ftype = cv_unqualified (ftype);
+ int sflags = (flags|LOOKUP_NO_CONVERSION)&~LOOKUP_NO_TEMP_BIND;
+ conversion *new_second
+ = reference_binding (rto, ftype, NULL_TREE, c_cast_p,
+ sflags, complain);
+ if (!new_second)
+ return NULL;
+ return merge_conversion_sequences (t, new_second);
+ }
+ }
+
+ conv = build_conv (ck_ref_bind, rto, conv);
+ /* This reference binding, unlike those above, requires the
+ creation of a temporary. */
+ conv->need_temporary_p = true;
+ conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
+
+ /* [dcl.init.ref]
+
+ Otherwise, the reference shall be an lvalue reference to a
+ non-volatile const type, or the reference shall be an rvalue
+ reference. */
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto))
+ conv->bad_p = true;
+
+ /* [dcl.init.ref]
+
+ Otherwise, a temporary of type "cv1 T1" is created and
+ initialized from the initializer expression using the rules for a
+ non-reference copy initialization. If T1 is reference-related to
+ T2, cv1 must be the same cv-qualification as, or greater
+ cv-qualification than, cv2; otherwise, the program is ill-formed. */
+ if (related_p && !at_least_as_qualified_p (to, from))
+ conv->bad_p = true;
+
+ return conv;
+}
+
+/* Most of the implementation of implicit_conversion, with the same
+ parameters. */
+
+static conversion *
+implicit_conversion_1 (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv;
+
+ if (from == error_mark_node || to == error_mark_node
+ || expr == error_mark_node)
+ return NULL;
+
+ /* Other flags only apply to the primary function in overload
+ resolution, or after we've chosen one. */
+ flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
+ |LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
+ |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL);
+
+ /* FIXME: actually we don't want warnings either, but we can't just
+ have 'complain &= ~(tf_warning|tf_error)' because it would cause
+ the regression of, eg, g++.old-deja/g++.benjamin/16077.C.
+ We really ought not to issue that warning until we've committed
+ to that conversion. */
+ complain &= ~tf_error;
+
+ /* Call reshape_init early to remove redundant braces. */
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CLASS_TYPE_P (to)
+ && COMPLETE_TYPE_P (complete_type (to))
+ && !CLASSTYPE_NON_AGGREGATE (to))
+ {
+ expr = reshape_init (to, expr, complain);
+ if (expr == error_mark_node)
+ return NULL;
+ from = TREE_TYPE (expr);
+ }
+
+ if (TYPE_REF_P (to))
+ conv = reference_binding (to, from, expr, c_cast_p, flags, complain);
+ else
+ conv = standard_conversion (to, from, expr, c_cast_p, flags, complain);
+
+ if (conv)
+ return conv;
+
+ if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ if (is_std_init_list (to) && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
+ return build_list_conv (to, expr, flags, complain);
+
+ /* As an extension, allow list-initialization of _Complex. */
+ if (TREE_CODE (to) == COMPLEX_TYPE
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
+ {
+ conv = build_complex_conv (to, expr, flags, complain);
+ if (conv)
+ return conv;
+ }
+
+ /* Allow conversion from an initializer-list with one element to a
+ scalar type. */
+ if (SCALAR_TYPE_P (to))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ tree elt;
+
+ if (nelts == 0)
+ elt = build_value_init (to, tf_none);
+ else if (nelts == 1 && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr))
+ elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ elt = error_mark_node;
+
+ conv = implicit_conversion (to, TREE_TYPE (elt), elt,
+ c_cast_p, flags, complain);
+ if (conv)
+ {
+ conv->check_narrowing = true;
+ if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+ /* Too many levels of braces, i.e. '{{1}}'. */
+ conv->bad_p = true;
+ return conv;
+ }
+ }
+ else if (TREE_CODE (to) == ARRAY_TYPE)
+ return build_array_conv (to, expr, flags, complain);
+ }
+
+ if (expr != NULL_TREE
+ && (MAYBE_CLASS_TYPE_P (from)
+ || MAYBE_CLASS_TYPE_P (to))
+ && (flags & LOOKUP_NO_CONVERSION) == 0)
+ {
+ struct z_candidate *cand;
+
+ if (CLASS_TYPE_P (to)
+ && BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && !CLASSTYPE_NON_AGGREGATE (complete_type (to)))
+ return build_aggr_conv (to, expr, flags, complain);
+
+ cand = build_user_type_conversion_1 (to, expr, flags, complain);
+ if (cand)
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_NELTS (expr) == 1
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (expr)
+ && !is_list_ctor (cand->fn))
+ {
+ /* "If C is not an initializer-list constructor and the
+ initializer list has a single element of type cv U, where U is
+ X or a class derived from X, the implicit conversion sequence
+ has Exact Match rank if U is X, or Conversion rank if U is
+ derived from X." */
+ tree elt = CONSTRUCTOR_ELT (expr, 0)->value;
+ tree elttype = TREE_TYPE (elt);
+ if (reference_related_p (to, elttype))
+ return implicit_conversion (to, elttype, elt,
+ c_cast_p, flags, complain);
+ }
+ conv = cand->second_conv;
+ }
+
+ /* We used to try to bind a reference to a temporary here, but that
+ is now handled after the recursive call to this function at the end
+ of reference_binding. */
+ return conv;
+ }
+
+ return NULL;
+}
+
+/* Returns the implicit conversion sequence (see [over.ics]) from type
+ FROM to type TO. The optional expression EXPR may affect the
+ conversion. FLAGS are the usual overloading flags. If C_CAST_P is
+ true, this conversion is coming from a C-style cast. */
+
+static conversion *
+implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv = implicit_conversion_1 (to, from, expr, c_cast_p,
+ flags, complain);
+ if (!conv || conv->bad_p)
+ return conv;
+ if (conv_is_prvalue (conv)
+ && CLASS_TYPE_P (conv->type)
+ && CLASSTYPE_PURE_VIRTUALS (conv->type))
+ conv->bad_p = true;
+ return conv;
+}
+
+/* Like implicit_conversion, but return NULL if the conversion is bad.
+
+ This is not static so that check_non_deducible_conversion can call it within
+ add_template_candidate_real as part of overload resolution; it should not be
+ called outside of overload resolution. */
+
+conversion *
+good_conversion (tree to, tree from, tree expr,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *c = implicit_conversion (to, from, expr, /*cast*/false,
+ flags, complain);
+ if (c && c->bad_p)
+ c = NULL;
+ return c;
+}
+
+/* Add a new entry to the list of candidates. Used by the add_*_candidate
+ functions. ARGS will not be changed until a single candidate is
+ selected. */
+
+static struct z_candidate *
+add_candidate (struct z_candidate **candidates,
+ tree fn, tree first_arg, const vec<tree, va_gc> *args,
+ size_t num_convs, conversion **convs,
+ tree access_path, tree conversion_path,
+ int viable, struct rejection_reason *reason,
+ int flags)
+{
+ struct z_candidate *cand = (struct z_candidate *)
+ conversion_obstack_alloc (sizeof (struct z_candidate));
+
+ cand->fn = fn;
+ cand->first_arg = first_arg;
+ cand->args = args;
+ cand->convs = convs;
+ cand->num_convs = num_convs;
+ cand->access_path = access_path;
+ cand->conversion_path = conversion_path;
+ cand->viable = viable;
+ cand->reason = reason;
+ cand->next = *candidates;
+ cand->flags = flags;
+ *candidates = cand;
+
+ if (convs && cand->reversed ())
+ /* Swap the conversions for comparison in joust; we'll swap them back
+ before build_over_call. */
+ std::swap (convs[0], convs[1]);
+
+ return cand;
+}
+
+/* Return the number of remaining arguments in the parameter list
+ beginning with ARG. */
+
+int
+remaining_arguments (tree arg)
+{
+ int n;
+
+ for (n = 0; arg != NULL_TREE && arg != void_list_node;
+ arg = TREE_CHAIN (arg))
+ n++;
+
+ return n;
+}
+
+/* [over.match.copy]: When initializing a temporary object (12.2) to be bound
+ to the first parameter of a constructor where the parameter is of type
+ "reference to possibly cv-qualified T" and the constructor is called with a
+ single argument in the context of direct-initialization of an object of type
+ "cv2 T", explicit conversion functions are also considered.
+
+ So set LOOKUP_COPY_PARM to let reference_binding know that
+ it's being called in that context. */
+
+int
+conv_flags (int i, int nargs, tree fn, tree arg, int flags)
+{
+ int lflags = flags;
+ tree t;
+ if (i == 0 && nargs == 1 && DECL_CONSTRUCTOR_P (fn)
+ && (t = FUNCTION_FIRST_USER_PARMTYPE (fn))
+ && (same_type_ignoring_top_level_qualifiers_p
+ (non_reference (TREE_VALUE (t)), DECL_CONTEXT (fn))))
+ {
+ if (!(flags & LOOKUP_ONLYCONVERTING))
+ lflags |= LOOKUP_COPY_PARM;
+ if ((flags & LOOKUP_LIST_INIT_CTOR)
+ && BRACE_ENCLOSED_INITIALIZER_P (arg))
+ lflags |= LOOKUP_NO_CONVERSION;
+ }
+ else
+ lflags |= LOOKUP_ONLYCONVERTING;
+
+ return lflags;
+}
+
+/* Build an appropriate 'this' conversion for the method FN and class
+ type CTYPE from the value ARG (having type ARGTYPE) to the type PARMTYPE.
+ This function modifies PARMTYPE, ARGTYPE and ARG. */
+
+static conversion *
+build_this_conversion (tree fn, tree ctype,
+ tree& parmtype, tree& argtype, tree& arg,
+ int flags, tsubst_flags_t complain)
+{
+ gcc_assert (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn));
+
+ /* The type of the implicit object parameter ('this') for
+ overload resolution is not always the same as for the
+ function itself; conversion functions are considered to
+ be members of the class being converted, and functions
+ introduced by a using-declaration are considered to be
+ members of the class that uses them.
+
+ Since build_over_call ignores the ICS for the `this'
+ parameter, we can just change the parm type. */
+ parmtype = cp_build_qualified_type (ctype,
+ cp_type_quals (TREE_TYPE (parmtype)));
+ bool this_p = true;
+ if (FUNCTION_REF_QUALIFIED (TREE_TYPE (fn)))
+ {
+ /* If the function has a ref-qualifier, the implicit
+ object parameter has reference type. */
+ bool rv = FUNCTION_RVALUE_QUALIFIED (TREE_TYPE (fn));
+ parmtype = cp_build_reference_type (parmtype, rv);
+ /* The special handling of 'this' conversions in compare_ics
+ does not apply if there is a ref-qualifier. */
+ this_p = false;
+ }
+ else
+ {
+ parmtype = build_pointer_type (parmtype);
+ /* We don't use build_this here because we don't want to
+ capture the object argument until we've chosen a
+ non-static member function. */
+ arg = build_address (arg);
+ argtype = lvalue_type (arg);
+ }
+ flags |= LOOKUP_ONLYCONVERTING;
+ conversion *t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, flags, complain);
+ t->this_p = this_p;
+ return t;
+}
+
+/* Create an overload candidate for the function or method FN called
+ with the argument list FIRST_ARG/ARGS and add it to CANDIDATES.
+ FLAGS is passed on to implicit_conversion.
+
+ This does not change ARGS.
+
+ CTYPE, if non-NULL, is the type we want to pretend this function
+ comes from for purposes of overload resolution.
+
+ SHORTCUT_BAD_CONVS controls how we handle "bad" argument conversions.
+ If true, we stop computing conversions upon seeing the first bad
+ conversion. This is used by add_candidates to avoid computing
+ more conversions than necessary in the presence of a strictly viable
+ candidate, while preserving the defacto behavior of overload resolution
+ when it turns out there are only non-strictly viable candidates. */
+
+static struct z_candidate *
+add_function_candidate (struct z_candidate **candidates,
+ tree fn, tree ctype, tree first_arg,
+ const vec<tree, va_gc> *args, tree access_path,
+ tree conversion_path, int flags,
+ conversion **convs,
+ bool shortcut_bad_convs,
+ tsubst_flags_t complain)
+{
+ tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ int i, len;
+ tree parmnode;
+ tree orig_first_arg = first_arg;
+ int skip;
+ int viable = 1;
+ struct rejection_reason *reason = NULL;
+
+ /* The `this', `in_chrg' and VTT arguments to constructors are not
+ considered in overload resolution. */
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ if (ctor_omit_inherited_parms (fn))
+ /* Bring back parameters omitted from an inherited ctor. */
+ parmlist = FUNCTION_FIRST_USER_PARMTYPE (DECL_ORIGIN (fn));
+ else
+ parmlist = skip_artificial_parms_for (fn, parmlist);
+ skip = num_artificial_parms_for (fn);
+ if (skip > 0 && first_arg != NULL_TREE)
+ {
+ --skip;
+ first_arg = NULL_TREE;
+ }
+ }
+ else
+ skip = 0;
+
+ len = vec_safe_length (args) - skip + (first_arg != NULL_TREE ? 1 : 0);
+ if (!convs)
+ convs = alloc_conversions (len);
+
+ /* 13.3.2 - Viable functions [over.match.viable]
+ First, to be a viable function, a candidate function shall have enough
+ parameters to agree in number with the arguments in the list.
+
+ We need to check this first; otherwise, checking the ICSes might cause
+ us to produce an ill-formed template instantiation. */
+
+ parmnode = parmlist;
+ for (i = 0; i < len; ++i)
+ {
+ if (parmnode == NULL_TREE || parmnode == void_list_node)
+ break;
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if ((i < len && parmnode)
+ || !sufficient_parms_p (parmnode))
+ {
+ int remaining = remaining_arguments (parmnode);
+ viable = 0;
+ reason = arity_rejection (first_arg, i + remaining, len);
+ }
+
+ /* An inherited constructor (12.6.3 [class.inhctor.init]) that has a first
+ parameter of type "reference to cv C" (including such a constructor
+ instantiated from a template) is excluded from the set of candidate
+ functions when used to construct an object of type D with an argument list
+ containing a single argument if C is reference-related to D. */
+ if (viable && len == 1 && parmlist && DECL_CONSTRUCTOR_P (fn)
+ && flag_new_inheriting_ctors
+ && DECL_INHERITED_CTOR (fn))
+ {
+ tree ptype = non_reference (TREE_VALUE (parmlist));
+ tree dtype = DECL_CONTEXT (fn);
+ tree btype = DECL_INHERITED_CTOR_BASE (fn);
+ if (reference_related_p (ptype, dtype)
+ && reference_related_p (btype, ptype))
+ {
+ viable = false;
+ reason = inherited_ctor_rejection ();
+ }
+ }
+
+ /* Second, for a function to be viable, its constraints must be
+ satisfied. */
+ if (flag_concepts && viable && !constraints_satisfied_p (fn))
+ {
+ reason = constraint_failure ();
+ viable = false;
+ }
+
+ /* When looking for a function from a subobject from an implicit
+ copy/move constructor/operator=, don't consider anything that takes (a
+ reference to) an unrelated type. See c++/44909 and core 1092. */
+ if (viable && parmlist && (flags & LOOKUP_DEFAULTED))
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ i = 1;
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+ && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR))
+ i = 2;
+ else
+ i = 0;
+ if (i && len == i)
+ {
+ parmnode = chain_index (i-1, parmlist);
+ if (!reference_related_p (non_reference (TREE_VALUE (parmnode)),
+ ctype))
+ viable = 0;
+ }
+
+ /* This only applies at the top level. */
+ flags &= ~LOOKUP_DEFAULTED;
+ }
+
+ if (! viable)
+ goto out;
+
+ /* Third, for F to be a viable function, there shall exist for each
+ argument an implicit conversion sequence that converts that argument
+ to the corresponding parameter of F. */
+
+ parmnode = parmlist;
+
+ for (i = 0; i < len; ++i)
+ {
+ tree argtype, to_type;
+ tree arg;
+
+ if (parmnode == void_list_node)
+ break;
+
+ if (convs[i])
+ {
+ /* Already set during deduction. */
+ parmnode = TREE_CHAIN (parmnode);
+ continue;
+ }
+
+ if (i == 0 && first_arg != NULL_TREE)
+ arg = first_arg;
+ else
+ arg = CONST_CAST_TREE (
+ (*args)[i + skip - (first_arg != NULL_TREE ? 1 : 0)]);
+ argtype = lvalue_type (arg);
+
+ conversion *t;
+ if (parmnode)
+ {
+ tree parmtype = TREE_VALUE (parmnode);
+ if (i == 0
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ t = build_this_conversion (fn, ctype, parmtype, argtype, arg,
+ flags, complain);
+ else
+ {
+ int lflags = conv_flags (i, len-skip, fn, arg, flags);
+ t = implicit_conversion (parmtype, argtype, arg,
+ /*c_cast_p=*/false, lflags, complain);
+ }
+ to_type = parmtype;
+ parmnode = TREE_CHAIN (parmnode);
+ }
+ else
+ {
+ t = build_identity_conv (argtype, arg);
+ t->ellipsis_p = true;
+ to_type = argtype;
+ }
+
+ convs[i] = t;
+ if (! t)
+ {
+ viable = 0;
+ reason = arg_conversion_rejection (first_arg, i, argtype, to_type,
+ EXPR_LOCATION (arg));
+ break;
+ }
+
+ if (t->bad_p)
+ {
+ viable = -1;
+ reason = bad_arg_conversion_rejection (first_arg, i, arg, to_type,
+ EXPR_LOCATION (arg));
+ if (shortcut_bad_convs)
+ break;
+ }
+ }
+
+ out:
+ return add_candidate (candidates, fn, orig_first_arg, args, len, convs,
+ access_path, conversion_path, viable, reason, flags);
+}
+
+/* Create an overload candidate for the conversion function FN which will
+ be invoked for expression OBJ, producing a pointer-to-function which
+ will in turn be called with the argument list FIRST_ARG/ARGLIST,
+ and add it to CANDIDATES. This does not change ARGLIST. FLAGS is
+ passed on to implicit_conversion.
+
+ Actually, we don't really care about FN; we care about the type it
+ converts to. There may be multiple conversion functions that will
+ convert to that type, and we rely on build_user_type_conversion_1 to
+ choose the best one; so when we create our candidate, we record the type
+ instead of the function. */
+
+static struct z_candidate *
+add_conv_candidate (struct z_candidate **candidates, tree fn, tree obj,
+ const vec<tree, va_gc> *arglist,
+ tree access_path, tree conversion_path,
+ tsubst_flags_t complain)
+{
+ tree totype = TREE_TYPE (TREE_TYPE (fn));
+ int i, len, viable, flags;
+ tree parmlist, parmnode;
+ conversion **convs;
+ struct rejection_reason *reason;
+
+ for (parmlist = totype; TREE_CODE (parmlist) != FUNCTION_TYPE; )
+ parmlist = TREE_TYPE (parmlist);
+ parmlist = TYPE_ARG_TYPES (parmlist);
+
+ len = vec_safe_length (arglist) + 1;
+ convs = alloc_conversions (len);
+ parmnode = parmlist;
+ viable = 1;
+ flags = LOOKUP_IMPLICIT;
+ reason = NULL;
+
+ /* Don't bother looking up the same type twice. */
+ if (*candidates && (*candidates)->fn == totype)
+ return NULL;
+
+ for (i = 0; i < len; ++i)
+ {
+ tree arg, argtype, convert_type = NULL_TREE;
+ conversion *t;
+
+ if (i == 0)
+ arg = obj;
+ else
+ arg = (*arglist)[i - 1];
+ argtype = lvalue_type (arg);
+
+ if (i == 0)
+ {
+ t = build_identity_conv (argtype, NULL_TREE);
+ t = build_conv (ck_user, totype, t);
+ /* Leave the 'cand' field null; we'll figure out the conversion in
+ convert_like if this candidate is chosen. */
+ convert_type = totype;
+ }
+ else if (parmnode == void_list_node)
+ break;
+ else if (parmnode)
+ {
+ t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg,
+ /*c_cast_p=*/false, flags, complain);
+ convert_type = TREE_VALUE (parmnode);
+ }
+ else
+ {
+ t = build_identity_conv (argtype, arg);
+ t->ellipsis_p = true;
+ convert_type = argtype;
+ }
+
+ convs[i] = t;
+ if (! t)
+ break;
+
+ if (t->bad_p)
+ {
+ viable = -1;
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, arg, convert_type,
+ EXPR_LOCATION (arg));
+ }
+
+ if (i == 0)
+ continue;
+
+ if (parmnode)
+ parmnode = TREE_CHAIN (parmnode);
+ }
+
+ if (i < len
+ || ! sufficient_parms_p (parmnode))
+ {
+ int remaining = remaining_arguments (parmnode);
+ viable = 0;
+ reason = arity_rejection (NULL_TREE, i + remaining, len);
+ }
+
+ return add_candidate (candidates, totype, obj, arglist, len, convs,
+ access_path, conversion_path, viable, reason, flags);
+}
+
+static void
+build_builtin_candidate (struct z_candidate **candidates, tree fnname,
+ tree type1, tree type2, const vec<tree,va_gc> &args,
+ tree *argtypes, int flags, tsubst_flags_t complain)
+{
+ conversion *t;
+ conversion **convs;
+ size_t num_convs;
+ int viable = 1;
+ tree types[2];
+ struct rejection_reason *reason = NULL;
+
+ types[0] = type1;
+ types[1] = type2;
+
+ num_convs = args.length ();
+ convs = alloc_conversions (num_convs);
+
+ /* TRUTH_*_EXPR do "contextual conversion to bool", which means explicit
+ conversion ops are allowed. We handle that here by just checking for
+ boolean_type_node because other operators don't ask for it. COND_EXPR
+ also does contextual conversion to bool for the first operand, but we
+ handle that in build_conditional_expr, and type1 here is operand 2. */
+ if (type1 != boolean_type_node)
+ flags |= LOOKUP_ONLYCONVERTING;
+
+ for (unsigned i = 0; i < 2 && i < num_convs; ++i)
+ {
+ t = implicit_conversion (types[i], argtypes[i], args[i],
+ /*c_cast_p=*/false, flags, complain);
+ if (! t)
+ {
+ viable = 0;
+ /* We need something for printing the candidate. */
+ t = build_identity_conv (types[i], NULL_TREE);
+ reason = arg_conversion_rejection (NULL_TREE, i, argtypes[i],
+ types[i], EXPR_LOCATION (args[i]));
+ }
+ else if (t->bad_p)
+ {
+ viable = 0;
+ reason = bad_arg_conversion_rejection (NULL_TREE, i, args[i],
+ types[i],
+ EXPR_LOCATION (args[i]));
+ }
+ convs[i] = t;
+ }
+
+ /* For COND_EXPR we rearranged the arguments; undo that now. */
+ if (num_convs == 3)
+ {
+ convs[2] = convs[1];
+ convs[1] = convs[0];
+ t = implicit_conversion (boolean_type_node, argtypes[2], args[2],
+ /*c_cast_p=*/false, flags,
+ complain);
+ if (t)
+ convs[0] = t;
+ else
+ {
+ viable = 0;
+ reason = arg_conversion_rejection (NULL_TREE, 0, argtypes[2],
+ boolean_type_node,
+ EXPR_LOCATION (args[2]));
+ }
+ }
+
+ add_candidate (candidates, fnname, /*first_arg=*/NULL_TREE, /*args=*/NULL,
+ num_convs, convs,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE,
+ viable, reason, flags);
+}
+
+static bool
+is_complete (tree t)
+{
+ return COMPLETE_TYPE_P (complete_type (t));
+}
+
+/* Returns nonzero if TYPE is a promoted arithmetic type. */
+
+static bool
+promoted_arithmetic_type_p (tree type)
+{
+ /* [over.built]
+
+ In this section, the term promoted integral type is used to refer
+ to those integral types which are preserved by integral promotion
+ (including e.g. int and long but excluding e.g. char).
+ Similarly, the term promoted arithmetic type refers to promoted
+ integral types plus floating types. */
+ return ((CP_INTEGRAL_TYPE_P (type)
+ && same_type_p (type_promotes_to (type), type))
+ || TREE_CODE (type) == REAL_TYPE);
+}
+
+/* Create any builtin operator overload candidates for the operator in
+ question given the converted operand types TYPE1 and TYPE2. The other
+ args are passed through from add_builtin_candidates to
+ build_builtin_candidate.
+
+ TYPE1 and TYPE2 may not be permissible, and we must filter them.
+ If CODE is requires candidates operands of the same type of the kind
+ of which TYPE1 and TYPE2 are, we add both candidates
+ CODE (TYPE1, TYPE1) and CODE (TYPE2, TYPE2). */
+
+static void
+add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname, tree type1,
+ tree type2, vec<tree,va_gc> &args, tree *argtypes,
+ int flags, tsubst_flags_t complain)
+{
+ switch (code)
+ {
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ args[1] = integer_zero_node;
+ type2 = integer_type_node;
+ break;
+ default:
+ break;
+ }
+
+ switch (code)
+ {
+
+/* 4 For every pair (T, VQ), where T is an arithmetic type other than bool,
+ and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ VQ T& operator++(VQ T&);
+ T operator++(VQ T&, int);
+ 5 For every pair (T, VQ), where T is an arithmetic type other than bool,
+ and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ VQ T& operator--(VQ T&);
+ T operator--(VQ T&, int);
+ 6 For every pair (T, VQ), where T is a cv-qualified or cv-unqualified object
+ type, and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ T*VQ& operator++(T*VQ&);
+ T*VQ& operator--(T*VQ&);
+ T* operator++(T*VQ&, int);
+ T* operator--(T*VQ&, int); */
+
+ case POSTDECREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ if (TREE_CODE (type1) == BOOLEAN_TYPE)
+ return;
+ /* FALLTHRU */
+ case POSTINCREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ /* P0002R1, Remove deprecated operator++(bool) added "other than bool"
+ to p4. */
+ if (TREE_CODE (type1) == BOOLEAN_TYPE && cxx_dialect >= cxx17)
+ return;
+ if (ARITHMETIC_TYPE_P (type1) || TYPE_PTROB_P (type1))
+ {
+ type1 = build_reference_type (type1);
+ break;
+ }
+ return;
+
+/* 7 For every cv-qualified or cv-unqualified object type T, there
+ exist candidate operator functions of the form
+
+ T& operator*(T*);
+
+
+ 8 For every function type T that does not have cv-qualifiers or
+ a ref-qualifier, there exist candidate operator functions of the form
+ T& operator*(T*); */
+
+ case INDIRECT_REF:
+ if (TYPE_PTR_P (type1)
+ && (TYPE_PTROB_P (type1)
+ || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE))
+ break;
+ return;
+
+/* 9 For every type T, there exist candidate operator functions of the form
+ T* operator+(T*);
+
+ 10 For every floating-point or promoted integral type T, there exist
+ candidate operator functions of the form
+ T operator+(T);
+ T operator-(T); */
+
+ case UNARY_PLUS_EXPR: /* unary + */
+ if (TYPE_PTR_P (type1))
+ break;
+ /* FALLTHRU */
+ case NEGATE_EXPR:
+ if (ARITHMETIC_TYPE_P (type1))
+ break;
+ return;
+
+/* 11 For every promoted integral type T, there exist candidate operator
+ functions of the form
+ T operator~(T); */
+
+ case BIT_NOT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1))
+ break;
+ return;
+
+/* 12 For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type, C1
+ is the same type as C2 or is a derived class of C2, and T is an object
+ type or a function type there exist candidate operator functions of the
+ form
+ CV12 T& operator->*(CV1 C1*, CV2 T C2::*);
+ where CV12 is the union of CV1 and CV2. */
+
+ case MEMBER_REF:
+ if (TYPE_PTR_P (type1) && TYPE_PTRMEM_P (type2))
+ {
+ tree c1 = TREE_TYPE (type1);
+ tree c2 = TYPE_PTRMEM_CLASS_TYPE (type2);
+
+ if (MAYBE_CLASS_TYPE_P (c1) && DERIVED_FROM_P (c2, c1)
+ && (TYPE_PTRMEMFUNC_P (type2)
+ || is_complete (TYPE_PTRMEM_POINTED_TO_TYPE (type2))))
+ break;
+ }
+ return;
+
+/* 13 For every pair of types L and R, where each of L and R is a floating-point
+ or promoted integral type, there exist candidate operator functions of the
+ form
+ LR operator*(L, R);
+ LR operator/(L, R);
+ LR operator+(L, R);
+ LR operator-(L, R);
+ bool operator<(L, R);
+ bool operator>(L, R);
+ bool operator<=(L, R);
+ bool operator>=(L, R);
+ bool operator==(L, R);
+ bool operator!=(L, R);
+ where LR is the result of the usual arithmetic conversions between
+ types L and R.
+
+ 14 For every integral type T there exists a candidate operator function of
+ the form
+
+ std::strong_ordering operator<=>(T, T);
+
+ 15 For every pair of floating-point types L and R, there exists a candidate
+ operator function of the form
+
+ std::partial_ordering operator<=>(L, R);
+
+ 16 For every cv-qualified or cv-unqualified object type T there exist
+ candidate operator functions of the form
+ T* operator+(T*, std::ptrdiff_t);
+ T& operator[](T*, std::ptrdiff_t);
+ T* operator-(T*, std::ptrdiff_t);
+ T* operator+(std::ptrdiff_t, T*);
+ T& operator[](std::ptrdiff_t, T*);
+
+ 17 For every T, where T is a pointer to object type, there exist candidate
+ operator functions of the form
+ std::ptrdiff_t operator-(T, T);
+
+ 18 For every T, where T is an enumeration type or a pointer type, there
+ exist candidate operator functions of the form
+ bool operator<(T, T);
+ bool operator>(T, T);
+ bool operator<=(T, T);
+ bool operator>=(T, T);
+ bool operator==(T, T);
+ bool operator!=(T, T);
+ R operator<=>(T, T);
+
+ where R is the result type specified in [expr.spaceship].
+
+ 19 For every T, where T is a pointer-to-member type or std::nullptr_t,
+ there exist candidate operator functions of the form
+ bool operator==(T, T);
+ bool operator!=(T, T); */
+
+ case MINUS_EXPR:
+ if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2))
+ break;
+ if (TYPE_PTROB_P (type1)
+ && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ /* FALLTHRU */
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ return;
+
+ /* This isn't exactly what's specified above for operator<=>, but it's
+ close enough. In particular, we don't care about the return type
+ specified above; it doesn't participate in overload resolution and it
+ doesn't affect the semantics of the built-in operator. */
+ case SPACESHIP_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2)))
+ break;
+ if (NULLPTR_TYPE_P (type1) && NULLPTR_TYPE_P (type2))
+ break;
+ if (TYPE_PTRMEM_P (type1) && null_ptr_cst_p (args[1]))
+ {
+ type2 = type1;
+ break;
+ }
+ if (TYPE_PTRMEM_P (type2) && null_ptr_cst_p (args[0]))
+ {
+ type1 = type2;
+ break;
+ }
+ /* Fall through. */
+ case LT_EXPR:
+ case GT_EXPR:
+ case LE_EXPR:
+ case GE_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ if (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ break;
+ if (TREE_CODE (type1) == ENUMERAL_TYPE
+ && TREE_CODE (type2) == ENUMERAL_TYPE)
+ break;
+ if (TYPE_PTR_P (type1)
+ && null_ptr_cst_p (args[1]))
+ {
+ type2 = type1;
+ break;
+ }
+ if (null_ptr_cst_p (args[0])
+ && TYPE_PTR_P (type2))
+ {
+ type1 = type2;
+ break;
+ }
+ return;
+
+ case PLUS_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ /* FALLTHRU */
+ case ARRAY_REF:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && TYPE_PTROB_P (type2))
+ {
+ type1 = ptrdiff_type_node;
+ break;
+ }
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ return;
+
+/* 18For every pair of promoted integral types L and R, there exist candi-
+ date operator functions of the form
+ LR operator%(L, R);
+ LR operator&(L, R);
+ LR operator^(L, R);
+ LR operator|(L, R);
+ L operator<<(L, R);
+ L operator>>(L, R);
+ where LR is the result of the usual arithmetic conversions between
+ types L and R. */
+
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ break;
+ return;
+
+/* 19For every triple L, VQ, R), where L is an arithmetic or enumeration
+ type, VQ is either volatile or empty, and R is a promoted arithmetic
+ type, there exist candidate operator functions of the form
+ VQ L& operator=(VQ L&, R);
+ VQ L& operator*=(VQ L&, R);
+ VQ L& operator/=(VQ L&, R);
+ VQ L& operator+=(VQ L&, R);
+ VQ L& operator-=(VQ L&, R);
+
+ 20For every pair T, VQ), where T is any type and VQ is either volatile
+ or empty, there exist candidate operator functions of the form
+ T*VQ& operator=(T*VQ&, T*);
+
+ 21For every pair T, VQ), where T is a pointer to member type and VQ is
+ either volatile or empty, there exist candidate operator functions of
+ the form
+ VQ T& operator=(VQ T&, T);
+
+ 22For every triple T, VQ, I), where T is a cv-qualified or cv-
+ unqualified complete object type, VQ is either volatile or empty, and
+ I is a promoted integral type, there exist candidate operator func-
+ tions of the form
+ T*VQ& operator+=(T*VQ&, I);
+ T*VQ& operator-=(T*VQ&, I);
+
+ 23For every triple L, VQ, R), where L is an integral or enumeration
+ type, VQ is either volatile or empty, and R is a promoted integral
+ type, there exist candidate operator functions of the form
+
+ VQ L& operator%=(VQ L&, R);
+ VQ L& operator<<=(VQ L&, R);
+ VQ L& operator>>=(VQ L&, R);
+ VQ L& operator&=(VQ L&, R);
+ VQ L& operator^=(VQ L&, R);
+ VQ L& operator|=(VQ L&, R); */
+
+ case MODIFY_EXPR:
+ switch (code2)
+ {
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ if (TYPE_PTROB_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ {
+ type2 = ptrdiff_type_node;
+ break;
+ }
+ /* FALLTHRU */
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ return;
+
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type1) && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type2))
+ break;
+ return;
+
+ case NOP_EXPR:
+ if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2))
+ break;
+ if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2))
+ || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
+ || ((TYPE_PTRMEMFUNC_P (type1)
+ || TYPE_PTR_P (type1))
+ && null_ptr_cst_p (args[1])))
+ {
+ type2 = type1;
+ break;
+ }
+ return;
+
+ default:
+ gcc_unreachable ();
+ }
+ type1 = build_reference_type (type1);
+ break;
+
+ case COND_EXPR:
+ /* [over.built]
+
+ For every pair of promoted arithmetic types L and R, there
+ exist candidate operator functions of the form
+
+ LR operator?(bool, L, R);
+
+ where LR is the result of the usual arithmetic conversions
+ between types L and R.
+
+ For every type T, where T is a pointer or pointer-to-member
+ type, there exist candidate operator functions of the form T
+ operator?(bool, T, T); */
+
+ if (promoted_arithmetic_type_p (type1)
+ && promoted_arithmetic_type_p (type2))
+ /* That's OK. */
+ break;
+
+ /* Otherwise, the types should be pointers. */
+ if (!TYPE_PTR_OR_PTRMEM_P (type1) || !TYPE_PTR_OR_PTRMEM_P (type2))
+ return;
+
+ /* We don't check that the two types are the same; the logic
+ below will actually create two candidates; one in which both
+ parameter types are TYPE1, and one in which both parameter
+ types are TYPE2. */
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ if (ARITHMETIC_TYPE_P (type1))
+ break;
+ return;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Make sure we don't create builtin candidates with dependent types. */
+ bool u1 = uses_template_parms (type1);
+ bool u2 = type2 ? uses_template_parms (type2) : false;
+ if (u1 || u2)
+ {
+ /* Try to recover if one of the types is non-dependent. But if
+ there's only one type, there's nothing we can do. */
+ if (!type2)
+ return;
+ /* And we lose if both are dependent. */
+ if (u1 && u2)
+ return;
+ /* Or if they have different forms. */
+ if (TREE_CODE (type1) != TREE_CODE (type2))
+ return;
+
+ if (u1 && !u2)
+ type1 = type2;
+ else if (u2 && !u1)
+ type2 = type1;
+ }
+
+ /* If we're dealing with two pointer types or two enumeral types,
+ we need candidates for both of them. */
+ if (type2 && !same_type_p (type1, type2)
+ && TREE_CODE (type1) == TREE_CODE (type2)
+ && (TYPE_REF_P (type1)
+ || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))
+ || (TYPE_PTRDATAMEM_P (type1) && TYPE_PTRDATAMEM_P (type2))
+ || TYPE_PTRMEMFUNC_P (type1)
+ || MAYBE_CLASS_TYPE_P (type1)
+ || TREE_CODE (type1) == ENUMERAL_TYPE))
+ {
+ if (TYPE_PTR_OR_PTRMEM_P (type1))
+ {
+ tree cptype = composite_pointer_type (input_location,
+ type1, type2,
+ error_mark_node,
+ error_mark_node,
+ CPO_CONVERSION,
+ tf_none);
+ if (cptype != error_mark_node)
+ {
+ build_builtin_candidate
+ (candidates, fnname, cptype, cptype, args, argtypes,
+ flags, complain);
+ return;
+ }
+ }
+
+ build_builtin_candidate
+ (candidates, fnname, type1, type1, args, argtypes, flags, complain);
+ build_builtin_candidate
+ (candidates, fnname, type2, type2, args, argtypes, flags, complain);
+ return;
+ }
+
+ build_builtin_candidate
+ (candidates, fnname, type1, type2, args, argtypes, flags, complain);
+}
+
+tree
+type_decays_to (tree type)
+{
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return build_pointer_type (TREE_TYPE (type));
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ return build_pointer_type (type);
+ return type;
+}
+
+/* There are three conditions of builtin candidates:
+
+ 1) bool-taking candidates. These are the same regardless of the input.
+ 2) pointer-pair taking candidates. These are generated for each type
+ one of the input types converts to.
+ 3) arithmetic candidates. According to the standard, we should generate
+ all of these, but I'm trying not to...
+
+ Here we generate a superset of the possible candidates for this particular
+ case. That is a subset of the full set the standard defines, plus some
+ other cases which the standard disallows. add_builtin_candidate will
+ filter out the invalid set. */
+
+static void
+add_builtin_candidates (struct z_candidate **candidates, enum tree_code code,
+ enum tree_code code2, tree fnname,
+ vec<tree, va_gc> *argv,
+ int flags, tsubst_flags_t complain)
+{
+ int ref1;
+ int enum_p = 0;
+ tree type, argtypes[3], t;
+ /* TYPES[i] is the set of possible builtin-operator parameter types
+ we will consider for the Ith argument. */
+ vec<tree, va_gc> *types[2];
+ unsigned ix;
+ vec<tree, va_gc> &args = *argv;
+ unsigned len = args.length ();
+
+ for (unsigned i = 0; i < len; ++i)
+ {
+ if (args[i])
+ argtypes[i] = unlowered_expr_type (args[i]);
+ else
+ argtypes[i] = NULL_TREE;
+ }
+
+ switch (code)
+ {
+/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type,
+ and VQ is either volatile or empty, there exist candidate operator
+ functions of the form
+ VQ T& operator++(VQ T&); */
+
+ case POSTINCREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case MODIFY_EXPR:
+ ref1 = 1;
+ break;
+
+/* 24There also exist candidate operator functions of the form
+ bool operator!(bool);
+ bool operator&&(bool, bool);
+ bool operator||(bool, bool); */
+
+ case TRUTH_NOT_EXPR:
+ build_builtin_candidate
+ (candidates, fnname, boolean_type_node,
+ NULL_TREE, args, argtypes, flags, complain);
+ return;
+
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ build_builtin_candidate
+ (candidates, fnname, boolean_type_node,
+ boolean_type_node, args, argtypes, flags, complain);
+ return;
+
+ case ADDR_EXPR:
+ case COMPOUND_EXPR:
+ case COMPONENT_REF:
+ case CO_AWAIT_EXPR:
+ return;
+
+ case COND_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case SPACESHIP_EXPR:
+ enum_p = 1;
+ /* Fall through. */
+
+ default:
+ ref1 = 0;
+ }
+
+ types[0] = make_tree_vector ();
+ types[1] = make_tree_vector ();
+
+ if (len == 3)
+ len = 2;
+ for (unsigned i = 0; i < len; ++i)
+ {
+ if (MAYBE_CLASS_TYPE_P (argtypes[i]))
+ {
+ tree convs;
+
+ if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR)
+ return;
+
+ convs = lookup_conversions (argtypes[i]);
+
+ if (code == COND_EXPR)
+ {
+ if (lvalue_p (args[i]))
+ vec_safe_push (types[i], build_reference_type (argtypes[i]));
+
+ vec_safe_push (types[i], TYPE_MAIN_VARIANT (argtypes[i]));
+ }
+
+ else if (! convs)
+ return;
+
+ for (; convs; convs = TREE_CHAIN (convs))
+ {
+ type = TREE_TYPE (convs);
+
+ if (i == 0 && ref1
+ && (!TYPE_REF_P (type)
+ || CP_TYPE_CONST_P (TREE_TYPE (type))))
+ continue;
+
+ if (code == COND_EXPR && TYPE_REF_P (type))
+ vec_safe_push (types[i], type);
+
+ type = non_reference (type);
+ if (i != 0 || ! ref1)
+ {
+ type = cv_unqualified (type_decays_to (type));
+ if (enum_p && TREE_CODE (type) == ENUMERAL_TYPE)
+ vec_safe_push (types[i], type);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ }
+
+ if (! vec_member (type, types[i]))
+ vec_safe_push (types[i], type);
+ }
+ }
+ else
+ {
+ if (code == COND_EXPR && lvalue_p (args[i]))
+ vec_safe_push (types[i], build_reference_type (argtypes[i]));
+ type = non_reference (argtypes[i]);
+ if (i != 0 || ! ref1)
+ {
+ type = cv_unqualified (type_decays_to (type));
+ if (enum_p && UNSCOPED_ENUM_P (type))
+ vec_safe_push (types[i], type);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+ }
+ vec_safe_push (types[i], type);
+ }
+ }
+
+ /* Run through the possible parameter types of both arguments,
+ creating candidates with those parameter types. */
+ FOR_EACH_VEC_ELT_REVERSE (*(types[0]), ix, t)
+ {
+ unsigned jx;
+ tree u;
+
+ if (!types[1]->is_empty ())
+ FOR_EACH_VEC_ELT_REVERSE (*(types[1]), jx, u)
+ add_builtin_candidate
+ (candidates, code, code2, fnname, t,
+ u, args, argtypes, flags, complain);
+ else
+ add_builtin_candidate
+ (candidates, code, code2, fnname, t,
+ NULL_TREE, args, argtypes, flags, complain);
+ }
+
+ release_tree_vector (types[0]);
+ release_tree_vector (types[1]);
+}
+
+
+/* If TMPL can be successfully instantiated as indicated by
+ EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES.
+
+ TMPL is the template. EXPLICIT_TARGS are any explicit template
+ arguments. ARGLIST is the arguments provided at the call-site.
+ This does not change ARGLIST. The RETURN_TYPE is the desired type
+ for conversion operators. If OBJ is NULL_TREE, FLAGS and CTYPE are
+ as for add_function_candidate. If an OBJ is supplied, FLAGS and
+ CTYPE are ignored, and OBJ is as for add_conv_candidate.
+
+ SHORTCUT_BAD_CONVS is as in add_function_candidate. */
+
+static struct z_candidate*
+add_template_candidate_real (struct z_candidate **candidates, tree tmpl,
+ tree ctype, tree explicit_targs, tree first_arg,
+ const vec<tree, va_gc> *arglist, tree return_type,
+ tree access_path, tree conversion_path,
+ int flags, tree obj, unification_kind_t strict,
+ bool shortcut_bad_convs, tsubst_flags_t complain)
+{
+ int ntparms = DECL_NTPARMS (tmpl);
+ tree targs = make_tree_vec (ntparms);
+ unsigned int len = vec_safe_length (arglist);
+ unsigned int nargs = (first_arg == NULL_TREE ? 0 : 1) + len;
+ unsigned int skip_without_in_chrg = 0;
+ tree first_arg_without_in_chrg = first_arg;
+ tree *args_without_in_chrg;
+ unsigned int nargs_without_in_chrg;
+ unsigned int ia, ix;
+ tree arg;
+ struct z_candidate *cand;
+ tree fn;
+ struct rejection_reason *reason = NULL;
+ int errs;
+ conversion **convs = NULL;
+
+ /* We don't do deduction on the in-charge parameter, the VTT
+ parameter or 'this'. */
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl))
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else if (return_type && strict == DEDUCE_CALL)
+ /* We're deducing for a call to the result of a template conversion
+ function, so the args don't contain 'this'; leave them alone. */;
+ else
+ ++skip_without_in_chrg;
+ }
+
+ if ((DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (tmpl)
+ || DECL_BASE_CONSTRUCTOR_P (tmpl))
+ && CLASSTYPE_VBASECLASSES (DECL_CONTEXT (tmpl)))
+ {
+ if (first_arg_without_in_chrg != NULL_TREE)
+ first_arg_without_in_chrg = NULL_TREE;
+ else
+ ++skip_without_in_chrg;
+ }
+
+ if (len < skip_without_in_chrg)
+ return NULL;
+
+ if (DECL_CONSTRUCTOR_P (tmpl) && nargs == 2
+ && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (first_arg),
+ TREE_TYPE ((*arglist)[0])))
+ {
+ /* 12.8/6 says, "A declaration of a constructor for a class X is
+ ill-formed if its first parameter is of type (optionally cv-qualified)
+ X and either there are no other parameters or else all other
+ parameters have default arguments. A member function template is never
+ instantiated to produce such a constructor signature."
+
+ So if we're trying to copy an object of the containing class, don't
+ consider a template constructor that has a first parameter type that
+ is just a template parameter, as we would deduce a signature that we
+ would then reject in the code below. */
+ if (tree firstparm = FUNCTION_FIRST_USER_PARMTYPE (tmpl))
+ {
+ firstparm = TREE_VALUE (firstparm);
+ if (PACK_EXPANSION_P (firstparm))
+ firstparm = PACK_EXPANSION_PATTERN (firstparm);
+ if (TREE_CODE (firstparm) == TEMPLATE_TYPE_PARM)
+ {
+ gcc_assert (!explicit_targs);
+ reason = invalid_copy_with_fn_template_rejection ();
+ goto fail;
+ }
+ }
+ }
+
+ nargs_without_in_chrg = ((first_arg_without_in_chrg != NULL_TREE ? 1 : 0)
+ + (len - skip_without_in_chrg));
+ args_without_in_chrg = XALLOCAVEC (tree, nargs_without_in_chrg);
+ ia = 0;
+ if (first_arg_without_in_chrg != NULL_TREE)
+ {
+ args_without_in_chrg[ia] = first_arg_without_in_chrg;
+ ++ia;
+ }
+ for (ix = skip_without_in_chrg;
+ vec_safe_iterate (arglist, ix, &arg);
+ ++ix)
+ {
+ args_without_in_chrg[ia] = arg;
+ ++ia;
+ }
+ gcc_assert (ia == nargs_without_in_chrg);
+
+ if (!obj && explicit_targs)
+ {
+ /* Check that there's no obvious arity mismatch before proceeding with
+ deduction. This avoids substituting explicit template arguments
+ into the template (which could result in an error outside the
+ immediate context) when the resulting candidate would be unviable
+ anyway. */
+ int min_arity = 0, max_arity = 0;
+ tree parms = TYPE_ARG_TYPES (TREE_TYPE (tmpl));
+ parms = skip_artificial_parms_for (tmpl, parms);
+ for (; parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (!parms || PACK_EXPANSION_P (TREE_VALUE (parms)))
+ {
+ max_arity = -1;
+ break;
+ }
+ if (TREE_PURPOSE (parms))
+ /* A parameter with a default argument. */
+ ++max_arity;
+ else
+ ++min_arity, ++max_arity;
+ }
+ if (ia < (unsigned)min_arity)
+ {
+ /* Too few arguments. */
+ reason = arity_rejection (NULL_TREE, min_arity, ia,
+ /*least_p=*/(max_arity == -1));
+ goto fail;
+ }
+ else if (max_arity != -1 && ia > (unsigned)max_arity)
+ {
+ /* Too many arguments. */
+ reason = arity_rejection (NULL_TREE, max_arity, ia);
+ goto fail;
+ }
+ }
+
+ errs = errorcount+sorrycount;
+ if (!obj)
+ {
+ convs = alloc_conversions (nargs);
+
+ if (shortcut_bad_convs
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (tmpl)
+ && !DECL_CONSTRUCTOR_P (tmpl))
+ {
+ /* Check the 'this' conversion before proceeding with deduction.
+ This is effectively an extension of the DR 1391 resolution
+ that we perform in check_non_deducible_conversions, though it's
+ convenient to do this extra check here instead of there. */
+ tree parmtype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (tmpl)));
+ tree argtype = lvalue_type (first_arg);
+ tree arg = first_arg;
+ conversion *t = build_this_conversion (tmpl, ctype,
+ parmtype, argtype, arg,
+ flags, complain);
+ convs[0] = t;
+ if (t->bad_p)
+ {
+ reason = bad_arg_conversion_rejection (first_arg, 0,
+ arg, parmtype,
+ EXPR_LOCATION (arg));
+ goto fail;
+ }
+ }
+ }
+ fn = fn_type_unification (tmpl, explicit_targs, targs,
+ args_without_in_chrg,
+ nargs_without_in_chrg,
+ return_type, strict, flags, convs,
+ false, complain & tf_decltype);
+
+ if (fn == error_mark_node)
+ {
+ /* Don't repeat unification later if it already resulted in errors. */
+ if (errorcount+sorrycount == errs)
+ reason = template_unification_rejection (tmpl, explicit_targs,
+ targs, args_without_in_chrg,
+ nargs_without_in_chrg,
+ return_type, strict, flags);
+ else
+ reason = template_unification_error_rejection ();
+ goto fail;
+ }
+
+ /* Now the explicit specifier might have been deduced; check if this
+ declaration is explicit. If it is and we're ignoring non-converting
+ constructors, don't add this function to the set of candidates. */
+ if ((flags & LOOKUP_ONLYCONVERTING) && DECL_NONCONVERTING_P (fn))
+ return NULL;
+
+ if (DECL_CONSTRUCTOR_P (fn) && nargs == 2)
+ {
+ tree arg_types = FUNCTION_FIRST_USER_PARMTYPE (fn);
+ if (arg_types && same_type_p (TYPE_MAIN_VARIANT (TREE_VALUE (arg_types)),
+ ctype))
+ {
+ /* We're trying to produce a constructor with a prohibited signature,
+ as discussed above; handle here any cases we didn't catch then,
+ such as X(X<T>). */
+ reason = invalid_copy_with_fn_template_rejection ();
+ goto fail;
+ }
+ }
+
+ if (obj != NULL_TREE)
+ /* Aha, this is a conversion function. */
+ cand = add_conv_candidate (candidates, fn, obj, arglist,
+ access_path, conversion_path, complain);
+ else
+ cand = add_function_candidate (candidates, fn, ctype,
+ first_arg, arglist, access_path,
+ conversion_path, flags, convs,
+ shortcut_bad_convs, complain);
+ if (DECL_TI_TEMPLATE (fn) != tmpl)
+ /* This situation can occur if a member template of a template
+ class is specialized. Then, instantiate_template might return
+ an instantiation of the specialization, in which case the
+ DECL_TI_TEMPLATE field will point at the original
+ specialization. For example:
+
+ template <class T> struct S { template <class U> void f(U);
+ template <> void f(int) {}; };
+ S<double> sd;
+ sd.f(3);
+
+ Here, TMPL will be template <class U> S<double>::f(U).
+ And, instantiate template will give us the specialization
+ template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field
+ for this will point at template <class T> template <> S<T>::f(int),
+ so that we can find the definition. For the purposes of
+ overload resolution, however, we want the original TMPL. */
+ cand->template_decl = build_template_info (tmpl, targs);
+ else
+ cand->template_decl = DECL_TEMPLATE_INFO (fn);
+ cand->explicit_targs = explicit_targs;
+
+ return cand;
+ fail:
+ int viable = (reason->code == rr_bad_arg_conversion ? -1 : 0);
+ return add_candidate (candidates, tmpl, first_arg, arglist, nargs, convs,
+ access_path, conversion_path, viable, reason, flags);
+}
+
+
+static struct z_candidate *
+add_template_candidate (struct z_candidate **candidates, tree tmpl, tree ctype,
+ tree explicit_targs, tree first_arg,
+ const vec<tree, va_gc> *arglist, tree return_type,
+ tree access_path, tree conversion_path, int flags,
+ unification_kind_t strict, bool shortcut_bad_convs,
+ tsubst_flags_t complain)
+{
+ return
+ add_template_candidate_real (candidates, tmpl, ctype,
+ explicit_targs, first_arg, arglist,
+ return_type, access_path, conversion_path,
+ flags, NULL_TREE, strict, shortcut_bad_convs,
+ complain);
+}
+
+/* Create an overload candidate for the conversion function template TMPL,
+ returning RETURN_TYPE, which will be invoked for expression OBJ to produce a
+ pointer-to-function which will in turn be called with the argument list
+ ARGLIST, and add it to CANDIDATES. This does not change ARGLIST. FLAGS is
+ passed on to implicit_conversion. */
+
+static struct z_candidate *
+add_template_conv_candidate (struct z_candidate **candidates, tree tmpl,
+ tree obj,
+ const vec<tree, va_gc> *arglist,
+ tree return_type, tree access_path,
+ tree conversion_path, tsubst_flags_t complain)
+{
+ /* Making this work broke PR 71117 and 85118, so until the committee resolves
+ core issue 2189, let's disable this candidate if there are any call
+ operators. */
+ if (*candidates)
+ return NULL;
+
+ return
+ add_template_candidate_real (candidates, tmpl, NULL_TREE, NULL_TREE,
+ NULL_TREE, arglist, return_type, access_path,
+ conversion_path, 0, obj, DEDUCE_CALL,
+ /*shortcut_bad_convs=*/false, complain);
+}
+
+/* The CANDS are the set of candidates that were considered for
+ overload resolution. Return the set of viable candidates, or CANDS
+ if none are viable. If any of the candidates were viable, set
+ *ANY_VIABLE_P to true. STRICT_P is true if a candidate should be
+ considered viable only if it is strictly viable. */
+
+static struct z_candidate*
+splice_viable (struct z_candidate *cands,
+ bool strict_p,
+ bool *any_viable_p)
+{
+ struct z_candidate *viable;
+ struct z_candidate **last_viable;
+ struct z_candidate **cand;
+ bool found_strictly_viable = false;
+
+ /* Be strict inside templates, since build_over_call won't actually
+ do the conversions to get pedwarns. */
+ if (processing_template_decl)
+ strict_p = true;
+
+ viable = NULL;
+ last_viable = &viable;
+ *any_viable_p = false;
+
+ cand = &cands;
+ while (*cand)
+ {
+ struct z_candidate *c = *cand;
+ if (!strict_p
+ && (c->viable == 1 || TREE_CODE (c->fn) == TEMPLATE_DECL))
+ {
+ /* Be strict in the presence of a viable candidate. Also if
+ there are template candidates, so that we get deduction errors
+ for them instead of silently preferring a bad conversion. */
+ strict_p = true;
+ if (viable && !found_strictly_viable)
+ {
+ /* Put any spliced near matches back onto the main list so
+ that we see them if there is no strict match. */
+ *any_viable_p = false;
+ *last_viable = cands;
+ cands = viable;
+ viable = NULL;
+ last_viable = &viable;
+ }
+ }
+
+ if (strict_p ? c->viable == 1 : c->viable)
+ {
+ *last_viable = c;
+ *cand = c->next;
+ c->next = NULL;
+ last_viable = &c->next;
+ *any_viable_p = true;
+ if (c->viable == 1)
+ found_strictly_viable = true;
+ }
+ else
+ cand = &c->next;
+ }
+
+ return viable ? viable : cands;
+}
+
+static bool
+any_strictly_viable (struct z_candidate *cands)
+{
+ for (; cands; cands = cands->next)
+ if (cands->viable == 1)
+ return true;
+ return false;
+}
+
+/* OBJ is being used in an expression like "OBJ.f (...)". In other
+ words, it is about to become the "this" pointer for a member
+ function call. Take the address of the object. */
+
+static tree
+build_this (tree obj)
+{
+ /* In a template, we are only concerned about the type of the
+ expression, so we can take a shortcut. */
+ if (processing_template_decl)
+ return build_address (obj);
+
+ return cp_build_addr_expr (obj, tf_warning_or_error);
+}
+
+/* Returns true iff functions are equivalent. Equivalent functions are
+ not '==' only if one is a function-local extern function or if
+ both are extern "C". */
+
+static inline int
+equal_functions (tree fn1, tree fn2)
+{
+ if (TREE_CODE (fn1) != TREE_CODE (fn2))
+ return 0;
+ if (TREE_CODE (fn1) == TEMPLATE_DECL)
+ return fn1 == fn2;
+ if (DECL_LOCAL_DECL_P (fn1) || DECL_LOCAL_DECL_P (fn2)
+ || DECL_EXTERN_C_FUNCTION_P (fn1))
+ return decls_match (fn1, fn2);
+ return fn1 == fn2;
+}
+
+/* Print information about a candidate FN being rejected due to INFO. */
+
+static void
+print_conversion_rejection (location_t loc, struct conversion_info *info,
+ tree fn)
+{
+ tree from = info->from;
+ if (!TYPE_P (from))
+ from = lvalue_type (from);
+ if (info->n_arg == -1)
+ {
+ /* Conversion of implicit `this' argument failed. */
+ if (!TYPE_P (info->from))
+ /* A bad conversion for 'this' must be discarding cv-quals. */
+ inform (loc, " passing %qT as %<this%> "
+ "argument discards qualifiers",
+ from);
+ else
+ inform (loc, " no known conversion for implicit "
+ "%<this%> parameter from %qH to %qI",
+ from, info->to_type);
+ }
+ else if (!TYPE_P (info->from))
+ {
+ if (info->n_arg >= 0)
+ inform (loc, " conversion of argument %d would be ill-formed:",
+ info->n_arg + 1);
+ perform_implicit_conversion (info->to_type, info->from,
+ tf_warning_or_error);
+ }
+ else if (info->n_arg == -2)
+ /* Conversion of conversion function return value failed. */
+ inform (loc, " no known conversion from %qH to %qI",
+ from, info->to_type);
+ else
+ {
+ if (TREE_CODE (fn) == FUNCTION_DECL)
+ loc = get_fndecl_argument_location (fn, info->n_arg);
+ inform (loc, " no known conversion for argument %d from %qH to %qI",
+ info->n_arg + 1, from, info->to_type);
+ }
+}
+
+/* Print information about a candidate with WANT parameters and we found
+ HAVE. */
+
+static void
+print_arity_information (location_t loc, unsigned int have, unsigned int want,
+ bool least_p)
+{
+ if (least_p)
+ inform_n (loc, want,
+ " candidate expects at least %d argument, %d provided",
+ " candidate expects at least %d arguments, %d provided",
+ want, have);
+ else
+ inform_n (loc, want,
+ " candidate expects %d argument, %d provided",
+ " candidate expects %d arguments, %d provided",
+ want, have);
+}
+
+/* Print information about one overload candidate CANDIDATE. MSGSTR
+ is the text to print before the candidate itself.
+
+ NOTE: Unlike most diagnostic functions in GCC, MSGSTR is expected
+ to have been run through gettext by the caller. This wart makes
+ life simpler in print_z_candidates and for the translators. */
+
+static void
+print_z_candidate (location_t loc, const char *msgstr,
+ struct z_candidate *candidate)
+{
+ const char *msg = (msgstr == NULL
+ ? ""
+ : ACONCAT ((_(msgstr), " ", NULL)));
+ tree fn = candidate->fn;
+ if (flag_new_inheriting_ctors)
+ fn = strip_inheriting_ctors (fn);
+ location_t cloc = location_of (fn);
+
+ if (identifier_p (fn))
+ {
+ cloc = loc;
+ if (candidate->num_convs == 3)
+ inform (cloc, "%s%<%D(%T, %T, %T)%> (built-in)", msg, fn,
+ candidate->convs[0]->type,
+ candidate->convs[1]->type,
+ candidate->convs[2]->type);
+ else if (candidate->num_convs == 2)
+ inform (cloc, "%s%<%D(%T, %T)%> (built-in)", msg, fn,
+ candidate->convs[0]->type,
+ candidate->convs[1]->type);
+ else
+ inform (cloc, "%s%<%D(%T)%> (built-in)", msg, fn,
+ candidate->convs[0]->type);
+ }
+ else if (TYPE_P (fn))
+ inform (cloc, "%s%qT (conversion)", msg, fn);
+ else if (candidate->viable == -1)
+ inform (cloc, "%s%#qD (near match)", msg, fn);
+ else if (DECL_DELETED_FN (fn))
+ inform (cloc, "%s%#qD (deleted)", msg, fn);
+ else if (candidate->reversed ())
+ inform (cloc, "%s%#qD (reversed)", msg, fn);
+ else if (candidate->rewritten ())
+ inform (cloc, "%s%#qD (rewritten)", msg, fn);
+ else
+ inform (cloc, "%s%#qD", msg, fn);
+ if (fn != candidate->fn)
+ {
+ cloc = location_of (candidate->fn);
+ inform (cloc, " inherited here");
+ }
+ /* Give the user some information about why this candidate failed. */
+ if (candidate->reason != NULL)
+ {
+ struct rejection_reason *r = candidate->reason;
+
+ switch (r->code)
+ {
+ case rr_arity:
+ print_arity_information (cloc, r->u.arity.actual,
+ r->u.arity.expected,
+ r->u.arity.least_p);
+ break;
+ case rr_arg_conversion:
+ print_conversion_rejection (cloc, &r->u.conversion, fn);
+ break;
+ case rr_bad_arg_conversion:
+ print_conversion_rejection (cloc, &r->u.bad_conversion, fn);
+ break;
+ case rr_explicit_conversion:
+ inform (cloc, " return type %qT of explicit conversion function "
+ "cannot be converted to %qT with a qualification "
+ "conversion", r->u.conversion.from,
+ r->u.conversion.to_type);
+ break;
+ case rr_template_conversion:
+ inform (cloc, " conversion from return type %qT of template "
+ "conversion function specialization to %qT is not an "
+ "exact match", r->u.conversion.from,
+ r->u.conversion.to_type);
+ break;
+ case rr_template_unification:
+ /* We use template_unification_error_rejection if unification caused
+ actual non-SFINAE errors, in which case we don't need to repeat
+ them here. */
+ if (r->u.template_unification.tmpl == NULL_TREE)
+ {
+ inform (cloc, " substitution of deduced template arguments "
+ "resulted in errors seen above");
+ break;
+ }
+ /* Re-run template unification with diagnostics. */
+ inform (cloc, " template argument deduction/substitution failed:");
+ fn_type_unification (r->u.template_unification.tmpl,
+ r->u.template_unification.explicit_targs,
+ (make_tree_vec
+ (r->u.template_unification.num_targs)),
+ r->u.template_unification.args,
+ r->u.template_unification.nargs,
+ r->u.template_unification.return_type,
+ r->u.template_unification.strict,
+ r->u.template_unification.flags,
+ NULL, true, false);
+ break;
+ case rr_invalid_copy:
+ inform (cloc,
+ " a constructor taking a single argument of its own "
+ "class type is invalid");
+ break;
+ case rr_constraint_failure:
+ diagnose_constraints (cloc, fn, NULL_TREE);
+ break;
+ case rr_inherited_ctor:
+ inform (cloc, " an inherited constructor is not a candidate for "
+ "initialization from an expression of the same or derived "
+ "type");
+ break;
+ case rr_none:
+ default:
+ /* This candidate didn't have any issues or we failed to
+ handle a particular code. Either way... */
+ gcc_unreachable ();
+ }
+ }
+}
+
+static void
+print_z_candidates (location_t loc, struct z_candidate *candidates)
+{
+ struct z_candidate *cand1;
+ struct z_candidate **cand2;
+
+ if (!candidates)
+ return;
+
+ /* Remove non-viable deleted candidates. */
+ cand1 = candidates;
+ for (cand2 = &cand1; *cand2; )
+ {
+ if (TREE_CODE ((*cand2)->fn) == FUNCTION_DECL
+ && !(*cand2)->viable
+ && DECL_DELETED_FN ((*cand2)->fn))
+ *cand2 = (*cand2)->next;
+ else
+ cand2 = &(*cand2)->next;
+ }
+ /* ...if there are any non-deleted ones. */
+ if (cand1)
+ candidates = cand1;
+
+ /* There may be duplicates in the set of candidates. We put off
+ checking this condition as long as possible, since we have no way
+ to eliminate duplicates from a set of functions in less than n^2
+ time. Now we are about to emit an error message, so it is more
+ permissible to go slowly. */
+ for (cand1 = candidates; cand1; cand1 = cand1->next)
+ {
+ tree fn = cand1->fn;
+ /* Skip builtin candidates and conversion functions. */
+ if (!DECL_P (fn))
+ continue;
+ cand2 = &cand1->next;
+ while (*cand2)
+ {
+ if (DECL_P ((*cand2)->fn)
+ && equal_functions (fn, (*cand2)->fn))
+ *cand2 = (*cand2)->next;
+ else
+ cand2 = &(*cand2)->next;
+ }
+ }
+
+ for (; candidates; candidates = candidates->next)
+ print_z_candidate (loc, N_("candidate:"), candidates);
+}
+
+/* USER_SEQ is a user-defined conversion sequence, beginning with a
+ USER_CONV. STD_SEQ is the standard conversion sequence applied to
+ the result of the conversion function to convert it to the final
+ desired type. Merge the two sequences into a single sequence,
+ and return the merged sequence. */
+
+static conversion *
+merge_conversion_sequences (conversion *user_seq, conversion *std_seq)
+{
+ conversion **t;
+ bool bad = user_seq->bad_p;
+
+ gcc_assert (user_seq->kind == ck_user);
+
+ /* Find the end of the second conversion sequence. */
+ for (t = &std_seq; (*t)->kind != ck_identity; t = &((*t)->u.next))
+ {
+ /* The entire sequence is a user-conversion sequence. */
+ (*t)->user_conv_p = true;
+ if (bad)
+ (*t)->bad_p = true;
+ }
+
+ if ((*t)->rvaluedness_matches_p)
+ /* We're binding a reference directly to the result of the conversion.
+ build_user_type_conversion_1 stripped the REFERENCE_TYPE from the return
+ type, but we want it back. */
+ user_seq->type = TREE_TYPE (TREE_TYPE (user_seq->cand->fn));
+
+ /* Replace the identity conversion with the user conversion
+ sequence. */
+ *t = user_seq;
+
+ return std_seq;
+}
+
+/* Handle overload resolution for initializing an object of class type from
+ an initializer list. First we look for a suitable constructor that
+ takes a std::initializer_list; if we don't find one, we then look for a
+ non-list constructor.
+
+ Parameters are as for add_candidates, except that the arguments are in
+ the form of a CONSTRUCTOR (the initializer list) rather than a vector, and
+ the RETURN_TYPE parameter is replaced by TOTYPE, the desired type. */
+
+static void
+add_list_candidates (tree fns, tree first_arg,
+ const vec<tree, va_gc> *args, tree totype,
+ tree explicit_targs, bool template_only,
+ tree conversion_path, tree access_path,
+ int flags,
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
+{
+ gcc_assert (*candidates == NULL);
+
+ /* We're looking for a ctor for list-initialization. */
+ flags |= LOOKUP_LIST_INIT_CTOR;
+ /* And we don't allow narrowing conversions. We also use this flag to
+ avoid the copy constructor call for copy-list-initialization. */
+ flags |= LOOKUP_NO_NARROWING;
+
+ unsigned nart = num_artificial_parms_for (OVL_FIRST (fns)) - 1;
+ tree init_list = (*args)[nart];
+
+ /* Always use the default constructor if the list is empty (DR 990). */
+ if (CONSTRUCTOR_NELTS (init_list) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
+ ;
+ /* If the class has a list ctor, try passing the list as a single
+ argument first, but only consider list ctors. */
+ else if (TYPE_HAS_LIST_CTOR (totype))
+ {
+ flags |= LOOKUP_LIST_ONLY;
+ add_candidates (fns, first_arg, args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates, complain);
+ if (any_strictly_viable (*candidates))
+ return;
+ }
+ else if (CONSTRUCTOR_IS_DESIGNATED_INIT (init_list)
+ && !CP_AGGREGATE_TYPE_P (totype))
+ {
+ if (complain & tf_error)
+ error ("designated initializers cannot be used with a "
+ "non-aggregate type %qT", totype);
+ return;
+ }
+
+ /* Expand the CONSTRUCTOR into a new argument vec. */
+ vec<tree, va_gc> *new_args;
+ vec_alloc (new_args, nart + CONSTRUCTOR_NELTS (init_list));
+ for (unsigned i = 0; i < nart; ++i)
+ new_args->quick_push ((*args)[i]);
+ for (unsigned i = 0; i < CONSTRUCTOR_NELTS (init_list); ++i)
+ new_args->quick_push (CONSTRUCTOR_ELT (init_list, i)->value);
+
+ /* We aren't looking for list-ctors anymore. */
+ flags &= ~LOOKUP_LIST_ONLY;
+ /* We allow more user-defined conversions within an init-list. */
+ flags &= ~LOOKUP_NO_CONVERSION;
+
+ add_candidates (fns, first_arg, new_args, NULL_TREE,
+ explicit_targs, template_only, conversion_path,
+ access_path, flags, candidates, complain);
+}
+
+/* Returns the best overload candidate to perform the requested
+ conversion. This function is used for three the overloading situations
+ described in [over.match.copy], [over.match.conv], and [over.match.ref].
+ If TOTYPE is a REFERENCE_TYPE, we're trying to find a direct binding as
+ per [dcl.init.ref], so we ignore temporary bindings. */
+
+static struct z_candidate *
+build_user_type_conversion_1 (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *candidates, *cand;
+ tree fromtype;
+ tree ctors = NULL_TREE;
+ tree conv_fns = NULL_TREE;
+ conversion *conv = NULL;
+ tree first_arg = NULL_TREE;
+ vec<tree, va_gc> *args = NULL;
+ bool any_viable_p;
+ int convflags;
+
+ if (!expr)
+ return NULL;
+
+ fromtype = TREE_TYPE (expr);
+
+ /* We represent conversion within a hierarchy using RVALUE_CONV and
+ BASE_CONV, as specified by [over.best.ics]; these become plain
+ constructor calls, as specified in [dcl.init]. */
+ gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
+ || !DERIVED_FROM_P (totype, fromtype));
+
+ if (CLASS_TYPE_P (totype))
+ /* Use lookup_fnfields_slot instead of lookup_fnfields to avoid
+ creating a garbage BASELINK; constructors can't be inherited. */
+ ctors = get_class_binding (totype, complete_ctor_identifier);
+
+ tree to_nonref = non_reference (totype);
+ if (MAYBE_CLASS_TYPE_P (fromtype))
+ {
+ if (same_type_ignoring_top_level_qualifiers_p (to_nonref, fromtype) ||
+ (CLASS_TYPE_P (to_nonref) && CLASS_TYPE_P (fromtype)
+ && DERIVED_FROM_P (to_nonref, fromtype)))
+ {
+ /* [class.conv.fct] A conversion function is never used to
+ convert a (possibly cv-qualified) object to the (possibly
+ cv-qualified) same object type (or a reference to it), to a
+ (possibly cv-qualified) base class of that type (or a
+ reference to it)... */
+ }
+ else
+ conv_fns = lookup_conversions (fromtype);
+ }
+
+ candidates = 0;
+ flags |= LOOKUP_NO_CONVERSION;
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ flags |= LOOKUP_NO_NARROWING;
+ /* Prevent add_candidates from treating a non-strictly viable candidate
+ as unviable. */
+ complain |= tf_conv;
+
+ /* It's OK to bind a temporary for converting constructor arguments, but
+ not in converting the return value of a conversion operator. */
+ convflags = ((flags & LOOKUP_NO_TEMP_BIND) | LOOKUP_NO_CONVERSION
+ | (flags & LOOKUP_NO_NARROWING));
+ flags &= ~LOOKUP_NO_TEMP_BIND;
+
+ if (ctors)
+ {
+ int ctorflags = flags;
+
+ first_arg = build_dummy_object (totype);
+
+ /* We should never try to call the abstract or base constructor
+ from here. */
+ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (OVL_FIRST (ctors))
+ && !DECL_HAS_VTT_PARM_P (OVL_FIRST (ctors)));
+
+ args = make_tree_vector_single (expr);
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ /* List-initialization. */
+ add_list_candidates (ctors, first_arg, args, totype, NULL_TREE,
+ false, TYPE_BINFO (totype), TYPE_BINFO (totype),
+ ctorflags, &candidates, complain);
+ }
+ else
+ {
+ add_candidates (ctors, first_arg, args, NULL_TREE, NULL_TREE, false,
+ TYPE_BINFO (totype), TYPE_BINFO (totype),
+ ctorflags, &candidates, complain);
+ }
+
+ for (cand = candidates; cand; cand = cand->next)
+ {
+ cand->second_conv = build_identity_conv (totype, NULL_TREE);
+
+ /* If totype isn't a reference, and LOOKUP_ONLYCONVERTING is
+ set, then this is copy-initialization. In that case, "The
+ result of the call is then used to direct-initialize the
+ object that is the destination of the copy-initialization."
+ [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. */
+ if (!TYPE_REF_P (totype)
+ && cxx_dialect < cxx17
+ && (flags & LOOKUP_ONLYCONVERTING)
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ cand->second_conv
+ = build_conv (ck_rvalue, totype, cand->second_conv);
+ }
+ }
+
+ if (conv_fns)
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ first_arg = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ first_arg = expr;
+ }
+
+ for (; conv_fns; conv_fns = TREE_CHAIN (conv_fns))
+ {
+ tree conversion_path = TREE_PURPOSE (conv_fns);
+ struct z_candidate *old_candidates;
+
+ /* If LOOKUP_NO_CONVERSION, don't consider a conversion function that
+ would need an addional user-defined conversion, i.e. if the return
+ type differs in class-ness from the desired type. So we avoid
+ considering operator bool when calling a copy constructor.
+
+ This optimization avoids the failure in PR97600, and is allowed by
+ [temp.inst]/9: "If the function selected by overload resolution can be
+ determined without instantiating a class template definition, it is
+ unspecified whether that instantiation actually takes place." */
+ tree convtype = non_reference (TREE_TYPE (conv_fns));
+ if ((flags & LOOKUP_NO_CONVERSION)
+ && !WILDCARD_TYPE_P (convtype)
+ && (CLASS_TYPE_P (to_nonref)
+ != CLASS_TYPE_P (convtype)))
+ continue;
+
+ /* If we are called to convert to a reference type, we are trying to
+ find a direct binding, so don't even consider temporaries. If
+ we don't find a direct binding, the caller will try again to
+ look for a temporary binding. */
+ if (TYPE_REF_P (totype))
+ convflags |= LOOKUP_NO_TEMP_BIND;
+
+ old_candidates = candidates;
+ add_candidates (TREE_VALUE (conv_fns), first_arg, NULL, totype,
+ NULL_TREE, false,
+ conversion_path, TYPE_BINFO (fromtype),
+ flags, &candidates, complain);
+
+ for (cand = candidates; cand != old_candidates; cand = cand->next)
+ {
+ if (cand->viable == 0)
+ /* Already rejected, don't change to -1. */
+ continue;
+
+ tree rettype = TREE_TYPE (TREE_TYPE (cand->fn));
+ conversion *ics
+ = implicit_conversion (totype,
+ rettype,
+ 0,
+ /*c_cast_p=*/false, convflags,
+ complain);
+
+ /* If LOOKUP_NO_TEMP_BIND isn't set, then this is
+ copy-initialization. In that case, "The result of the
+ call is then used to direct-initialize the object that is
+ the destination of the copy-initialization." [dcl.init]
+
+ We represent this in the conversion sequence with an
+ rvalue conversion, which means a constructor call. But
+ don't add a second rvalue conversion if there's already
+ one there. Which there really shouldn't be, but it's
+ harmless since we'd add it here anyway. */
+ if (ics && MAYBE_CLASS_TYPE_P (totype) && ics->kind != ck_rvalue
+ && !(convflags & LOOKUP_NO_TEMP_BIND))
+ ics = build_conv (ck_rvalue, totype, ics);
+
+ cand->second_conv = ics;
+
+ if (!ics)
+ {
+ cand->viable = 0;
+ cand->reason = arg_conversion_rejection (NULL_TREE, -2,
+ rettype, totype,
+ EXPR_LOCATION (expr));
+ }
+ else if (TYPE_REF_P (totype) && !ics->rvaluedness_matches_p
+ /* Limit this to non-templates for now (PR90546). */
+ && !cand->template_decl
+ && TREE_CODE (TREE_TYPE (totype)) != FUNCTION_TYPE)
+ {
+ /* If we are called to convert to a reference type, we are trying
+ to find a direct binding per [over.match.ref], so rvaluedness
+ must match for non-functions. */
+ cand->viable = 0;
+ }
+ else if (DECL_NONCONVERTING_P (cand->fn)
+ && ics->rank > cr_exact)
+ {
+ /* 13.3.1.5: For direct-initialization, those explicit
+ conversion functions that are not hidden within S and
+ yield type T or a type that can be converted to type T
+ with a qualification conversion (4.4) are also candidate
+ functions. */
+ /* 13.3.1.6 doesn't have a parallel restriction, but it should;
+ I've raised this issue with the committee. --jason 9/2011 */
+ cand->viable = -1;
+ cand->reason = explicit_conversion_rejection (rettype, totype);
+ }
+ else if (cand->viable == 1 && ics->bad_p)
+ {
+ cand->viable = -1;
+ cand->reason
+ = bad_arg_conversion_rejection (NULL_TREE, -2,
+ rettype, totype,
+ EXPR_LOCATION (expr));
+ }
+ else if (primary_template_specialization_p (cand->fn)
+ && ics->rank > cr_exact)
+ {
+ /* 13.3.3.1.2: If the user-defined conversion is specified by
+ a specialization of a conversion function template, the
+ second standard conversion sequence shall have exact match
+ rank. */
+ cand->viable = -1;
+ cand->reason = template_conversion_rejection (rettype, totype);
+ }
+ }
+ }
+
+ candidates = splice_viable (candidates, false, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (args)
+ release_tree_vector (args);
+ return NULL;
+ }
+
+ cand = tourney (candidates, complain);
+ if (cand == NULL)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error_at (cp_expr_loc_or_input_loc (expr),
+ "conversion from %qH to %qI is ambiguous",
+ fromtype, totype);
+ print_z_candidates (location_of (expr), candidates);
+ }
+
+ cand = candidates; /* any one will do */
+ cand->second_conv = build_ambiguous_conv (totype, expr);
+ cand->second_conv->user_conv_p = true;
+ if (!any_strictly_viable (candidates))
+ cand->second_conv->bad_p = true;
+ if (flags & LOOKUP_ONLYCONVERTING)
+ cand->second_conv->need_temporary_p = true;
+ /* If there are viable candidates, don't set ICS_BAD_FLAG; an
+ ambiguous conversion is no worse than another user-defined
+ conversion. */
+
+ return cand;
+ }
+
+ tree convtype;
+ if (!DECL_CONSTRUCTOR_P (cand->fn))
+ convtype = non_reference (TREE_TYPE (TREE_TYPE (cand->fn)));
+ else if (cand->second_conv->kind == ck_rvalue)
+ /* DR 5: [in the first step of copy-initialization]...if the function
+ is a constructor, the call initializes a temporary of the
+ cv-unqualified version of the destination type. */
+ convtype = cv_unqualified (totype);
+ else
+ convtype = totype;
+ /* Build the user conversion sequence. */
+ conv = build_conv
+ (ck_user,
+ convtype,
+ build_identity_conv (TREE_TYPE (expr), expr));
+ conv->cand = cand;
+ if (cand->viable == -1)
+ conv->bad_p = true;
+
+ /* We're performing the maybe-rvalue overload resolution and
+ a conversion function is in play. Reject converting the return
+ value of the conversion function to a base class. */
+ if ((flags & LOOKUP_PREFER_RVALUE) && !DECL_CONSTRUCTOR_P (cand->fn))
+ for (conversion *t = cand->second_conv; t; t = next_conversion (t))
+ if (t->kind == ck_base)
+ return NULL;
+
+ /* Remember that this was a list-initialization. */
+ if (flags & LOOKUP_NO_NARROWING)
+ conv->check_narrowing = true;
+
+ /* Combine it with the second conversion sequence. */
+ cand->second_conv = merge_conversion_sequences (conv,
+ cand->second_conv);
+
+ return cand;
+}
+
+/* Wrapper for above. */
+
+tree
+build_user_type_conversion (tree totype, tree expr, int flags,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *cand;
+ tree ret;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+ cand = build_user_type_conversion_1 (totype, expr, flags, complain);
+
+ if (cand)
+ {
+ if (cand->second_conv->kind == ck_ambig)
+ ret = error_mark_node;
+ else
+ {
+ expr = convert_like (cand->second_conv, expr, complain);
+ ret = convert_from_reference (expr);
+ }
+ }
+ else
+ ret = NULL_TREE;
+
+ return ret;
+}
+
+/* Give a helpful diagnostic when implicit_conversion fails. */
+
+static void
+implicit_conversion_error (location_t loc, tree type, tree expr)
+{
+ tsubst_flags_t complain = tf_warning_or_error;
+
+ /* If expr has unknown type, then it is an overloaded function.
+ Call instantiate_type to get good error messages. */
+ if (TREE_TYPE (expr) == unknown_type_node)
+ instantiate_type (type, expr, complain);
+ else if (invalid_nonstatic_memfn_p (loc, expr, complain))
+ /* We gave an error. */;
+ else if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_IS_DESIGNATED_INIT (expr)
+ && !CP_AGGREGATE_TYPE_P (type))
+ error_at (loc, "designated initializers cannot be used with a "
+ "non-aggregate type %qT", type);
+ else
+ {
+ range_label_for_type_mismatch label (TREE_TYPE (expr), type);
+ gcc_rich_location rich_loc (loc, &label);
+ error_at (&rich_loc, "could not convert %qE from %qH to %qI",
+ expr, TREE_TYPE (expr), type);
+ }
+}
+
+/* Worker for build_converted_constant_expr. */
+
+static tree
+build_converted_constant_expr_internal (tree type, tree expr,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+ tree t;
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false, flags, complain);
+
+ /* A converted constant expression of type T is an expression, implicitly
+ converted to type T, where the converted expression is a constant
+ expression and the implicit conversion sequence contains only
+
+ * user-defined conversions,
+ * lvalue-to-rvalue conversions (7.1),
+ * array-to-pointer conversions (7.2),
+ * function-to-pointer conversions (7.3),
+ * qualification conversions (7.5),
+ * integral promotions (7.6),
+ * integral conversions (7.8) other than narrowing conversions (11.6.4),
+ * null pointer conversions (7.11) from std::nullptr_t,
+ * null member pointer conversions (7.12) from std::nullptr_t, and
+ * function pointer conversions (7.13),
+
+ and where the reference binding (if any) binds directly. */
+
+ for (conversion *c = conv;
+ c && c->kind != ck_identity;
+ c = next_conversion (c))
+ {
+ switch (c->kind)
+ {
+ /* A conversion function is OK. If it isn't constexpr, we'll
+ complain later that the argument isn't constant. */
+ case ck_user:
+ /* List-initialization is OK. */
+ case ck_aggr:
+ /* The lvalue-to-rvalue conversion is OK. */
+ case ck_rvalue:
+ /* Array-to-pointer and function-to-pointer. */
+ case ck_lvalue:
+ /* Function pointer conversions. */
+ case ck_fnptr:
+ /* Qualification conversions. */
+ case ck_qual:
+ break;
+
+ case ck_ref_bind:
+ if (c->need_temporary_p)
+ {
+ if (complain & tf_error)
+ error_at (loc, "initializing %qH with %qI in converted "
+ "constant expression does not bind directly",
+ type, next_conversion (c)->type);
+ conv = NULL;
+ }
+ break;
+
+ case ck_base:
+ case ck_pmem:
+ case ck_ptr:
+ case ck_std:
+ t = next_conversion (c)->type;
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (t)
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (type))
+ /* Integral promotion or conversion. */
+ break;
+ if (NULLPTR_TYPE_P (t))
+ /* Conversion from nullptr to pointer or pointer-to-member. */
+ break;
+
+ if (complain & tf_error)
+ error_at (loc, "conversion from %qH to %qI in a "
+ "converted constant expression", t, type);
+ /* fall through. */
+
+ default:
+ conv = NULL;
+ break;
+ }
+ }
+
+ /* Avoid confusing convert_nontype_argument by introducing
+ a redundant conversion to the same reference type. */
+ if (conv && conv->kind == ck_ref_bind
+ && REFERENCE_REF_P (expr))
+ {
+ tree ref = TREE_OPERAND (expr, 0);
+ if (same_type_p (type, TREE_TYPE (ref)))
+ return ref;
+ }
+
+ if (conv)
+ {
+ /* Don't copy a class in a template. */
+ if (CLASS_TYPE_P (type) && conv->kind == ck_rvalue
+ && processing_template_decl)
+ conv = next_conversion (conv);
+
+ /* Issuing conversion warnings for value-dependent expressions is
+ likely too noisy. */
+ warning_sentinel w (warn_conversion);
+ conv->check_narrowing = true;
+ conv->check_narrowing_const_only = true;
+ expr = convert_like (conv, expr, complain);
+ }
+ else
+ {
+ if (complain & tf_error)
+ implicit_conversion_error (loc, type, expr);
+ expr = error_mark_node;
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* Subroutine of convert_nontype_argument.
+
+ EXPR is an expression used in a context that requires a converted
+ constant-expression, such as a template non-type parameter. Do any
+ necessary conversions (that are permitted for converted
+ constant-expressions) to convert it to the desired type.
+
+ This function doesn't consider explicit conversion functions. If
+ you mean to use "a contextually converted constant expression of type
+ bool", use build_converted_constant_bool_expr.
+
+ If conversion is successful, returns the converted expression;
+ otherwise, returns error_mark_node. */
+
+tree
+build_converted_constant_expr (tree type, tree expr, tsubst_flags_t complain)
+{
+ return build_converted_constant_expr_internal (type, expr, LOOKUP_IMPLICIT,
+ complain);
+}
+
+/* Used to create "a contextually converted constant expression of type
+ bool". This differs from build_converted_constant_expr in that it
+ also considers explicit conversion functions. */
+
+tree
+build_converted_constant_bool_expr (tree expr, tsubst_flags_t complain)
+{
+ return build_converted_constant_expr_internal (boolean_type_node, expr,
+ LOOKUP_NORMAL, complain);
+}
+
+/* Do any initial processing on the arguments to a function call. */
+
+vec<tree, va_gc> *
+resolve_args (vec<tree, va_gc> *args, tsubst_flags_t complain)
+{
+ unsigned int ix;
+ tree arg;
+
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ {
+ if (error_operand_p (arg))
+ return NULL;
+ else if (VOID_TYPE_P (TREE_TYPE (arg)))
+ {
+ if (complain & tf_error)
+ error_at (cp_expr_loc_or_input_loc (arg),
+ "invalid use of void expression");
+ return NULL;
+ }
+ else if (invalid_nonstatic_memfn_p (EXPR_LOCATION (arg), arg, complain))
+ return NULL;
+ }
+ return args;
+}
+
+/* Perform overload resolution on FN, which is called with the ARGS.
+
+ Return the candidate function selected by overload resolution, or
+ NULL if the event that overload resolution failed. In the case
+ that overload resolution fails, *CANDIDATES will be the set of
+ candidates considered, and ANY_VIABLE_P will be set to true or
+ false to indicate whether or not any of the candidates were
+ viable.
+
+ The ARGS should already have gone through RESOLVE_ARGS before this
+ function is called. */
+
+static struct z_candidate *
+perform_overload_resolution (tree fn,
+ const vec<tree, va_gc> *args,
+ struct z_candidate **candidates,
+ bool *any_viable_p, tsubst_flags_t complain)
+{
+ struct z_candidate *cand;
+ tree explicit_targs;
+ int template_only;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ explicit_targs = NULL_TREE;
+ template_only = 0;
+
+ *candidates = NULL;
+ *any_viable_p = true;
+
+ /* Check FN. */
+ gcc_assert (OVL_P (fn) || TREE_CODE (fn) == TEMPLATE_ID_EXPR);
+
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ {
+ explicit_targs = TREE_OPERAND (fn, 1);
+ fn = TREE_OPERAND (fn, 0);
+ template_only = 1;
+ }
+
+ /* Add the various candidate functions. */
+ add_candidates (fn, NULL_TREE, args, NULL_TREE,
+ explicit_targs, template_only,
+ /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE,
+ LOOKUP_NORMAL,
+ candidates, complain);
+
+ *candidates = splice_viable (*candidates, false, any_viable_p);
+ if (*any_viable_p)
+ cand = tourney (*candidates, complain);
+ else
+ cand = NULL;
+
+ return cand;
+}
+
+/* Print an error message about being unable to build a call to FN with
+ ARGS. ANY_VIABLE_P indicates whether any candidate functions could
+ be located; CANDIDATES is a possibly empty list of such
+ functions. */
+
+static void
+print_error_for_call_failure (tree fn, const vec<tree, va_gc> *args,
+ struct z_candidate *candidates)
+{
+ tree targs = NULL_TREE;
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ {
+ targs = TREE_OPERAND (fn, 1);
+ fn = TREE_OPERAND (fn, 0);
+ }
+ tree name = OVL_NAME (fn);
+ location_t loc = location_of (name);
+ if (targs)
+ name = lookup_template_function (name, targs);
+
+ auto_diagnostic_group d;
+ if (!any_strictly_viable (candidates))
+ error_at (loc, "no matching function for call to %<%D(%A)%>",
+ name, build_tree_list_vec (args));
+ else
+ error_at (loc, "call of overloaded %<%D(%A)%> is ambiguous",
+ name, build_tree_list_vec (args));
+ if (candidates)
+ print_z_candidates (loc, candidates);
+}
+
+/* Perform overload resolution on the set of deduction guides DGUIDES
+ using ARGS. Returns the selected deduction guide, or error_mark_node
+ if overload resolution fails. */
+
+tree
+perform_dguide_overload_resolution (tree dguides, const vec<tree, va_gc> *args,
+ tsubst_flags_t complain)
+{
+ z_candidate *candidates;
+ bool any_viable_p;
+ tree result;
+
+ gcc_assert (deduction_guide_p (OVL_FIRST (dguides)));
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ void *p = conversion_obstack_alloc (0);
+
+ z_candidate *cand = perform_overload_resolution (dguides, args, &candidates,
+ &any_viable_p, complain);
+ if (!cand)
+ {
+ if (complain & tf_error)
+ print_error_for_call_failure (dguides, args, candidates);
+ result = error_mark_node;
+ }
+ else
+ result = cand->fn;
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* Return an expression for a call to FN (a namespace-scope function,
+ or a static member function) with the ARGS. This may change
+ ARGS. */
+
+tree
+build_new_function_call (tree fn, vec<tree, va_gc> **args,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *candidates, *cand;
+ bool any_viable_p;
+ void *p;
+ tree result;
+
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ if (flag_tm)
+ tm_malloc_replacement (fn);
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ cand = perform_overload_resolution (fn, *args, &candidates, &any_viable_p,
+ complain);
+
+ if (!cand)
+ {
+ if (complain & tf_error)
+ {
+ // If there is a single (non-viable) function candidate,
+ // let the error be diagnosed by cp_build_function_call_vec.
+ if (!any_viable_p && candidates && ! candidates->next
+ && (TREE_CODE (candidates->fn) == FUNCTION_DECL))
+ return cp_build_function_call_vec (candidates->fn, args, complain);
+
+ // Otherwise, emit notes for non-viable candidates.
+ print_error_for_call_failure (fn, *args, candidates);
+ }
+ result = error_mark_node;
+ }
+ else
+ {
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ }
+
+ if (flag_coroutines
+ && result
+ && TREE_CODE (result) == CALL_EXPR
+ && DECL_BUILT_IN_CLASS (TREE_OPERAND (CALL_EXPR_FN (result), 0))
+ == BUILT_IN_NORMAL)
+ result = coro_validate_builtin_call (result);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* Build a call to a global operator new. FNNAME is the name of the
+ operator (either "operator new" or "operator new[]") and ARGS are
+ the arguments provided. This may change ARGS. *SIZE points to the
+ total number of bytes required by the allocation, and is updated if
+ that is changed here. *COOKIE_SIZE is non-NULL if a cookie should
+ be used. If this function determines that no cookie should be
+ used, after all, *COOKIE_SIZE is set to NULL_TREE. If SIZE_CHECK
+ is not NULL_TREE, it is evaluated before calculating the final
+ array size, and if it fails, the array size is replaced with
+ (size_t)-1 (usually triggering a std::bad_alloc exception). If FN
+ is non-NULL, it will be set, upon return, to the allocation
+ function called. */
+
+tree
+build_operator_new_call (tree fnname, vec<tree, va_gc> **args,
+ tree *size, tree *cookie_size,
+ tree align_arg, tree size_check,
+ tree *fn, tsubst_flags_t complain)
+{
+ tree original_size = *size;
+ tree fns;
+ struct z_candidate *candidates;
+ struct z_candidate *cand = NULL;
+ bool any_viable_p;
+
+ if (fn)
+ *fn = NULL_TREE;
+ /* Set to (size_t)-1 if the size check fails. */
+ if (size_check != NULL_TREE)
+ {
+ tree errval = TYPE_MAX_VALUE (sizetype);
+ if (cxx_dialect >= cxx11 && flag_exceptions)
+ errval = throw_bad_array_new_length ();
+ *size = fold_build3 (COND_EXPR, sizetype, size_check,
+ original_size, errval);
+ }
+ vec_safe_insert (*args, 0, *size);
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+
+ /* Based on:
+
+ [expr.new]
+
+ If this lookup fails to find the name, or if the allocated type
+ is not a class type, the allocation function's name is looked
+ up in the global scope.
+
+ we disregard block-scope declarations of "operator new". */
+ fns = lookup_name (fnname, LOOK_where::NAMESPACE);
+ fns = lookup_arg_dependent (fnname, fns, *args);
+
+ if (align_arg)
+ {
+ vec<tree, va_gc>* align_args
+ = vec_copy_and_insert (*args, align_arg, 1);
+ cand = perform_overload_resolution (fns, align_args, &candidates,
+ &any_viable_p, tf_none);
+ if (cand)
+ *args = align_args;
+ /* If no aligned allocation function matches, try again without the
+ alignment. */
+ }
+
+ /* Figure out what function is being called. */
+ if (!cand)
+ cand = perform_overload_resolution (fns, *args, &candidates, &any_viable_p,
+ complain);
+
+ /* If no suitable function could be found, issue an error message
+ and give up. */
+ if (!cand)
+ {
+ if (complain & tf_error)
+ print_error_for_call_failure (fns, *args, candidates);
+ return error_mark_node;
+ }
+
+ /* If a cookie is required, add some extra space. Whether
+ or not a cookie is required cannot be determined until
+ after we know which function was called. */
+ if (*cookie_size)
+ {
+ bool use_cookie = true;
+ tree arg_types;
+
+ arg_types = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+ /* Skip the size_t parameter. */
+ arg_types = TREE_CHAIN (arg_types);
+ /* Check the remaining parameters (if any). */
+ if (arg_types
+ && TREE_CHAIN (arg_types) == void_list_node
+ && same_type_p (TREE_VALUE (arg_types),
+ ptr_type_node))
+ use_cookie = false;
+ /* If we need a cookie, adjust the number of bytes allocated. */
+ if (use_cookie)
+ {
+ /* Update the total size. */
+ *size = size_binop (PLUS_EXPR, original_size, *cookie_size);
+ if (size_check)
+ {
+ /* Set to (size_t)-1 if the size check fails. */
+ gcc_assert (size_check != NULL_TREE);
+ *size = fold_build3 (COND_EXPR, sizetype, size_check,
+ *size, TYPE_MAX_VALUE (sizetype));
+ }
+ /* Update the argument list to reflect the adjusted size. */
+ (**args)[0] = *size;
+ }
+ else
+ *cookie_size = NULL_TREE;
+ }
+
+ /* Tell our caller which function we decided to call. */
+ if (fn)
+ *fn = cand->fn;
+
+ /* Build the CALL_EXPR. */
+ tree ret = build_over_call (cand, LOOKUP_NORMAL, complain);
+
+ /* Set this flag for all callers of this function. In addition to
+ new-expressions, this is called for allocating coroutine state; treat
+ that as an implicit new-expression. */
+ tree call = extract_call_expr (ret);
+ if (TREE_CODE (call) == CALL_EXPR)
+ CALL_FROM_NEW_OR_DELETE_P (call) = 1;
+
+ return ret;
+}
+
+/* Build a new call to operator(). This may change ARGS. */
+
+tree
+build_op_call (tree obj, vec<tree, va_gc> **args, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ tree fns, convs, first_mem_arg = NULL_TREE;
+ bool any_viable_p;
+ tree result = NULL_TREE;
+ void *p;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ obj = mark_lvalue_use (obj);
+
+ if (error_operand_p (obj))
+ return error_mark_node;
+
+ tree type = TREE_TYPE (obj);
+
+ obj = prep_operand (obj);
+
+ if (TYPE_PTRMEMFUNC_P (type))
+ {
+ if (complain & tf_error)
+ /* It's no good looking for an overloaded operator() on a
+ pointer-to-member-function. */
+ error ("pointer-to-member function %qE cannot be called without "
+ "an object; consider using %<.*%> or %<->*%>", obj);
+ return error_mark_node;
+ }
+
+ if (TYPE_BINFO (type))
+ {
+ fns = lookup_fnfields (TYPE_BINFO (type), call_op_identifier, 1, complain);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ fns = NULL_TREE;
+
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ if (fns)
+ {
+ first_mem_arg = obj;
+
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ first_mem_arg, *args, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
+ LOOKUP_NORMAL, &candidates, complain);
+ }
+
+ convs = lookup_conversions (type);
+
+ for (; convs; convs = TREE_CHAIN (convs))
+ {
+ tree totype = TREE_TYPE (convs);
+
+ if (TYPE_PTRFN_P (totype)
+ || TYPE_REFFN_P (totype)
+ || (TYPE_REF_P (totype)
+ && TYPE_PTRFN_P (TREE_TYPE (totype))))
+ for (tree fn : ovl_range (TREE_VALUE (convs)))
+ {
+ if (DECL_NONCONVERTING_P (fn))
+ continue;
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ add_template_conv_candidate
+ (&candidates, fn, obj, *args, totype,
+ /*access_path=*/NULL_TREE,
+ /*conversion_path=*/NULL_TREE, complain);
+ else
+ add_conv_candidate (&candidates, fn, obj,
+ *args, /*conversion_path=*/NULL_TREE,
+ /*access_path=*/NULL_TREE, complain);
+ }
+ }
+
+ /* Be strict here because if we choose a bad conversion candidate, the
+ errors we get won't mention the call context. */
+ candidates = splice_viable (candidates, true, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error ("no match for call to %<(%T) (%A)%>", TREE_TYPE (obj),
+ build_tree_list_vec (*args));
+ print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
+ }
+ result = error_mark_node;
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error ("call of %<(%T) (%A)%> is ambiguous",
+ TREE_TYPE (obj), build_tree_list_vec (*args));
+ print_z_candidates (location_of (TREE_TYPE (obj)), candidates);
+ }
+ result = error_mark_node;
+ }
+ else if (TREE_CODE (cand->fn) == FUNCTION_DECL
+ && DECL_OVERLOADED_OPERATOR_P (cand->fn)
+ && DECL_OVERLOADED_OPERATOR_IS (cand->fn, CALL_EXPR))
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ else
+ {
+ if (TREE_CODE (cand->fn) == FUNCTION_DECL)
+ obj = convert_like_with_context (cand->convs[0], obj, cand->fn,
+ -1, complain);
+ else
+ {
+ gcc_checking_assert (TYPE_P (cand->fn));
+ obj = convert_like (cand->convs[0], obj, complain);
+ }
+ obj = convert_from_reference (obj);
+ result = cp_build_function_call_vec (obj, args, complain);
+ }
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* Called by op_error to prepare format strings suitable for the error
+ function. It concatenates a prefix (controlled by MATCH), ERRMSG,
+ and a suffix (controlled by NTYPES). */
+
+static const char *
+op_error_string (const char *errmsg, int ntypes, bool match)
+{
+ const char *msg;
+
+ const char *msgp = concat (match ? G_("ambiguous overload for ")
+ : G_("no match for "), errmsg, NULL);
+
+ if (ntypes == 3)
+ msg = concat (msgp, G_(" (operand types are %qT, %qT, and %qT)"), NULL);
+ else if (ntypes == 2)
+ msg = concat (msgp, G_(" (operand types are %qT and %qT)"), NULL);
+ else
+ msg = concat (msgp, G_(" (operand type is %qT)"), NULL);
+
+ return msg;
+}
+
+static void
+op_error (const op_location_t &loc,
+ enum tree_code code, enum tree_code code2,
+ tree arg1, tree arg2, tree arg3, bool match)
+{
+ bool assop = code == MODIFY_EXPR;
+ const char *opname = OVL_OP_INFO (assop, assop ? code2 : code)->name;
+
+ switch (code)
+ {
+ case COND_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("ternary %<operator?:%>"),
+ 3, match),
+ TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+ else
+ error_at (loc, op_error_string (G_("ternary %<operator?:%> "
+ "in %<%E ? %E : %E%>"), 3, match),
+ arg1, arg2, arg3,
+ TREE_TYPE (arg1), TREE_TYPE (arg2), TREE_TYPE (arg3));
+ break;
+
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%E%s%>"),
+ 1, match),
+ opname, arg1, opname, TREE_TYPE (arg1));
+ break;
+
+ case ARRAY_REF:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator[]%>"), 2, match),
+ TREE_TYPE (arg1), TREE_TYPE (arg2));
+ else
+ error_at (loc, op_error_string (G_("%<operator[]%> in %<%E[%E]%>"),
+ 2, match),
+ arg1, arg2, TREE_TYPE (arg1), TREE_TYPE (arg2));
+ break;
+
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%qs"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%qs in %<%s %E%>"), 1, match),
+ opname, opname, arg1, TREE_TYPE (arg1));
+ break;
+
+ case CO_AWAIT_EXPR:
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator %s%>"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%<operator %s%> in %<%s%E%>"),
+ 1, match),
+ opname, opname, arg1, TREE_TYPE (arg1));
+ break;
+
+ default:
+ if (arg2)
+ if (flag_diagnostics_show_caret)
+ {
+ binary_op_rich_location richloc (loc, arg1, arg2, true);
+ error_at (&richloc,
+ op_error_string (G_("%<operator%s%>"), 2, match),
+ opname, TREE_TYPE (arg1), TREE_TYPE (arg2));
+ }
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%E %s %E%>"),
+ 2, match),
+ opname, arg1, opname, arg2,
+ TREE_TYPE (arg1), TREE_TYPE (arg2));
+ else
+ if (flag_diagnostics_show_caret)
+ error_at (loc, op_error_string (G_("%<operator%s%>"), 1, match),
+ opname, TREE_TYPE (arg1));
+ else
+ error_at (loc, op_error_string (G_("%<operator%s%> in %<%s%E%>"),
+ 1, match),
+ opname, opname, arg1, TREE_TYPE (arg1));
+ break;
+ }
+}
+
+/* Return the implicit conversion sequence that could be used to
+ convert E1 to E2 in [expr.cond]. */
+
+static conversion *
+conditional_conversion (tree e1, tree e2, tsubst_flags_t complain)
+{
+ tree t1 = non_reference (TREE_TYPE (e1));
+ tree t2 = non_reference (TREE_TYPE (e2));
+ conversion *conv;
+ bool good_base;
+
+ /* [expr.cond]
+
+ If E2 is an lvalue: E1 can be converted to match E2 if E1 can be
+ implicitly converted (clause _conv_) to the type "lvalue reference to
+ T2", subject to the constraint that in the conversion the
+ reference must bind directly (_dcl.init.ref_) to an lvalue.
+
+ If E2 is an xvalue: E1 can be converted to match E2 if E1 can be
+ implicitly converted to the type "rvalue reference to T2", subject to
+ the constraint that the reference must bind directly. */
+ if (glvalue_p (e2))
+ {
+ tree rtype = cp_build_reference_type (t2, !lvalue_p (e2));
+ conv = implicit_conversion (rtype,
+ t1,
+ e1,
+ /*c_cast_p=*/false,
+ LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND
+ |LOOKUP_ONLYCONVERTING,
+ complain);
+ if (conv && !conv->bad_p)
+ return conv;
+ }
+
+ /* If E2 is a prvalue or if neither of the conversions above can be done
+ and at least one of the operands has (possibly cv-qualified) class
+ type: */
+ if (!CLASS_TYPE_P (t1) && !CLASS_TYPE_P (t2))
+ return NULL;
+
+ /* [expr.cond]
+
+ If E1 and E2 have class type, and the underlying class types are
+ the same or one is a base class of the other: E1 can be converted
+ to match E2 if the class of T2 is the same type as, or a base
+ class of, the class of T1, and the cv-qualification of T2 is the
+ same cv-qualification as, or a greater cv-qualification than, the
+ cv-qualification of T1. If the conversion is applied, E1 is
+ changed to an rvalue of type T2 that still refers to the original
+ source class object (or the appropriate subobject thereof). */
+ if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
+ && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
+ {
+ if (good_base && at_least_as_qualified_p (t2, t1))
+ {
+ conv = build_identity_conv (t1, e1);
+ if (!same_type_p (TYPE_MAIN_VARIANT (t1),
+ TYPE_MAIN_VARIANT (t2)))
+ conv = build_conv (ck_base, t2, conv);
+ else
+ conv = build_conv (ck_rvalue, t2, conv);
+ return conv;
+ }
+ else
+ return NULL;
+ }
+ else
+ /* [expr.cond]
+
+ Otherwise: E1 can be converted to match E2 if E1 can be implicitly
+ converted to the type that expression E2 would have if E2 were
+ converted to an rvalue (or the type it has, if E2 is an rvalue). */
+ return implicit_conversion (t2, t1, e1, /*c_cast_p=*/false,
+ LOOKUP_IMPLICIT, complain);
+}
+
+/* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three
+ arguments to the conditional expression. */
+
+tree
+build_conditional_expr (const op_location_t &loc,
+ tree arg1, tree arg2, tree arg3,
+ tsubst_flags_t complain)
+{
+ tree arg2_type;
+ tree arg3_type;
+ tree result = NULL_TREE;
+ tree result_type = NULL_TREE;
+ bool is_glvalue = true;
+ struct z_candidate *candidates = 0;
+ struct z_candidate *cand;
+ void *p;
+ tree orig_arg2, orig_arg3;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ /* As a G++ extension, the second argument to the conditional can be
+ omitted. (So that `a ? : c' is roughly equivalent to `a ? a :
+ c'.) If the second operand is omitted, make sure it is
+ calculated only once. */
+ if (!arg2)
+ {
+ if (complain & tf_error)
+ pedwarn (loc, OPT_Wpedantic,
+ "ISO C++ forbids omitting the middle term of "
+ "a %<?:%> expression");
+
+ if ((complain & tf_warning) && !truth_value_p (TREE_CODE (arg1)))
+ warn_for_omitted_condop (loc, arg1);
+
+ /* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */
+ if (glvalue_p (arg1))
+ {
+ arg1 = cp_stabilize_reference (arg1);
+ arg2 = arg1 = prevent_lifetime_extension (arg1);
+ }
+ else
+ arg2 = arg1 = cp_save_expr (arg1);
+ }
+
+ /* If something has already gone wrong, just pass that fact up the
+ tree. */
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ orig_arg2 = arg2;
+ orig_arg3 = arg3;
+
+ if (gnu_vector_type_p (TREE_TYPE (arg1))
+ && VECTOR_INTEGER_TYPE_P (TREE_TYPE (arg1)))
+ {
+ tree arg1_type = TREE_TYPE (arg1);
+
+ /* If arg1 is another cond_expr choosing between -1 and 0,
+ then we can use its comparison. It may help to avoid
+ additional comparison, produce more accurate diagnostics
+ and enables folding. */
+ if (TREE_CODE (arg1) == VEC_COND_EXPR
+ && integer_minus_onep (TREE_OPERAND (arg1, 1))
+ && integer_zerop (TREE_OPERAND (arg1, 2)))
+ arg1 = TREE_OPERAND (arg1, 0);
+
+ arg1 = force_rvalue (arg1, complain);
+ arg2 = force_rvalue (arg2, complain);
+ arg3 = force_rvalue (arg3, complain);
+
+ /* force_rvalue can return error_mark on valid arguments. */
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ arg2_type = TREE_TYPE (arg2);
+ arg3_type = TREE_TYPE (arg3);
+
+ if (!VECTOR_TYPE_P (arg2_type)
+ && !VECTOR_TYPE_P (arg3_type))
+ {
+ /* Rely on the error messages of the scalar version. */
+ tree scal = build_conditional_expr (loc, integer_one_node,
+ orig_arg2, orig_arg3, complain);
+ if (scal == error_mark_node)
+ return error_mark_node;
+ tree stype = TREE_TYPE (scal);
+ tree ctype = TREE_TYPE (arg1_type);
+ if (TYPE_SIZE (stype) != TYPE_SIZE (ctype)
+ || (!INTEGRAL_TYPE_P (stype) && !SCALAR_FLOAT_TYPE_P (stype)))
+ {
+ if (complain & tf_error)
+ error_at (loc, "inferred scalar type %qT is not an integer or "
+ "floating-point type of the same size as %qT", stype,
+ COMPARISON_CLASS_P (arg1)
+ ? TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+ : ctype);
+ return error_mark_node;
+ }
+
+ tree vtype = build_opaque_vector_type (stype,
+ TYPE_VECTOR_SUBPARTS (arg1_type));
+ /* We could pass complain & tf_warning to unsafe_conversion_p,
+ but the warnings (like Wsign-conversion) have already been
+ given by the scalar build_conditional_expr_1. We still check
+ unsafe_conversion_p to forbid truncating long long -> float. */
+ if (unsafe_conversion_p (stype, arg2, NULL_TREE, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qH to vector %qI "
+ "involves truncation", arg2_type, vtype);
+ return error_mark_node;
+ }
+ if (unsafe_conversion_p (stype, arg3, NULL_TREE, false))
+ {
+ if (complain & tf_error)
+ error_at (loc, "conversion of scalar %qH to vector %qI "
+ "involves truncation", arg3_type, vtype);
+ return error_mark_node;
+ }
+
+ arg2 = cp_convert (stype, arg2, complain);
+ arg2 = save_expr (arg2);
+ arg2 = build_vector_from_val (vtype, arg2);
+ arg2_type = vtype;
+ arg3 = cp_convert (stype, arg3, complain);
+ arg3 = save_expr (arg3);
+ arg3 = build_vector_from_val (vtype, arg3);
+ arg3_type = vtype;
+ }
+
+ if ((gnu_vector_type_p (arg2_type) && !VECTOR_TYPE_P (arg3_type))
+ || (gnu_vector_type_p (arg3_type) && !VECTOR_TYPE_P (arg2_type)))
+ {
+ enum stv_conv convert_flag =
+ scalar_to_vector (loc, VEC_COND_EXPR, arg2, arg3,
+ complain & tf_error);
+
+ switch (convert_flag)
+ {
+ case stv_error:
+ return error_mark_node;
+ case stv_firstarg:
+ {
+ arg2 = save_expr (arg2);
+ arg2 = convert (TREE_TYPE (arg3_type), arg2);
+ arg2 = build_vector_from_val (arg3_type, arg2);
+ arg2_type = TREE_TYPE (arg2);
+ break;
+ }
+ case stv_secondarg:
+ {
+ arg3 = save_expr (arg3);
+ arg3 = convert (TREE_TYPE (arg2_type), arg3);
+ arg3 = build_vector_from_val (arg2_type, arg3);
+ arg3_type = TREE_TYPE (arg3);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ if (!gnu_vector_type_p (arg2_type)
+ || !gnu_vector_type_p (arg3_type)
+ || !same_type_p (arg2_type, arg3_type)
+ || maybe_ne (TYPE_VECTOR_SUBPARTS (arg1_type),
+ TYPE_VECTOR_SUBPARTS (arg2_type))
+ || TYPE_SIZE (arg1_type) != TYPE_SIZE (arg2_type))
+ {
+ if (complain & tf_error)
+ error_at (loc,
+ "incompatible vector types in conditional expression: "
+ "%qT, %qT and %qT", TREE_TYPE (arg1),
+ TREE_TYPE (orig_arg2), TREE_TYPE (orig_arg3));
+ return error_mark_node;
+ }
+
+ if (!COMPARISON_CLASS_P (arg1))
+ {
+ tree cmp_type = truth_type_for (arg1_type);
+ arg1 = build2 (NE_EXPR, cmp_type, arg1, build_zero_cst (arg1_type));
+ }
+ return build3_loc (loc, VEC_COND_EXPR, arg2_type, arg1, arg2, arg3);
+ }
+
+ /* [expr.cond]
+
+ The first expression is implicitly converted to bool (clause
+ _conv_). */
+ arg1 = perform_implicit_conversion_flags (boolean_type_node, arg1, complain,
+ LOOKUP_NORMAL);
+ if (error_operand_p (arg1))
+ return error_mark_node;
+
+ /* [expr.cond]
+
+ If either the second or the third operand has type (possibly
+ cv-qualified) void, then the lvalue-to-rvalue (_conv.lval_),
+ array-to-pointer (_conv.array_), and function-to-pointer
+ (_conv.func_) standard conversions are performed on the second
+ and third operands. */
+ arg2_type = unlowered_expr_type (arg2);
+ arg3_type = unlowered_expr_type (arg3);
+ if (VOID_TYPE_P (arg2_type) || VOID_TYPE_P (arg3_type))
+ {
+ /* 'void' won't help in resolving an overloaded expression on the
+ other side, so require it to resolve by itself. */
+ if (arg2_type == unknown_type_node)
+ {
+ arg2 = resolve_nondeduced_context_or_error (arg2, complain);
+ arg2_type = TREE_TYPE (arg2);
+ }
+ if (arg3_type == unknown_type_node)
+ {
+ arg3 = resolve_nondeduced_context_or_error (arg3, complain);
+ arg3_type = TREE_TYPE (arg3);
+ }
+
+ /* [expr.cond]
+
+ One of the following shall hold:
+
+ --The second or the third operand (but not both) is a
+ throw-expression (_except.throw_); the result is of the type
+ and value category of the other.
+
+ --Both the second and the third operands have type void; the
+ result is of type void and is a prvalue. */
+ if (TREE_CODE (arg2) == THROW_EXPR
+ && TREE_CODE (arg3) != THROW_EXPR)
+ {
+ result_type = arg3_type;
+ is_glvalue = glvalue_p (arg3);
+ }
+ else if (TREE_CODE (arg2) != THROW_EXPR
+ && TREE_CODE (arg3) == THROW_EXPR)
+ {
+ result_type = arg2_type;
+ is_glvalue = glvalue_p (arg2);
+ }
+ else if (VOID_TYPE_P (arg2_type) && VOID_TYPE_P (arg3_type))
+ {
+ result_type = void_type_node;
+ is_glvalue = false;
+ }
+ else
+ {
+ if (complain & tf_error)
+ {
+ if (VOID_TYPE_P (arg2_type))
+ error_at (cp_expr_loc_or_loc (arg3, loc),
+ "second operand to the conditional operator "
+ "is of type %<void%>, but the third operand is "
+ "neither a throw-expression nor of type %<void%>");
+ else
+ error_at (cp_expr_loc_or_loc (arg2, loc),
+ "third operand to the conditional operator "
+ "is of type %<void%>, but the second operand is "
+ "neither a throw-expression nor of type %<void%>");
+ }
+ return error_mark_node;
+ }
+
+ goto valid_operands;
+ }
+ /* [expr.cond]
+
+ Otherwise, if the second and third operand have different types,
+ and either has (possibly cv-qualified) class type, or if both are
+ glvalues of the same value category and the same type except for
+ cv-qualification, an attempt is made to convert each of those operands
+ to the type of the other. */
+ else if (!same_type_p (arg2_type, arg3_type)
+ && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)
+ || (same_type_ignoring_top_level_qualifiers_p (arg2_type,
+ arg3_type)
+ && glvalue_p (arg2) && glvalue_p (arg3)
+ && lvalue_p (arg2) == lvalue_p (arg3))))
+ {
+ conversion *conv2;
+ conversion *conv3;
+ bool converted = false;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv2 = conditional_conversion (arg2, arg3, complain);
+ conv3 = conditional_conversion (arg3, arg2, complain);
+
+ /* [expr.cond]
+
+ If both can be converted, or one can be converted but the
+ conversion is ambiguous, the program is ill-formed. If
+ neither can be converted, the operands are left unchanged and
+ further checking is performed as described below. If exactly
+ one conversion is possible, that conversion is applied to the
+ chosen operand and the converted operand is used in place of
+ the original operand for the remainder of this section. */
+ if ((conv2 && !conv2->bad_p
+ && conv3 && !conv3->bad_p)
+ || (conv2 && conv2->kind == ck_ambig)
+ || (conv3 && conv3->kind == ck_ambig))
+ {
+ if (complain & tf_error)
+ {
+ error_at (loc, "operands to %<?:%> have different types "
+ "%qT and %qT",
+ arg2_type, arg3_type);
+ if (conv2 && !conv2->bad_p && conv3 && !conv3->bad_p)
+ inform (loc, " and each type can be converted to the other");
+ else if (conv2 && conv2->kind == ck_ambig)
+ convert_like (conv2, arg2, complain);
+ else
+ convert_like (conv3, arg3, complain);
+ }
+ result = error_mark_node;
+ }
+ else if (conv2 && !conv2->bad_p)
+ {
+ arg2 = convert_like (conv2, arg2, complain);
+ arg2 = convert_from_reference (arg2);
+ arg2_type = TREE_TYPE (arg2);
+ /* Even if CONV2 is a valid conversion, the result of the
+ conversion may be invalid. For example, if ARG3 has type
+ "volatile X", and X does not have a copy constructor
+ accepting a "volatile X&", then even if ARG2 can be
+ converted to X, the conversion will fail. */
+ if (error_operand_p (arg2))
+ result = error_mark_node;
+ converted = true;
+ }
+ else if (conv3 && !conv3->bad_p)
+ {
+ arg3 = convert_like (conv3, arg3, complain);
+ arg3 = convert_from_reference (arg3);
+ arg3_type = TREE_TYPE (arg3);
+ if (error_operand_p (arg3))
+ result = error_mark_node;
+ converted = true;
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (result)
+ return result;
+
+ /* If, after the conversion, both operands have class type,
+ treat the cv-qualification of both operands as if it were the
+ union of the cv-qualification of the operands.
+
+ The standard is not clear about what to do in this
+ circumstance. For example, if the first operand has type
+ "const X" and the second operand has a user-defined
+ conversion to "volatile X", what is the type of the second
+ operand after this step? Making it be "const X" (matching
+ the first operand) seems wrong, as that discards the
+ qualification without actually performing a copy. Leaving it
+ as "volatile X" seems wrong as that will result in the
+ conditional expression failing altogether, even though,
+ according to this step, the one operand could be converted to
+ the type of the other. */
+ if (converted
+ && CLASS_TYPE_P (arg2_type)
+ && cp_type_quals (arg2_type) != cp_type_quals (arg3_type))
+ arg2_type = arg3_type =
+ cp_build_qualified_type (arg2_type,
+ cp_type_quals (arg2_type)
+ | cp_type_quals (arg3_type));
+ }
+
+ /* [expr.cond]
+
+ If the second and third operands are glvalues of the same value
+ category and have the same type, the result is of that type and
+ value category. */
+ if (((lvalue_p (arg2) && lvalue_p (arg3))
+ || (xvalue_p (arg2) && xvalue_p (arg3)))
+ && same_type_p (arg2_type, arg3_type))
+ {
+ result_type = arg2_type;
+ goto valid_operands;
+ }
+
+ /* [expr.cond]
+
+ Otherwise, the result is an rvalue. If the second and third
+ operand do not have the same type, and either has (possibly
+ cv-qualified) class type, overload resolution is used to
+ determine the conversions (if any) to be applied to the operands
+ (_over.match.oper_, _over.built_). */
+ is_glvalue = false;
+ if (!same_type_p (arg2_type, arg3_type)
+ && (CLASS_TYPE_P (arg2_type) || CLASS_TYPE_P (arg3_type)))
+ {
+ releasing_vec args;
+ conversion *conv;
+ bool any_viable_p;
+
+ /* Rearrange the arguments so that add_builtin_candidate only has
+ to know about two args. In build_builtin_candidate, the
+ arguments are unscrambled. */
+ args->quick_push (arg2);
+ args->quick_push (arg3);
+ args->quick_push (arg1);
+ add_builtin_candidates (&candidates,
+ COND_EXPR,
+ NOP_EXPR,
+ ovl_op_identifier (false, COND_EXPR),
+ args,
+ LOOKUP_NORMAL, complain);
+
+ /* [expr.cond]
+
+ If the overload resolution fails, the program is
+ ill-formed. */
+ candidates = splice_viable (candidates, false, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ error_at (loc, "operands to %<?:%> have different types %qT and %qT",
+ arg2_type, arg3_type);
+ return error_mark_node;
+ }
+ cand = tourney (candidates, complain);
+ if (!cand)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ op_error (loc, COND_EXPR, NOP_EXPR, arg1, arg2, arg3, FALSE);
+ print_z_candidates (loc, candidates);
+ }
+ return error_mark_node;
+ }
+
+ /* [expr.cond]
+
+ Otherwise, the conversions thus determined are applied, and
+ the converted operands are used in place of the original
+ operands for the remainder of this section. */
+ conv = cand->convs[0];
+ arg1 = convert_like (conv, arg1, complain);
+ conv = cand->convs[1];
+ arg2 = convert_like (conv, arg2, complain);
+ arg2_type = TREE_TYPE (arg2);
+ conv = cand->convs[2];
+ arg3 = convert_like (conv, arg3, complain);
+ arg3_type = TREE_TYPE (arg3);
+ }
+
+ /* [expr.cond]
+
+ Lvalue-to-rvalue (_conv.lval_), array-to-pointer (_conv.array_),
+ and function-to-pointer (_conv.func_) standard conversions are
+ performed on the second and third operands.
+
+ We need to force the lvalue-to-rvalue conversion here for class types,
+ so we get TARGET_EXPRs; trying to deal with a COND_EXPR of class rvalues
+ that isn't wrapped with a TARGET_EXPR plays havoc with exception
+ regions. */
+
+ arg2 = force_rvalue (arg2, complain);
+ if (!CLASS_TYPE_P (arg2_type))
+ arg2_type = TREE_TYPE (arg2);
+
+ arg3 = force_rvalue (arg3, complain);
+ if (!CLASS_TYPE_P (arg3_type))
+ arg3_type = TREE_TYPE (arg3);
+
+ if (arg2 == error_mark_node || arg3 == error_mark_node)
+ return error_mark_node;
+
+ /* [expr.cond]
+
+ After those conversions, one of the following shall hold:
+
+ --The second and third operands have the same type; the result is of
+ that type. */
+ if (same_type_p (arg2_type, arg3_type))
+ result_type = arg2_type;
+ /* [expr.cond]
+
+ --The second and third operands have arithmetic or enumeration
+ type; the usual arithmetic conversions are performed to bring
+ them to a common type, and the result is of that type. */
+ else if ((ARITHMETIC_TYPE_P (arg2_type)
+ || UNSCOPED_ENUM_P (arg2_type))
+ && (ARITHMETIC_TYPE_P (arg3_type)
+ || UNSCOPED_ENUM_P (arg3_type)))
+ {
+ /* In this case, there is always a common type. */
+ result_type = type_after_usual_arithmetic_conversions (arg2_type,
+ arg3_type);
+ if (complain & tf_warning)
+ do_warn_double_promotion (result_type, arg2_type, arg3_type,
+ "implicit conversion from %qH to %qI to "
+ "match other result of conditional",
+ loc);
+
+ if (TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && TREE_CODE (arg3_type) == ENUMERAL_TYPE)
+ {
+ tree stripped_orig_arg2 = tree_strip_any_location_wrapper (orig_arg2);
+ tree stripped_orig_arg3 = tree_strip_any_location_wrapper (orig_arg3);
+ if (TREE_CODE (stripped_orig_arg2) == CONST_DECL
+ && TREE_CODE (stripped_orig_arg3) == CONST_DECL
+ && (DECL_CONTEXT (stripped_orig_arg2)
+ == DECL_CONTEXT (stripped_orig_arg3)))
+ /* Two enumerators from the same enumeration can have different
+ types when the enumeration is still being defined. */;
+ else if (complain & tf_warning)
+ warning_at (loc, OPT_Wenum_compare, "enumerated mismatch "
+ "in conditional expression: %qT vs %qT",
+ arg2_type, arg3_type);
+ }
+ else if ((complain & tf_warning)
+ && warn_deprecated_enum_float_conv
+ && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && TREE_CODE (arg3_type) == REAL_TYPE)
+ || (TREE_CODE (arg2_type) == REAL_TYPE
+ && TREE_CODE (arg3_type) == ENUMERAL_TYPE)))
+ {
+ if (TREE_CODE (arg2_type) == ENUMERAL_TYPE)
+ warning_at (loc, OPT_Wdeprecated_enum_float_conversion,
+ "conditional expression between enumeration type "
+ "%qT and floating-point type %qT is deprecated",
+ arg2_type, arg3_type);
+ else
+ warning_at (loc, OPT_Wdeprecated_enum_float_conversion,
+ "conditional expression between floating-point "
+ "type %qT and enumeration type %qT is deprecated",
+ arg2_type, arg3_type);
+ }
+ else if ((extra_warnings || warn_enum_conversion)
+ && ((TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && !same_type_p (arg3_type, type_promotes_to (arg2_type)))
+ || (TREE_CODE (arg3_type) == ENUMERAL_TYPE
+ && !same_type_p (arg2_type,
+ type_promotes_to (arg3_type)))))
+ {
+ if (complain & tf_warning)
+ {
+ enum opt_code opt = (warn_enum_conversion
+ ? OPT_Wenum_conversion
+ : OPT_Wextra);
+ warning_at (loc, opt, "enumerated and "
+ "non-enumerated type in conditional expression");
+ }
+ }
+
+ arg2 = perform_implicit_conversion (result_type, arg2, complain);
+ arg3 = perform_implicit_conversion (result_type, arg3, complain);
+ }
+ /* [expr.cond]
+
+ --The second and third operands have pointer type, or one has
+ pointer type and the other is a null pointer constant; pointer
+ conversions (_conv.ptr_) and qualification conversions
+ (_conv.qual_) are performed to bring them to their composite
+ pointer type (_expr.rel_). The result is of the composite
+ pointer type.
+
+ --The second and third operands have pointer to member type, or
+ one has pointer to member type and the other is a null pointer
+ constant; pointer to member conversions (_conv.mem_) and
+ qualification conversions (_conv.qual_) are performed to bring
+ them to a common type, whose cv-qualification shall match the
+ cv-qualification of either the second or the third operand.
+ The result is of the common type. */
+ else if ((null_ptr_cst_p (arg2)
+ && TYPE_PTR_OR_PTRMEM_P (arg3_type))
+ || (null_ptr_cst_p (arg3)
+ && TYPE_PTR_OR_PTRMEM_P (arg2_type))
+ || (TYPE_PTR_P (arg2_type) && TYPE_PTR_P (arg3_type))
+ || (TYPE_PTRDATAMEM_P (arg2_type) && TYPE_PTRDATAMEM_P (arg3_type))
+ || (TYPE_PTRMEMFUNC_P (arg2_type) && TYPE_PTRMEMFUNC_P (arg3_type)))
+ {
+ result_type = composite_pointer_type (loc,
+ arg2_type, arg3_type, arg2,
+ arg3, CPO_CONDITIONAL_EXPR,
+ complain);
+ if (result_type == error_mark_node)
+ return error_mark_node;
+ arg2 = perform_implicit_conversion (result_type, arg2, complain);
+ arg3 = perform_implicit_conversion (result_type, arg3, complain);
+ }
+
+ if (!result_type)
+ {
+ if (complain & tf_error)
+ error_at (loc, "operands to %<?:%> have different types %qT and %qT",
+ arg2_type, arg3_type);
+ return error_mark_node;
+ }
+
+ if (arg2 == error_mark_node || arg3 == error_mark_node)
+ return error_mark_node;
+
+ valid_operands:
+ if (processing_template_decl && is_glvalue)
+ {
+ /* Let lvalue_kind know this was a glvalue. */
+ tree arg = (result_type == arg2_type ? arg2 : arg3);
+ result_type = cp_build_reference_type (result_type, xvalue_p (arg));
+ }
+
+ result = build3_loc (loc, COND_EXPR, result_type, arg1, arg2, arg3);
+
+ /* If the ARG2 and ARG3 are the same and don't have side-effects,
+ warn here, because the COND_EXPR will be turned into ARG2. */
+ if (warn_duplicated_branches
+ && (complain & tf_warning)
+ && (arg2 == arg3 || operand_equal_p (arg2, arg3,
+ OEP_ADDRESS_OF_SAME_FIELD)))
+ warning_at (EXPR_LOCATION (result), OPT_Wduplicated_branches,
+ "this condition has identical branches");
+
+ /* We can't use result_type below, as fold might have returned a
+ throw_expr. */
+
+ if (!is_glvalue)
+ {
+ /* Expand both sides into the same slot, hopefully the target of
+ the ?: expression. We used to check for TARGET_EXPRs here,
+ but now we sometimes wrap them in NOP_EXPRs so the test would
+ fail. */
+ if (CLASS_TYPE_P (TREE_TYPE (result)))
+ result = get_target_expr_sfinae (result, complain);
+ /* If this expression is an rvalue, but might be mistaken for an
+ lvalue, we must add a NON_LVALUE_EXPR. */
+ result = rvalue (result);
+ }
+ else
+ result = force_paren_expr (result);
+
+ return result;
+}
+
+/* OPERAND is an operand to an expression. Perform necessary steps
+ required before using it. If OPERAND is NULL_TREE, NULL_TREE is
+ returned. */
+
+static tree
+prep_operand (tree operand)
+{
+ if (operand)
+ {
+ if (CLASS_TYPE_P (TREE_TYPE (operand))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (operand)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (operand)));
+ }
+
+ return operand;
+}
+
+/* True iff CONV represents a conversion sequence which no other can be better
+ than under [over.ics.rank]: in other words, a "conversion" to the exact same
+ type (including binding to a reference to the same type). This is stronger
+ than the standard's "identity" category, which also includes reference
+ bindings that add cv-qualifiers or change rvalueness. */
+
+static bool
+perfect_conversion_p (conversion *conv)
+{
+ if (CONVERSION_RANK (conv) != cr_identity)
+ return false;
+ if (conv->kind == ck_ref_bind)
+ {
+ if (!conv->rvaluedness_matches_p)
+ return false;
+ if (!same_type_p (TREE_TYPE (conv->type),
+ next_conversion (conv)->type))
+ return false;
+ }
+ if (conv->check_narrowing)
+ /* Brace elision is imperfect. */
+ return false;
+ return true;
+}
+
+/* True if CAND represents a perfect match, i.e. all perfect conversions, so no
+ other candidate can be a better match. Since the template/non-template
+ tiebreaker comes immediately after the conversion comparison in
+ [over.match.best], a perfect non-template candidate is better than all
+ templates. */
+
+static bool
+perfect_candidate_p (z_candidate *cand)
+{
+ if (cand->viable < 1)
+ return false;
+ /* CWG1402 makes an implicitly deleted move op worse than other
+ candidates. */
+ if (DECL_DELETED_FN (cand->fn) && DECL_DEFAULTED_FN (cand->fn)
+ && move_fn_p (cand->fn))
+ return false;
+ int len = cand->num_convs;
+ for (int i = 0; i < len; ++i)
+ if (!perfect_conversion_p (cand->convs[i]))
+ return false;
+ if (conversion *conv = cand->second_conv)
+ if (!perfect_conversion_p (conv))
+ return false;
+ return true;
+}
+
+/* Add each of the viable functions in FNS (a FUNCTION_DECL or
+ OVERLOAD) to the CANDIDATES, returning an updated list of
+ CANDIDATES. The ARGS are the arguments provided to the call;
+ if FIRST_ARG is non-null it is the implicit object argument,
+ otherwise the first element of ARGS is used if needed. The
+ EXPLICIT_TARGS are explicit template arguments provided.
+ TEMPLATE_ONLY is true if only template functions should be
+ considered. CONVERSION_PATH, ACCESS_PATH, and FLAGS are as for
+ add_function_candidate. */
+
+static void
+add_candidates (tree fns, tree first_arg, const vec<tree, va_gc> *args,
+ tree return_type,
+ tree explicit_targs, bool template_only,
+ tree conversion_path, tree access_path,
+ int flags,
+ struct z_candidate **candidates,
+ tsubst_flags_t complain)
+{
+ tree ctype;
+ const vec<tree, va_gc> *non_static_args;
+ bool check_list_ctor = false;
+ bool check_converting = false;
+ unification_kind_t strict;
+
+ if (!fns)
+ return;
+
+ /* Precalculate special handling of constructors and conversion ops. */
+ tree fn = OVL_FIRST (fns);
+ if (DECL_CONV_FN_P (fn))
+ {
+ check_list_ctor = false;
+ check_converting = (flags & LOOKUP_ONLYCONVERTING) != 0;
+ if (flags & LOOKUP_NO_CONVERSION)
+ /* We're doing return_type(x). */
+ strict = DEDUCE_CONV;
+ else
+ /* We're doing x.operator return_type(). */
+ strict = DEDUCE_EXACT;
+ /* [over.match.funcs] For conversion functions, the function
+ is considered to be a member of the class of the implicit
+ object argument for the purpose of defining the type of
+ the implicit object parameter. */
+ ctype = TYPE_MAIN_VARIANT (TREE_TYPE (first_arg));
+ }
+ else
+ {
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ check_list_ctor = (flags & LOOKUP_LIST_ONLY) != 0;
+ /* For list-initialization we consider explicit constructors
+ and complain if one is chosen. */
+ check_converting
+ = ((flags & (LOOKUP_ONLYCONVERTING|LOOKUP_LIST_INIT_CTOR))
+ == LOOKUP_ONLYCONVERTING);
+ }
+ strict = DEDUCE_CALL;
+ ctype = conversion_path ? BINFO_TYPE (conversion_path) : NULL_TREE;
+ }
+
+ if (first_arg)
+ non_static_args = args;
+ else
+ /* Delay creating the implicit this parameter until it is needed. */
+ non_static_args = NULL;
+
+ bool seen_strictly_viable = any_strictly_viable (*candidates);
+ /* If there's a non-template perfect match, we don't need to consider
+ templates. So check non-templates first. This optimization is only
+ really needed for the defaulted copy constructor of tuple and the like
+ (96926), but it seems like we might as well enable it more generally. */
+ bool seen_perfect = false;
+ enum { templates, non_templates, either } which = either;
+ if (template_only)
+ which = templates;
+ else /*if (flags & LOOKUP_DEFAULTED)*/
+ which = non_templates;
+
+ /* During overload resolution, we first consider each function under the
+ assumption that we'll eventually find a strictly viable candidate.
+ This allows us to circumvent our defacto behavior when checking
+ argument conversions and shortcut consideration of the candidate
+ upon encountering the first bad conversion. If this assumption
+ turns out to be false, and all candidates end up being non-strictly
+ viable, then we reconsider such candidates under the defacto behavior.
+ This trick is important for pruning member function overloads according
+ to their const/ref-qualifiers (since all 'this' conversions are at
+ worst bad) without breaking -fpermissive. */
+ tree bad_fns = NULL_TREE;
+ bool shortcut_bad_convs = true;
+
+ again:
+ for (tree fn : lkp_range (fns))
+ {
+ if (check_converting && DECL_NONCONVERTING_P (fn))
+ continue;
+ if (check_list_ctor && !is_list_ctor (fn))
+ continue;
+ if (which == templates && TREE_CODE (fn) != TEMPLATE_DECL)
+ continue;
+ if (which == non_templates && TREE_CODE (fn) == TEMPLATE_DECL)
+ continue;
+
+ tree fn_first_arg = NULL_TREE;
+ const vec<tree, va_gc> *fn_args = args;
+
+ if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+ {
+ /* Figure out where the object arg comes from. If this
+ function is a non-static member and we didn't get an
+ implicit object argument, move it out of args. */
+ if (first_arg == NULL_TREE)
+ {
+ unsigned int ix;
+ tree arg;
+ vec<tree, va_gc> *tempvec;
+ vec_alloc (tempvec, args->length () - 1);
+ for (ix = 1; args->iterate (ix, &arg); ++ix)
+ tempvec->quick_push (arg);
+ non_static_args = tempvec;
+ first_arg = (*args)[0];
+ }
+
+ fn_first_arg = first_arg;
+ fn_args = non_static_args;
+ }
+
+ /* Don't bother reversing an operator with two identical parameters. */
+ else if (vec_safe_length (args) == 2 && (flags & LOOKUP_REVERSED))
+ {
+ tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ if (same_type_p (TREE_VALUE (parmlist),
+ TREE_VALUE (TREE_CHAIN (parmlist))))
+ continue;
+ }
+
+ if (TREE_CODE (fn) == TEMPLATE_DECL)
+ {
+ if (!add_template_candidate (candidates,
+ fn,
+ ctype,
+ explicit_targs,
+ fn_first_arg,
+ fn_args,
+ return_type,
+ access_path,
+ conversion_path,
+ flags,
+ strict,
+ shortcut_bad_convs,
+ complain))
+ continue;
+ }
+ else
+ {
+ add_function_candidate (candidates,
+ fn,
+ ctype,
+ fn_first_arg,
+ fn_args,
+ access_path,
+ conversion_path,
+ flags,
+ NULL,
+ shortcut_bad_convs,
+ complain);
+ if (perfect_candidate_p (*candidates))
+ seen_perfect = true;
+ }
+
+ z_candidate *cand = *candidates;
+ if (cand->viable == 1)
+ seen_strictly_viable = true;
+
+ if (cand->viable == -1
+ && shortcut_bad_convs
+ && !cand->convs[cand->reversed () ? 0 : cand->num_convs - 1])
+ {
+ /* This candidate has been tentatively marked non-strictly viable,
+ and we didn't compute all argument conversions for it (having
+ stopped at the first bad conversion). Add the function to BAD_FNS
+ to fully reconsider later if we don't find any strictly viable
+ candidates. */
+ if (complain & (tf_error | tf_conv))
+ {
+ bad_fns = lookup_add (fn, bad_fns);
+ *candidates = (*candidates)->next;
+ }
+ else
+ /* But if we're in a SFINAE context, just mark this candidate as
+ unviable outright and avoid potentially reconsidering it.
+ This is safe to do because in a SFINAE context, performing a bad
+ conversion is always an error (even with -fpermissive), so a
+ non-strictly viable candidate is effectively unviable anyway. */
+ cand->viable = 0;
+ }
+ }
+ if (which == non_templates && !seen_perfect)
+ {
+ which = templates;
+ goto again;
+ }
+ else if (which == templates
+ && !seen_strictly_viable
+ && shortcut_bad_convs
+ && bad_fns)
+ {
+ /* None of the candidates are strictly viable, so consider again those
+ functions in BAD_FNS, this time without shortcutting bad conversions
+ so that all their argument conversions are computed. */
+ which = either;
+ fns = bad_fns;
+ shortcut_bad_convs = false;
+ goto again;
+ }
+}
+
+/* Returns 1 if P0145R2 says that the LHS of operator CODE is evaluated first,
+ -1 if the RHS is evaluated first, or 0 if the order is unspecified. */
+
+static int
+op_is_ordered (tree_code code)
+{
+ switch (code)
+ {
+ // 5. b @= a
+ case MODIFY_EXPR:
+ return (flag_strong_eval_order > 1 ? -1 : 0);
+
+ // 6. a[b]
+ case ARRAY_REF:
+ return (flag_strong_eval_order > 1 ? 1 : 0);
+
+ // 1. a.b
+ // Not overloadable (yet).
+ // 2. a->b
+ // Only one argument.
+ // 3. a->*b
+ case MEMBER_REF:
+ // 7. a << b
+ case LSHIFT_EXPR:
+ // 8. a >> b
+ case RSHIFT_EXPR:
+ // a && b
+ // Predates P0145R3.
+ case TRUTH_ANDIF_EXPR:
+ // a || b
+ // Predates P0145R3.
+ case TRUTH_ORIF_EXPR:
+ // a , b
+ // Predates P0145R3.
+ case COMPOUND_EXPR:
+ return (flag_strong_eval_order ? 1 : 0);
+
+ default:
+ return 0;
+ }
+}
+
+/* Subroutine of build_new_op: Add to CANDIDATES all candidates for the
+ operator indicated by CODE/CODE2. This function calls itself recursively to
+ handle C++20 rewritten comparison operator candidates.
+
+ LOOKUPS, if non-NULL, is the set of pertinent namespace-scope operator
+ overloads to consider. This parameter is used when instantiating a
+ dependent operator expression and has the same structure as
+ DEPENDENT_OPERATOR_TYPE_SAVED_LOOKUPS. */
+
+static tree
+add_operator_candidates (z_candidate **candidates,
+ tree_code code, tree_code code2,
+ vec<tree, va_gc> *arglist, tree lookups,
+ int flags, tsubst_flags_t complain)
+{
+ z_candidate *start_candidates = *candidates;
+ bool ismodop = code2 != ERROR_MARK;
+ tree fnname = ovl_op_identifier (ismodop, ismodop ? code2 : code);
+
+ /* LOOKUP_REWRITTEN is set when we're looking for the == or <=> operator to
+ rewrite from, and also when we're looking for the e.g. < operator to use
+ on the result of <=>. In the latter case, we don't want the flag set in
+ the candidate, we just want to suppress looking for rewrites. */
+ bool rewritten = (flags & LOOKUP_REWRITTEN);
+ if (rewritten && code != EQ_EXPR && code != SPACESHIP_EXPR)
+ flags &= ~LOOKUP_REWRITTEN;
+
+ bool memonly = false;
+ switch (code)
+ {
+ /* =, ->, [], () must be non-static member functions. */
+ case MODIFY_EXPR:
+ if (code2 != NOP_EXPR)
+ break;
+ /* FALLTHRU */
+ case COMPONENT_REF:
+ case ARRAY_REF:
+ memonly = true;
+ break;
+
+ default:
+ break;
+ }
+
+ /* Add namespace-scope operators to the list of functions to
+ consider. */
+ if (!memonly)
+ {
+ tree fns;
+ if (!lookups)
+ fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE);
+ /* If LOOKUPS is non-NULL, then we're instantiating a dependent operator
+ expression, and LOOKUPS is the result of stage 1 name lookup. */
+ else if (tree found = purpose_member (fnname, lookups))
+ fns = TREE_VALUE (found);
+ else
+ fns = NULL_TREE;
+ fns = lookup_arg_dependent (fnname, fns, arglist);
+ add_candidates (fns, NULL_TREE, arglist, NULL_TREE,
+ NULL_TREE, false, NULL_TREE, NULL_TREE,
+ flags, candidates, complain);
+ }
+
+ /* Add class-member operators to the candidate set. */
+ tree arg1_type = TREE_TYPE ((*arglist)[0]);
+ unsigned nargs = arglist->length () > 1 ? 2 : 1;
+ tree arg2_type = nargs > 1 ? TREE_TYPE ((*arglist)[1]) : NULL_TREE;
+ if (CLASS_TYPE_P (arg1_type))
+ {
+ tree fns = lookup_fnfields (arg1_type, fnname, 1, complain);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ if (fns)
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ NULL_TREE, arglist, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns),
+ BASELINK_ACCESS_BINFO (fns),
+ flags, candidates, complain);
+ }
+ /* Per [over.match.oper]3.2, if no operand has a class type, then
+ only non-member functions that have type T1 or reference to
+ cv-qualified-opt T1 for the first argument, if the first argument
+ has an enumeration type, or T2 or reference to cv-qualified-opt
+ T2 for the second argument, if the second argument has an
+ enumeration type. Filter out those that don't match. */
+ else if (! arg2_type || ! CLASS_TYPE_P (arg2_type))
+ {
+ struct z_candidate **candp, **next;
+
+ for (candp = candidates; *candp != start_candidates; candp = next)
+ {
+ unsigned i;
+ z_candidate *cand = *candp;
+ next = &cand->next;
+
+ tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (cand->fn));
+
+ for (i = 0; i < nargs; ++i)
+ {
+ tree parmtype = TREE_VALUE (parmlist);
+ tree argtype = unlowered_expr_type ((*arglist)[i]);
+
+ if (TYPE_REF_P (parmtype))
+ parmtype = TREE_TYPE (parmtype);
+ if (TREE_CODE (argtype) == ENUMERAL_TYPE
+ && (same_type_ignoring_top_level_qualifiers_p
+ (argtype, parmtype)))
+ break;
+
+ parmlist = TREE_CHAIN (parmlist);
+ }
+
+ /* No argument has an appropriate type, so remove this
+ candidate function from the list. */
+ if (i == nargs)
+ {
+ *candp = cand->next;
+ next = candp;
+ }
+ }
+ }
+
+ if (!rewritten)
+ {
+ /* The standard says to rewrite built-in candidates, too,
+ but there's no point. */
+ add_builtin_candidates (candidates, code, code2, fnname, arglist,
+ flags, complain);
+
+ /* Maybe add C++20 rewritten comparison candidates. */
+ tree_code rewrite_code = ERROR_MARK;
+ if (cxx_dialect >= cxx20
+ && nargs == 2
+ && (OVERLOAD_TYPE_P (arg1_type) || OVERLOAD_TYPE_P (arg2_type)))
+ switch (code)
+ {
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case SPACESHIP_EXPR:
+ rewrite_code = SPACESHIP_EXPR;
+ break;
+
+ case NE_EXPR:
+ case EQ_EXPR:
+ rewrite_code = EQ_EXPR;
+ break;
+
+ default:;
+ }
+
+ if (rewrite_code)
+ {
+ flags |= LOOKUP_REWRITTEN;
+ if (rewrite_code != code)
+ /* Add rewritten candidates in same order. */
+ add_operator_candidates (candidates, rewrite_code, ERROR_MARK,
+ arglist, lookups, flags, complain);
+
+ z_candidate *save_cand = *candidates;
+
+ /* Add rewritten candidates in reverse order. */
+ flags |= LOOKUP_REVERSED;
+ vec<tree,va_gc> *revlist = make_tree_vector ();
+ revlist->quick_push ((*arglist)[1]);
+ revlist->quick_push ((*arglist)[0]);
+ add_operator_candidates (candidates, rewrite_code, ERROR_MARK,
+ revlist, lookups, flags, complain);
+
+ /* Release the vec if we didn't add a candidate that uses it. */
+ for (z_candidate *c = *candidates; c != save_cand; c = c->next)
+ if (c->args == revlist)
+ {
+ revlist = NULL;
+ break;
+ }
+ release_tree_vector (revlist);
+ }
+ }
+
+ return NULL_TREE;
+}
+
+tree
+build_new_op (const op_location_t &loc, enum tree_code code, int flags,
+ tree arg1, tree arg2, tree arg3, tree lookups,
+ tree *overload, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ releasing_vec arglist;
+ tree result = NULL_TREE;
+ bool result_valid_p = false;
+ enum tree_code code2 = ERROR_MARK;
+ enum tree_code code_orig_arg1 = ERROR_MARK;
+ enum tree_code code_orig_arg2 = ERROR_MARK;
+ void *p;
+ bool strict_p;
+ bool any_viable_p;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ if (error_operand_p (arg1)
+ || error_operand_p (arg2)
+ || error_operand_p (arg3))
+ return error_mark_node;
+
+ bool ismodop = code == MODIFY_EXPR;
+ if (ismodop)
+ {
+ code2 = TREE_CODE (arg3);
+ arg3 = NULL_TREE;
+ }
+
+ tree arg1_type = unlowered_expr_type (arg1);
+ tree arg2_type = arg2 ? unlowered_expr_type (arg2) : NULL_TREE;
+
+ arg1 = prep_operand (arg1);
+
+ switch (code)
+ {
+ case NEW_EXPR:
+ case VEC_NEW_EXPR:
+ case VEC_DELETE_EXPR:
+ case DELETE_EXPR:
+ /* Use build_operator_new_call and build_op_delete_call instead. */
+ gcc_unreachable ();
+
+ case CALL_EXPR:
+ /* Use build_op_call instead. */
+ gcc_unreachable ();
+
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ /* These are saved for the sake of warn_logical_operator. */
+ code_orig_arg1 = TREE_CODE (arg1);
+ code_orig_arg2 = TREE_CODE (arg2);
+ break;
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ /* These are saved for the sake of maybe_warn_bool_compare. */
+ code_orig_arg1 = TREE_CODE (arg1_type);
+ code_orig_arg2 = TREE_CODE (arg2_type);
+ break;
+
+ default:
+ break;
+ }
+
+ arg2 = prep_operand (arg2);
+ arg3 = prep_operand (arg3);
+
+ if (code == COND_EXPR)
+ /* Use build_conditional_expr instead. */
+ gcc_unreachable ();
+ else if (! OVERLOAD_TYPE_P (arg1_type)
+ && (! arg2 || ! OVERLOAD_TYPE_P (arg2_type)))
+ goto builtin;
+
+ if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
+ {
+ arg2 = integer_zero_node;
+ arg2_type = integer_type_node;
+ }
+
+ arglist->quick_push (arg1);
+ if (arg2 != NULL_TREE)
+ arglist->quick_push (arg2);
+ if (arg3 != NULL_TREE)
+ arglist->quick_push (arg3);
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ result = add_operator_candidates (&candidates, code, code2, arglist,
+ lookups, flags, complain);
+ if (result == error_mark_node)
+ goto user_defined_result_ready;
+
+ switch (code)
+ {
+ case COMPOUND_EXPR:
+ case ADDR_EXPR:
+ /* For these, the built-in candidates set is empty
+ [over.match.oper]/3. We don't want non-strict matches
+ because exact matches are always possible with built-in
+ operators. The built-in candidate set for COMPONENT_REF
+ would be empty too, but since there are no such built-in
+ operators, we accept non-strict matches for them. */
+ strict_p = true;
+ break;
+
+ default:
+ strict_p = false;
+ break;
+ }
+
+ candidates = splice_viable (candidates, strict_p, &any_viable_p);
+ if (!any_viable_p)
+ {
+ switch (code)
+ {
+ case POSTINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ /* Don't try anything fancy if we're not allowed to produce
+ errors. */
+ if (!(complain & tf_error))
+ return error_mark_node;
+
+ /* Look for an `operator++ (int)'. Pre-1985 C++ didn't
+ distinguish between prefix and postfix ++ and
+ operator++() was used for both, so we allow this with
+ -fpermissive. */
+ else
+ {
+ tree fnname = ovl_op_identifier (ismodop, ismodop ? code2 : code);
+ const char *msg = (flag_permissive)
+ ? G_("no %<%D(int)%> declared for postfix %qs,"
+ " trying prefix operator instead")
+ : G_("no %<%D(int)%> declared for postfix %qs");
+ permerror (loc, msg, fnname, OVL_OP_INFO (false, code)->name);
+ }
+
+ if (!flag_permissive)
+ return error_mark_node;
+
+ if (code == POSTINCREMENT_EXPR)
+ code = PREINCREMENT_EXPR;
+ else
+ code = PREDECREMENT_EXPR;
+ result = build_new_op (loc, code, flags, arg1, NULL_TREE,
+ NULL_TREE, lookups, overload, complain);
+ break;
+
+ /* The caller will deal with these. */
+ case ADDR_EXPR:
+ case COMPOUND_EXPR:
+ case COMPONENT_REF:
+ case CO_AWAIT_EXPR:
+ result = NULL_TREE;
+ result_valid_p = true;
+ break;
+
+ default:
+ if (complain & tf_error)
+ {
+ /* If one of the arguments of the operator represents
+ an invalid use of member function pointer, try to report
+ a meaningful error ... */
+ if (invalid_nonstatic_memfn_p (loc, arg1, tf_error)
+ || invalid_nonstatic_memfn_p (loc, arg2, tf_error)
+ || invalid_nonstatic_memfn_p (loc, arg3, tf_error))
+ /* We displayed the error message. */;
+ else
+ {
+ /* ... Otherwise, report the more generic
+ "no matching operator found" error */
+ auto_diagnostic_group d;
+ op_error (loc, code, code2, arg1, arg2, arg3, FALSE);
+ print_z_candidates (loc, candidates);
+ }
+ }
+ result = error_mark_node;
+ break;
+ }
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ op_error (loc, code, code2, arg1, arg2, arg3, TRUE);
+ print_z_candidates (loc, candidates);
+ }
+ result = error_mark_node;
+ if (overload)
+ *overload = error_mark_node;
+ }
+ else if (TREE_CODE (cand->fn) == FUNCTION_DECL)
+ {
+ if (overload)
+ *overload = cand->fn;
+
+ if (resolve_args (arglist, complain) == NULL)
+ result = error_mark_node;
+ else
+ {
+ tsubst_flags_t ocomplain = complain;
+ if (cand->rewritten ())
+ /* We'll wrap this call in another one. */
+ ocomplain &= ~tf_decltype;
+ if (cand->reversed ())
+ {
+ /* We swapped these in add_candidate, swap them back now. */
+ std::swap (cand->convs[0], cand->convs[1]);
+ if (cand->fn == current_function_decl)
+ warning_at (loc, 0, "in C++20 this comparison calls the "
+ "current function recursively with reversed "
+ "arguments");
+ }
+ result = build_over_call (cand, LOOKUP_NORMAL, ocomplain);
+ }
+
+ if (trivial_fn_p (cand->fn) || DECL_IMMEDIATE_FUNCTION_P (cand->fn))
+ /* There won't be a CALL_EXPR. */;
+ else if (result && result != error_mark_node)
+ {
+ tree call = extract_call_expr (result);
+ CALL_EXPR_OPERATOR_SYNTAX (call) = true;
+
+ /* Specify evaluation order as per P0145R2. */
+ CALL_EXPR_ORDERED_ARGS (call) = false;
+ switch (op_is_ordered (code))
+ {
+ case -1:
+ CALL_EXPR_REVERSE_ARGS (call) = true;
+ break;
+
+ case 1:
+ CALL_EXPR_ORDERED_ARGS (call) = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ /* If this was a C++20 rewritten comparison, adjust the result. */
+ if (cand->rewritten ())
+ {
+ /* FIXME build_min_non_dep_op_overload can't handle rewrites. */
+ if (overload)
+ *overload = NULL_TREE;
+ switch (code)
+ {
+ case EQ_EXPR:
+ gcc_checking_assert (cand->reversed ());
+ gcc_fallthrough ();
+ case NE_EXPR:
+ /* If a rewritten operator== candidate is selected by
+ overload resolution for an operator @, its return type
+ shall be cv bool.... */
+ if (TREE_CODE (TREE_TYPE (result)) != BOOLEAN_TYPE)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error_at (loc, "return type of %qD is not %qs",
+ cand->fn, "bool");
+ inform (loc, "used as rewritten candidate for "
+ "comparison of %qT and %qT",
+ arg1_type, arg2_type);
+ }
+ result = error_mark_node;
+ }
+ else if (code == NE_EXPR)
+ /* !(y == x) or !(x == y) */
+ result = build1_loc (loc, TRUTH_NOT_EXPR,
+ boolean_type_node, result);
+ break;
+
+ /* If a rewritten operator<=> candidate is selected by
+ overload resolution for an operator @, x @ y is
+ interpreted as 0 @ (y <=> x) if the selected candidate is
+ a synthesized candidate with reversed order of parameters,
+ or (x <=> y) @ 0 otherwise, using the selected rewritten
+ operator<=> candidate. */
+ case SPACESHIP_EXPR:
+ if (!cand->reversed ())
+ /* We're in the build_new_op call below for an outer
+ reversed call; we don't need to do anything more. */
+ break;
+ gcc_fallthrough ();
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ {
+ tree lhs = result;
+ tree rhs = integer_zero_node;
+ if (cand->reversed ())
+ std::swap (lhs, rhs);
+ warning_sentinel ws (warn_zero_as_null_pointer_constant);
+ result = build_new_op (loc, code,
+ LOOKUP_NORMAL|LOOKUP_REWRITTEN,
+ lhs, rhs, NULL_TREE, lookups,
+ NULL, complain);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ }
+ else
+ {
+ /* Give any warnings we noticed during overload resolution. */
+ if (cand->warnings && (complain & tf_warning))
+ {
+ struct candidate_warning *w;
+ for (w = cand->warnings; w; w = w->next)
+ joust (cand, w->loser, 1, complain);
+ }
+
+ /* Check for comparison of different enum types. */
+ switch (code)
+ {
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ if (TREE_CODE (arg1_type) == ENUMERAL_TYPE
+ && TREE_CODE (arg2_type) == ENUMERAL_TYPE
+ && (TYPE_MAIN_VARIANT (arg1_type)
+ != TYPE_MAIN_VARIANT (arg2_type))
+ && (complain & tf_warning))
+ warning_at (loc, OPT_Wenum_compare,
+ "comparison between %q#T and %q#T",
+ arg1_type, arg2_type);
+ break;
+ default:
+ break;
+ }
+
+ /* "If a built-in candidate is selected by overload resolution, the
+ operands of class type are converted to the types of the
+ corresponding parameters of the selected operation function,
+ except that the second standard conversion sequence of a
+ user-defined conversion sequence (12.3.3.1.2) is not applied." */
+ conversion *conv = cand->convs[0];
+ if (conv->user_conv_p)
+ {
+ conv = strip_standard_conversion (conv);
+ arg1 = convert_like (conv, arg1, complain);
+ }
+
+ if (arg2)
+ {
+ conv = cand->convs[1];
+ if (conv->user_conv_p)
+ {
+ conv = strip_standard_conversion (conv);
+ arg2 = convert_like (conv, arg2, complain);
+ }
+ }
+
+ if (arg3)
+ {
+ conv = cand->convs[2];
+ if (conv->user_conv_p)
+ {
+ conv = strip_standard_conversion (conv);
+ arg3 = convert_like (conv, arg3, complain);
+ }
+ }
+ }
+ }
+
+ user_defined_result_ready:
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (result || result_valid_p)
+ return result;
+
+ builtin:
+ switch (code)
+ {
+ case MODIFY_EXPR:
+ return cp_build_modify_expr (loc, arg1, code2, arg2, complain);
+
+ case INDIRECT_REF:
+ return cp_build_indirect_ref (loc, arg1, RO_UNARY_STAR, complain);
+
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ if (complain & tf_warning)
+ warn_logical_operator (loc, code, boolean_type_node,
+ code_orig_arg1, arg1,
+ code_orig_arg2, arg2);
+ /* Fall through. */
+ case GT_EXPR:
+ case LT_EXPR:
+ case GE_EXPR:
+ case LE_EXPR:
+ case EQ_EXPR:
+ case NE_EXPR:
+ if ((complain & tf_warning)
+ && ((code_orig_arg1 == BOOLEAN_TYPE)
+ ^ (code_orig_arg2 == BOOLEAN_TYPE)))
+ maybe_warn_bool_compare (loc, code, arg1, arg2);
+ if (complain & tf_warning && warn_tautological_compare)
+ warn_tautological_cmp (loc, code, arg1, arg2);
+ /* Fall through. */
+ case SPACESHIP_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ case MULT_EXPR:
+ case TRUNC_DIV_EXPR:
+ case MAX_EXPR:
+ case MIN_EXPR:
+ case LSHIFT_EXPR:
+ case RSHIFT_EXPR:
+ case TRUNC_MOD_EXPR:
+ case BIT_AND_EXPR:
+ case BIT_IOR_EXPR:
+ case BIT_XOR_EXPR:
+ return cp_build_binary_op (loc, code, arg1, arg2, complain);
+
+ case UNARY_PLUS_EXPR:
+ case NEGATE_EXPR:
+ case BIT_NOT_EXPR:
+ case TRUTH_NOT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case PREDECREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case ABS_EXPR:
+ case CO_AWAIT_EXPR:
+ return cp_build_unary_op (code, arg1, false, complain);
+
+ case ARRAY_REF:
+ return cp_build_array_ref (input_location, arg1, arg2, complain);
+
+ case MEMBER_REF:
+ return build_m_component_ref (cp_build_indirect_ref (loc, arg1,
+ RO_ARROW_STAR,
+ complain),
+ arg2, complain);
+
+ /* The caller will deal with these. */
+ case ADDR_EXPR:
+ case COMPONENT_REF:
+ case COMPOUND_EXPR:
+ return NULL_TREE;
+
+ default:
+ gcc_unreachable ();
+ }
+ return NULL_TREE;
+}
+
+/* Build a new call to operator[]. This may change ARGS. */
+
+tree
+build_op_subscript (const op_location_t &loc, tree obj,
+ vec<tree, va_gc> **args, tree *overload,
+ tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ tree fns, first_mem_arg = NULL_TREE;
+ bool any_viable_p;
+ tree result = NULL_TREE;
+ void *p;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ obj = mark_lvalue_use (obj);
+
+ if (error_operand_p (obj))
+ return error_mark_node;
+
+ tree type = TREE_TYPE (obj);
+
+ obj = prep_operand (obj);
+
+ if (TYPE_BINFO (type))
+ {
+ fns = lookup_fnfields (TYPE_BINFO (type), ovl_op_identifier (ARRAY_REF),
+ 1, complain);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ fns = NULL_TREE;
+
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ if (fns)
+ {
+ first_mem_arg = obj;
+
+ add_candidates (BASELINK_FUNCTIONS (fns),
+ first_mem_arg, *args, NULL_TREE,
+ NULL_TREE, false,
+ BASELINK_BINFO (fns), BASELINK_ACCESS_BINFO (fns),
+ LOOKUP_NORMAL, &candidates, complain);
+ }
+
+ /* Be strict here because if we choose a bad conversion candidate, the
+ errors we get won't mention the call context. */
+ candidates = splice_viable (candidates, true, &any_viable_p);
+ if (!any_viable_p)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error ("no match for call to %<%T::operator[] (%A)%>",
+ TREE_TYPE (obj), build_tree_list_vec (*args));
+ print_z_candidates (loc, candidates);
+ }
+ result = error_mark_node;
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ error ("call of %<%T::operator[] (%A)%> is ambiguous",
+ TREE_TYPE (obj), build_tree_list_vec (*args));
+ print_z_candidates (loc, candidates);
+ }
+ result = error_mark_node;
+ }
+ else if (TREE_CODE (cand->fn) == FUNCTION_DECL
+ && DECL_OVERLOADED_OPERATOR_P (cand->fn)
+ && DECL_OVERLOADED_OPERATOR_IS (cand->fn, ARRAY_REF))
+ {
+ if (overload)
+ *overload = cand->fn;
+ result = build_over_call (cand, LOOKUP_NORMAL, complain);
+ if (trivial_fn_p (cand->fn) || DECL_IMMEDIATE_FUNCTION_P (cand->fn))
+ /* There won't be a CALL_EXPR. */;
+ else if (result && result != error_mark_node)
+ {
+ tree call = extract_call_expr (result);
+ CALL_EXPR_OPERATOR_SYNTAX (call) = true;
+
+ /* Specify evaluation order as per P0145R2. */
+ CALL_EXPR_ORDERED_ARGS (call) = op_is_ordered (ARRAY_REF) == 1;
+ }
+ }
+ else
+ gcc_unreachable ();
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return result;
+}
+
+/* CALL was returned by some call-building function; extract the actual
+ CALL_EXPR from any bits that have been tacked on, e.g. by
+ convert_from_reference. */
+
+tree
+extract_call_expr (tree call)
+{
+ while (TREE_CODE (call) == COMPOUND_EXPR)
+ call = TREE_OPERAND (call, 1);
+ if (REFERENCE_REF_P (call))
+ call = TREE_OPERAND (call, 0);
+ if (TREE_CODE (call) == TARGET_EXPR)
+ call = TARGET_EXPR_INITIAL (call);
+ if (cxx_dialect >= cxx20)
+ switch (TREE_CODE (call))
+ {
+ /* C++20 rewritten comparison operators. */
+ case TRUTH_NOT_EXPR:
+ call = TREE_OPERAND (call, 0);
+ break;
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ case SPACESHIP_EXPR:
+ {
+ tree op0 = TREE_OPERAND (call, 0);
+ if (integer_zerop (op0))
+ call = TREE_OPERAND (call, 1);
+ else
+ call = op0;
+ }
+ break;
+ default:;
+ }
+
+ gcc_assert (TREE_CODE (call) == CALL_EXPR
+ || TREE_CODE (call) == AGGR_INIT_EXPR
+ || call == error_mark_node);
+ return call;
+}
+
+/* Returns true if FN has two parameters, of which the second has type
+ size_t. */
+
+static bool
+second_parm_is_size_t (tree fn)
+{
+ tree t = FUNCTION_ARG_CHAIN (fn);
+ if (!t || !same_type_p (TREE_VALUE (t), size_type_node))
+ return false;
+ t = TREE_CHAIN (t);
+ if (t == void_list_node)
+ return true;
+ return false;
+}
+
+/* True if T, an allocation function, has std::align_val_t as its second
+ argument. */
+
+bool
+aligned_allocation_fn_p (tree t)
+{
+ if (!aligned_new_threshold)
+ return false;
+
+ tree a = FUNCTION_ARG_CHAIN (t);
+ return (a && same_type_p (TREE_VALUE (a), align_type_node));
+}
+
+/* True if T is std::destroying_delete_t. */
+
+static bool
+std_destroying_delete_t_p (tree t)
+{
+ return (TYPE_CONTEXT (t) == std_node
+ && id_equal (TYPE_IDENTIFIER (t), "destroying_delete_t"));
+}
+
+/* A deallocation function with at least two parameters whose second parameter
+ type is of type std::destroying_delete_t is a destroying operator delete. A
+ destroying operator delete shall be a class member function named operator
+ delete. [ Note: Array deletion cannot use a destroying operator
+ delete. --end note ] */
+
+tree
+destroying_delete_p (tree t)
+{
+ tree a = TYPE_ARG_TYPES (TREE_TYPE (t));
+ if (!a || !TREE_CHAIN (a))
+ return NULL_TREE;
+ tree type = TREE_VALUE (TREE_CHAIN (a));
+ return std_destroying_delete_t_p (type) ? type : NULL_TREE;
+}
+
+struct dealloc_info
+{
+ bool sized;
+ bool aligned;
+ tree destroying;
+};
+
+/* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation
+ function (3.7.4.2 [basic.stc.dynamic.deallocation]). If so, and DI is
+ non-null, also set *DI. */
+
+static bool
+usual_deallocation_fn_p (tree t, dealloc_info *di)
+{
+ if (di) *di = dealloc_info();
+
+ /* A template instance is never a usual deallocation function,
+ regardless of its signature. */
+ if (TREE_CODE (t) == TEMPLATE_DECL
+ || primary_template_specialization_p (t))
+ return false;
+
+ /* A usual deallocation function is a deallocation function whose parameters
+ after the first are
+ - optionally, a parameter of type std::destroying_delete_t, then
+ - optionally, a parameter of type std::size_t, then
+ - optionally, a parameter of type std::align_val_t. */
+ bool global = DECL_NAMESPACE_SCOPE_P (t);
+ tree chain = FUNCTION_ARG_CHAIN (t);
+ if (chain && destroying_delete_p (t))
+ {
+ if (di) di->destroying = TREE_VALUE (chain);
+ chain = TREE_CHAIN (chain);
+ }
+ if (chain
+ && (!global || flag_sized_deallocation)
+ && same_type_p (TREE_VALUE (chain), size_type_node))
+ {
+ if (di) di->sized = true;
+ chain = TREE_CHAIN (chain);
+ }
+ if (chain && aligned_new_threshold
+ && same_type_p (TREE_VALUE (chain), align_type_node))
+ {
+ if (di) di->aligned = true;
+ chain = TREE_CHAIN (chain);
+ }
+ return (chain == void_list_node);
+}
+
+/* Just return whether FN is a usual deallocation function. */
+
+bool
+usual_deallocation_fn_p (tree fn)
+{
+ return usual_deallocation_fn_p (fn, NULL);
+}
+
+/* Build a call to operator delete. This has to be handled very specially,
+ because the restrictions on what signatures match are different from all
+ other call instances. For a normal delete, only a delete taking (void *)
+ or (void *, size_t) is accepted. For a placement delete, only an exact
+ match with the placement new is accepted.
+
+ CODE is either DELETE_EXPR or VEC_DELETE_EXPR.
+ ADDR is the pointer to be deleted.
+ SIZE is the size of the memory block to be deleted.
+ GLOBAL_P is true if the delete-expression should not consider
+ class-specific delete operators.
+ PLACEMENT is the corresponding placement new call, or NULL_TREE.
+
+ If this call to "operator delete" is being generated as part to
+ deallocate memory allocated via a new-expression (as per [expr.new]
+ which requires that if the initialization throws an exception then
+ we call a deallocation function), then ALLOC_FN is the allocation
+ function. */
+
+tree
+build_op_delete_call (enum tree_code code, tree addr, tree size,
+ bool global_p, tree placement,
+ tree alloc_fn, tsubst_flags_t complain)
+{
+ tree fn = NULL_TREE;
+ tree fns, fnname, type, t;
+ dealloc_info di_fn = { };
+
+ if (addr == error_mark_node)
+ return error_mark_node;
+
+ type = strip_array_types (TREE_TYPE (TREE_TYPE (addr)));
+
+ fnname = ovl_op_identifier (false, code);
+
+ if (CLASS_TYPE_P (type)
+ && COMPLETE_TYPE_P (complete_type (type))
+ && !global_p)
+ /* In [class.free]
+
+ If the result of the lookup is ambiguous or inaccessible, or if
+ the lookup selects a placement deallocation function, the
+ program is ill-formed.
+
+ Therefore, we ask lookup_fnfields to complain about ambiguity. */
+ {
+ fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1, complain);
+ if (fns == error_mark_node)
+ return error_mark_node;
+ }
+ else
+ fns = NULL_TREE;
+
+ if (fns == NULL_TREE)
+ fns = lookup_name (fnname, LOOK_where::BLOCK_NAMESPACE);
+
+ /* Strip const and volatile from addr. */
+ tree oaddr = addr;
+ addr = cp_convert (ptr_type_node, addr, complain);
+
+ tree excluded_destroying = NULL_TREE;
+
+ if (placement)
+ {
+ /* "A declaration of a placement deallocation function matches the
+ declaration of a placement allocation function if it has the same
+ number of parameters and, after parameter transformations (8.3.5),
+ all parameter types except the first are identical."
+
+ So we build up the function type we want and ask instantiate_type
+ to get it for us. */
+ t = FUNCTION_ARG_CHAIN (alloc_fn);
+ t = tree_cons (NULL_TREE, ptr_type_node, t);
+ t = build_function_type (void_type_node, t);
+
+ fn = instantiate_type (t, fns, tf_none);
+ if (fn == error_mark_node)
+ return NULL_TREE;
+
+ fn = MAYBE_BASELINK_FUNCTIONS (fn);
+
+ /* "If the lookup finds the two-parameter form of a usual deallocation
+ function (3.7.4.2) and that function, considered as a placement
+ deallocation function, would have been selected as a match for the
+ allocation function, the program is ill-formed." */
+ if (second_parm_is_size_t (fn))
+ {
+ const char *const msg1
+ = G_("exception cleanup for this placement new selects "
+ "non-placement %<operator delete%>");
+ const char *const msg2
+ = G_("%qD is a usual (non-placement) deallocation "
+ "function in C++14 (or with %<-fsized-deallocation%>)");
+
+ /* But if the class has an operator delete (void *), then that is
+ the usual deallocation function, so we shouldn't complain
+ about using the operator delete (void *, size_t). */
+ if (DECL_CLASS_SCOPE_P (fn))
+ for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
+ {
+ if (usual_deallocation_fn_p (elt)
+ && FUNCTION_ARG_CHAIN (elt) == void_list_node)
+ goto ok;
+ }
+ /* Before C++14 a two-parameter global deallocation function is
+ always a placement deallocation function, but warn if
+ -Wc++14-compat. */
+ else if (!flag_sized_deallocation)
+ {
+ if (complain & tf_warning)
+ {
+ auto_diagnostic_group d;
+ if (warning (OPT_Wc__14_compat, msg1))
+ inform (DECL_SOURCE_LOCATION (fn), msg2, fn);
+ }
+ goto ok;
+ }
+
+ if (complain & tf_warning_or_error)
+ {
+ auto_diagnostic_group d;
+ if (permerror (input_location, msg1))
+ {
+ /* Only mention C++14 for namespace-scope delete. */
+ if (DECL_NAMESPACE_SCOPE_P (fn))
+ inform (DECL_SOURCE_LOCATION (fn), msg2, fn);
+ else
+ inform (DECL_SOURCE_LOCATION (fn),
+ "%qD is a usual (non-placement) deallocation "
+ "function", fn);
+ }
+ }
+ else
+ return error_mark_node;
+ ok:;
+ }
+ }
+ else
+ /* "Any non-placement deallocation function matches a non-placement
+ allocation function. If the lookup finds a single matching
+ deallocation function, that function will be called; otherwise, no
+ deallocation function will be called." */
+ for (tree elt : lkp_range (MAYBE_BASELINK_FUNCTIONS (fns)))
+ {
+ dealloc_info di_elt;
+ if (usual_deallocation_fn_p (elt, &di_elt))
+ {
+ /* If we're called for an EH cleanup in a new-expression, we can't
+ use a destroying delete; the exception was thrown before the
+ object was constructed. */
+ if (alloc_fn && di_elt.destroying)
+ {
+ excluded_destroying = elt;
+ continue;
+ }
+
+ if (!fn)
+ {
+ fn = elt;
+ di_fn = di_elt;
+ continue;
+ }
+
+ /* -- If any of the deallocation functions is a destroying
+ operator delete, all deallocation functions that are not
+ destroying operator deletes are eliminated from further
+ consideration. */
+ if (di_elt.destroying != di_fn.destroying)
+ {
+ if (di_elt.destroying)
+ {
+ fn = elt;
+ di_fn = di_elt;
+ }
+ continue;
+ }
+
+ /* -- If the type has new-extended alignment, a function with a
+ parameter of type std::align_val_t is preferred; otherwise a
+ function without such a parameter is preferred. If exactly one
+ preferred function is found, that function is selected and the
+ selection process terminates. If more than one preferred
+ function is found, all non-preferred functions are eliminated
+ from further consideration. */
+ if (aligned_new_threshold)
+ {
+ bool want_align = type_has_new_extended_alignment (type);
+ if (di_elt.aligned != di_fn.aligned)
+ {
+ if (want_align == di_elt.aligned)
+ {
+ fn = elt;
+ di_fn = di_elt;
+ }
+ continue;
+ }
+ }
+
+ /* -- If the deallocation functions have class scope, the one
+ without a parameter of type std::size_t is selected. */
+ bool want_size;
+ if (DECL_CLASS_SCOPE_P (fn))
+ want_size = false;
+
+ /* -- If the type is complete and if, for the second alternative
+ (delete array) only, the operand is a pointer to a class type
+ with a non-trivial destructor or a (possibly multi-dimensional)
+ array thereof, the function with a parameter of type std::size_t
+ is selected.
+
+ -- Otherwise, it is unspecified whether a deallocation function
+ with a parameter of type std::size_t is selected. */
+ else
+ {
+ want_size = COMPLETE_TYPE_P (type);
+ if (code == VEC_DELETE_EXPR
+ && !TYPE_VEC_NEW_USES_COOKIE (type))
+ /* We need a cookie to determine the array size. */
+ want_size = false;
+ }
+ gcc_assert (di_fn.sized != di_elt.sized);
+ if (want_size == di_elt.sized)
+ {
+ fn = elt;
+ di_fn = di_elt;
+ }
+ }
+ }
+
+ /* If we have a matching function, call it. */
+ if (fn)
+ {
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ /* If the FN is a member function, make sure that it is
+ accessible. */
+ if (BASELINK_P (fns))
+ perform_or_defer_access_check (BASELINK_BINFO (fns), fn, fn,
+ complain);
+
+ /* Core issue 901: It's ok to new a type with deleted delete. */
+ if (DECL_DELETED_FN (fn) && alloc_fn)
+ return NULL_TREE;
+
+ tree ret;
+ if (placement)
+ {
+ /* The placement args might not be suitable for overload
+ resolution at this point, so build the call directly. */
+ int nargs = call_expr_nargs (placement);
+ tree *argarray = XALLOCAVEC (tree, nargs);
+ int i;
+ argarray[0] = addr;
+ for (i = 1; i < nargs; i++)
+ argarray[i] = CALL_EXPR_ARG (placement, i);
+ if (!mark_used (fn, complain) && !(complain & tf_error))
+ return error_mark_node;
+ ret = build_cxx_call (fn, nargs, argarray, complain);
+ }
+ else
+ {
+ tree destroying = di_fn.destroying;
+ if (destroying)
+ {
+ /* Strip const and volatile from addr but retain the type of the
+ object. */
+ tree rtype = TREE_TYPE (TREE_TYPE (oaddr));
+ rtype = cv_unqualified (rtype);
+ rtype = TYPE_POINTER_TO (rtype);
+ addr = cp_convert (rtype, oaddr, complain);
+ destroying = build_functional_cast (input_location,
+ destroying, NULL_TREE,
+ complain);
+ }
+
+ releasing_vec args;
+ args->quick_push (addr);
+ if (destroying)
+ args->quick_push (destroying);
+ if (di_fn.sized)
+ args->quick_push (size);
+ if (di_fn.aligned)
+ {
+ tree al = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (type));
+ args->quick_push (al);
+ }
+ ret = cp_build_function_call_vec (fn, &args, complain);
+ }
+
+ /* Set this flag for all callers of this function. In addition to
+ delete-expressions, this is called for deallocating coroutine state;
+ treat that as an implicit delete-expression. This is also called for
+ the delete if the constructor throws in a new-expression, and for a
+ deleting destructor (which implements a delete-expression). */
+ /* But leave this flag off for destroying delete to avoid wrong
+ assumptions in the optimizers. */
+ tree call = extract_call_expr (ret);
+ if (TREE_CODE (call) == CALL_EXPR && !destroying_delete_p (fn))
+ CALL_FROM_NEW_OR_DELETE_P (call) = 1;
+
+ return ret;
+ }
+
+ /* If there's only a destroying delete that we can't use because the
+ object isn't constructed yet, and we used global new, use global
+ delete as well. */
+ if (excluded_destroying
+ && DECL_NAMESPACE_SCOPE_P (alloc_fn))
+ return build_op_delete_call (code, addr, size, true, placement,
+ alloc_fn, complain);
+
+ /* [expr.new]
+
+ If no unambiguous matching deallocation function can be found,
+ propagating the exception does not cause the object's memory to
+ be freed. */
+ if (alloc_fn)
+ {
+ if ((complain & tf_warning)
+ && !placement)
+ {
+ bool w = warning (0,
+ "no corresponding deallocation function for %qD",
+ alloc_fn);
+ if (w && excluded_destroying)
+ inform (DECL_SOURCE_LOCATION (excluded_destroying), "destroying "
+ "delete %qD cannot be used to release the allocated memory"
+ " if the initialization throws because the object is not "
+ "constructed yet", excluded_destroying);
+ }
+ return NULL_TREE;
+ }
+
+ if (complain & tf_error)
+ error ("no suitable %<operator %s%> for %qT",
+ OVL_OP_INFO (false, code)->name, type);
+ return error_mark_node;
+}
+
+/* Issue diagnostics about a disallowed access of DECL, using DIAG_DECL
+ in the diagnostics.
+
+ If ISSUE_ERROR is true, then issue an error about the access, followed
+ by a note showing the declaration. Otherwise, just show the note.
+
+ DIAG_DECL and DIAG_LOCATION will almost always be the same.
+ DIAG_LOCATION is just another DECL. NO_ACCESS_REASON is an optional
+ parameter used to specify why DECL wasn't accessible (e.g. ak_private
+ would be because DECL was private). If not using NO_ACCESS_REASON,
+ then it must be ak_none, and the access failure reason will be
+ figured out by looking at the protection of DECL. */
+
+void
+complain_about_access (tree decl, tree diag_decl, tree diag_location,
+ bool issue_error, access_kind no_access_reason)
+{
+ /* If we have not already figured out why DECL is inaccessible... */
+ if (no_access_reason == ak_none)
+ {
+ /* Examine the access of DECL to find out why. */
+ if (TREE_PRIVATE (decl))
+ no_access_reason = ak_private;
+ else if (TREE_PROTECTED (decl))
+ no_access_reason = ak_protected;
+ }
+
+ /* Now generate an error message depending on calculated access. */
+ if (no_access_reason == ak_private)
+ {
+ if (issue_error)
+ error ("%q#D is private within this context", diag_decl);
+ inform (DECL_SOURCE_LOCATION (diag_location), "declared private here");
+ }
+ else if (no_access_reason == ak_protected)
+ {
+ if (issue_error)
+ error ("%q#D is protected within this context", diag_decl);
+ inform (DECL_SOURCE_LOCATION (diag_location), "declared protected here");
+ }
+ /* Couldn't figure out why DECL is inaccesible, so just say it's
+ inaccessible. */
+ else
+ {
+ if (issue_error)
+ error ("%q#D is inaccessible within this context", diag_decl);
+ inform (DECL_SOURCE_LOCATION (diag_decl), "declared here");
+ }
+}
+
+/* Initialize a temporary of type TYPE with EXPR. The FLAGS are a
+ bitwise or of LOOKUP_* values. If any errors are warnings are
+ generated, set *DIAGNOSTIC_FN to "error" or "warning",
+ respectively. If no diagnostics are generated, set *DIAGNOSTIC_FN
+ to NULL. */
+
+static tree
+build_temp (tree expr, tree type, int flags,
+ diagnostic_t *diagnostic_kind, tsubst_flags_t complain)
+{
+ int savew, savee;
+
+ *diagnostic_kind = DK_UNSPECIFIED;
+
+ /* If the source is a packed field, calling the copy constructor will require
+ binding the field to the reference parameter to the copy constructor, and
+ we'll end up with an infinite loop. If we can use a bitwise copy, then
+ do that now. */
+ if ((lvalue_kind (expr) & clk_packed)
+ && CLASS_TYPE_P (TREE_TYPE (expr))
+ && !type_has_nontrivial_copy_init (TREE_TYPE (expr)))
+ return get_target_expr_sfinae (expr, complain);
+
+ /* In decltype, we might have decided not to wrap this call in a TARGET_EXPR.
+ But it turns out to be a subexpression, so perform temporary
+ materialization now. */
+ if (TREE_CODE (expr) == CALL_EXPR
+ && CLASS_TYPE_P (type)
+ && same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (expr)))
+ expr = build_cplus_new (type, expr, complain);
+
+ savew = warningcount + werrorcount, savee = errorcount;
+ releasing_vec args (make_tree_vector_single (expr));
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, flags, complain);
+ if (warningcount + werrorcount > savew)
+ *diagnostic_kind = DK_WARNING;
+ else if (errorcount > savee)
+ *diagnostic_kind = DK_ERROR;
+ return expr;
+}
+
+/* Get any location for EXPR, falling back to input_location.
+
+ If the result is in a system header and is the virtual location for
+ a token coming from the expansion of a macro, unwind it to the
+ location of the expansion point of the macro (e.g. to avoid the
+ diagnostic being suppressed for expansions of NULL where "NULL" is
+ in a system header). */
+
+static location_t
+get_location_for_expr_unwinding_for_system_header (tree expr)
+{
+ location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+ loc = expansion_point_location_if_in_system_header (loc);
+ return loc;
+}
+
+/* Perform warnings about peculiar, but valid, conversions from/to NULL.
+ Also handle a subset of zero as null warnings.
+ EXPR is implicitly converted to type TOTYPE.
+ FN and ARGNUM are used for diagnostics. */
+
+static void
+conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
+{
+ /* Issue warnings about peculiar, but valid, uses of NULL. */
+ if (TREE_CODE (totype) != BOOLEAN_TYPE
+ && ARITHMETIC_TYPE_P (totype)
+ && null_node_p (expr))
+ {
+ location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
+ if (fn)
+ {
+ auto_diagnostic_group d;
+ if (warning_at (loc, OPT_Wconversion_null,
+ "passing NULL to non-pointer argument %P of %qD",
+ argnum, fn))
+ inform (get_fndecl_argument_location (fn, argnum),
+ " declared here");
+ }
+ else
+ warning_at (loc, OPT_Wconversion_null,
+ "converting to non-pointer type %qT from NULL", totype);
+ }
+
+ /* Issue warnings if "false" is converted to a NULL pointer */
+ else if (TREE_CODE (TREE_TYPE (expr)) == BOOLEAN_TYPE
+ && TYPE_PTR_P (totype))
+ {
+ location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
+ if (fn)
+ {
+ auto_diagnostic_group d;
+ if (warning_at (loc, OPT_Wconversion_null,
+ "converting %<false%> to pointer type for argument "
+ "%P of %qD", argnum, fn))
+ inform (get_fndecl_argument_location (fn, argnum),
+ " declared here");
+ }
+ else
+ warning_at (loc, OPT_Wconversion_null,
+ "converting %<false%> to pointer type %qT", totype);
+ }
+ /* Handle zero as null pointer warnings for cases other
+ than EQ_EXPR and NE_EXPR */
+ else if ((TYPE_PTR_OR_PTRMEM_P (totype) || NULLPTR_TYPE_P (totype))
+ && null_ptr_cst_p (expr))
+ {
+ location_t loc = get_location_for_expr_unwinding_for_system_header (expr);
+ maybe_warn_zero_as_null_pointer_constant (expr, loc);
+ }
+}
+
+/* We gave a diagnostic during a conversion. If this was in the second
+ standard conversion sequence of a user-defined conversion sequence, say
+ which user-defined conversion. */
+
+static void
+maybe_print_user_conv_context (conversion *convs)
+{
+ if (convs->user_conv_p)
+ for (conversion *t = convs; t; t = next_conversion (t))
+ if (t->kind == ck_user)
+ {
+ print_z_candidate (0, N_(" after user-defined conversion:"),
+ t->cand);
+ break;
+ }
+}
+
+/* Locate the parameter with the given index within FNDECL.
+ ARGNUM is zero based, -1 indicates the `this' argument of a method.
+ Return the location of the FNDECL itself if there are problems. */
+
+location_t
+get_fndecl_argument_location (tree fndecl, int argnum)
+{
+ /* The locations of implicitly-declared functions are likely to be
+ more meaningful than those of their parameters. */
+ if (DECL_ARTIFICIAL (fndecl))
+ return DECL_SOURCE_LOCATION (fndecl);
+
+ int i;
+ tree param;
+
+ /* Locate param by index within DECL_ARGUMENTS (fndecl). */
+ for (i = 0, param = FUNCTION_FIRST_USER_PARM (fndecl);
+ i < argnum && param;
+ i++, param = TREE_CHAIN (param))
+ ;
+
+ /* If something went wrong (e.g. if we have a builtin and thus no arguments),
+ return the location of FNDECL. */
+ if (param == NULL)
+ return DECL_SOURCE_LOCATION (fndecl);
+
+ return DECL_SOURCE_LOCATION (param);
+}
+
+/* If FNDECL is non-NULL, issue a note highlighting ARGNUM
+ within its declaration (or the fndecl itself if something went
+ wrong). */
+
+void
+maybe_inform_about_fndecl_for_bogus_argument_init (tree fn, int argnum)
+{
+ if (fn)
+ inform (get_fndecl_argument_location (fn, argnum),
+ " initializing argument %P of %qD", argnum, fn);
+}
+
+/* Maybe warn about C++20 Conversions to arrays of unknown bound. C is
+ the conversion, EXPR is the expression we're converting. */
+
+static void
+maybe_warn_array_conv (location_t loc, conversion *c, tree expr)
+{
+ if (cxx_dialect >= cxx20)
+ return;
+
+ tree type = TREE_TYPE (expr);
+ type = strip_pointer_operator (type);
+
+ if (TREE_CODE (type) != ARRAY_TYPE
+ || TYPE_DOMAIN (type) == NULL_TREE)
+ return;
+
+ if (pedantic && conv_binds_to_array_of_unknown_bound (c))
+ pedwarn (loc, OPT_Wc__20_extensions,
+ "conversions to arrays of unknown bound "
+ "are only available with %<-std=c++20%> or %<-std=gnu++20%>");
+}
+
+/* We call this recursively in convert_like_internal. */
+static tree convert_like (conversion *, tree, tree, int, bool, bool,
+ tsubst_flags_t);
+
+/* Perform the conversions in CONVS on the expression EXPR. FN and
+ ARGNUM are used for diagnostics. ARGNUM is zero based, -1
+ indicates the `this' argument of a method. INNER is nonzero when
+ being called to continue a conversion chain. It is negative when a
+ reference binding will be applied, positive otherwise. If
+ ISSUE_CONVERSION_WARNINGS is true, warnings about suspicious
+ conversions will be emitted if appropriate. If C_CAST_P is true,
+ this conversion is coming from a C-style cast; in that case,
+ conversions to inaccessible bases are permitted. */
+
+static tree
+convert_like_internal (conversion *convs, tree expr, tree fn, int argnum,
+ bool issue_conversion_warnings, bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ tree totype = convs->type;
+ diagnostic_t diag_kind;
+ int flags;
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+
+ if (convs->bad_p && !(complain & tf_error))
+ return error_mark_node;
+
+ if (convs->bad_p
+ && convs->kind != ck_user
+ && convs->kind != ck_list
+ && convs->kind != ck_ambig
+ && (convs->kind != ck_ref_bind
+ || (convs->user_conv_p && next_conversion (convs)->bad_p))
+ && (convs->kind != ck_rvalue
+ || SCALAR_TYPE_P (totype))
+ && convs->kind != ck_base)
+ {
+ bool complained = false;
+ conversion *t = convs;
+
+ /* Give a helpful error if this is bad because of excess braces. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && SCALAR_TYPE_P (totype)
+ && CONSTRUCTOR_NELTS (expr) > 0
+ && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+ {
+ complained = permerror (loc, "too many braces around initializer "
+ "for %qT", totype);
+ while (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_NELTS (expr) == 1)
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ }
+
+ /* Give a helpful error if this is bad because a conversion to bool
+ from std::nullptr_t requires direct-initialization. */
+ if (NULLPTR_TYPE_P (TREE_TYPE (expr))
+ && TREE_CODE (totype) == BOOLEAN_TYPE)
+ complained = permerror (loc, "converting to %qH from %qI requires "
+ "direct-initialization",
+ totype, TREE_TYPE (expr));
+
+ for (; t ; t = next_conversion (t))
+ {
+ if (t->kind == ck_user && t->cand->reason)
+ {
+ auto_diagnostic_group d;
+ complained = permerror (loc, "invalid user-defined conversion "
+ "from %qH to %qI", TREE_TYPE (expr),
+ totype);
+ if (complained)
+ print_z_candidate (loc, N_("candidate is:"), t->cand);
+ expr = convert_like (t, expr, fn, argnum,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false, complain);
+ if (convs->kind == ck_ref_bind)
+ expr = convert_to_reference (totype, expr, CONV_IMPLICIT,
+ LOOKUP_NORMAL, NULL_TREE,
+ complain);
+ else
+ expr = cp_convert (totype, expr, complain);
+ if (complained)
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+ return expr;
+ }
+ else if (t->kind == ck_user || !t->bad_p)
+ {
+ expr = convert_like (t, expr, fn, argnum,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false, complain);
+ break;
+ }
+ else if (t->kind == ck_ambig)
+ return convert_like (t, expr, fn, argnum,
+ /*issue_conversion_warnings=*/false,
+ /*c_cast_p=*/false, complain);
+ else if (t->kind == ck_identity)
+ break;
+ }
+ if (!complained && expr != error_mark_node)
+ {
+ range_label_for_type_mismatch label (TREE_TYPE (expr), totype);
+ gcc_rich_location richloc (loc, &label);
+ complained = permerror (&richloc,
+ "invalid conversion from %qH to %qI",
+ TREE_TYPE (expr), totype);
+ }
+ if (complained)
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+
+ return cp_convert (totype, expr, complain);
+ }
+
+ if (issue_conversion_warnings && (complain & tf_warning))
+ conversion_null_warnings (totype, expr, fn, argnum);
+
+ switch (convs->kind)
+ {
+ case ck_user:
+ {
+ struct z_candidate *cand = convs->cand;
+
+ if (cand == NULL)
+ /* We chose the surrogate function from add_conv_candidate, now we
+ actually need to build the conversion. */
+ cand = build_user_type_conversion_1 (totype, expr,
+ LOOKUP_NO_CONVERSION, complain);
+
+ tree convfn = cand->fn;
+
+ /* When converting from an init list we consider explicit
+ constructors, but actually trying to call one is an error. */
+ if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
+ && BRACE_ENCLOSED_INITIALIZER_P (expr)
+ /* Unless this is for direct-list-initialization. */
+ && (!CONSTRUCTOR_IS_DIRECT_INIT (expr) || convs->need_temporary_p)
+ /* And in C++98 a default constructor can't be explicit. */
+ && cxx_dialect >= cxx11)
+ {
+ if (!(complain & tf_error))
+ return error_mark_node;
+ location_t loc = location_of (expr);
+ if (CONSTRUCTOR_NELTS (expr) == 0
+ && FUNCTION_FIRST_USER_PARMTYPE (convfn) != void_list_node)
+ {
+ auto_diagnostic_group d;
+ if (pedwarn (loc, 0, "converting to %qT from initializer list "
+ "would use explicit constructor %qD",
+ totype, convfn))
+ inform (loc, "in C++11 and above a default constructor "
+ "can be explicit");
+ }
+ else
+ error ("converting to %qT from initializer list would use "
+ "explicit constructor %qD", totype, convfn);
+ }
+
+ /* If we're initializing from {}, it's value-initialization. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && CONSTRUCTOR_NELTS (expr) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype)
+ && !processing_template_decl)
+ {
+ bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
+ if (abstract_virtuals_error_sfinae (NULL_TREE, totype, complain))
+ return error_mark_node;
+ expr = build_value_init (totype, complain);
+ expr = get_target_expr_sfinae (expr, complain);
+ if (expr != error_mark_node)
+ {
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ TARGET_EXPR_DIRECT_INIT_P (expr) = direct;
+ }
+ return expr;
+ }
+
+ /* We don't know here whether EXPR is being used as an lvalue or
+ rvalue, but we know it's read. */
+ mark_exp_read (expr);
+
+ /* Pass LOOKUP_NO_CONVERSION so rvalue/base handling knows not to allow
+ any more UDCs. */
+ expr = build_over_call (cand, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION,
+ complain);
+
+ /* If this is a constructor or a function returning an aggr type,
+ we need to build up a TARGET_EXPR. */
+ if (DECL_CONSTRUCTOR_P (convfn))
+ {
+ expr = build_cplus_new (totype, expr, complain);
+
+ /* Remember that this was list-initialization. */
+ if (convs->check_narrowing && expr != error_mark_node)
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ }
+
+ return expr;
+ }
+ case ck_identity:
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+ {
+ int nelts = CONSTRUCTOR_NELTS (expr);
+ if (nelts == 0)
+ expr = build_value_init (totype, complain);
+ else if (nelts == 1)
+ expr = CONSTRUCTOR_ELT (expr, 0)->value;
+ else
+ gcc_unreachable ();
+ }
+ expr = mark_use (expr, /*rvalue_p=*/!convs->rvaluedness_matches_p,
+ /*read_p=*/true, UNKNOWN_LOCATION,
+ /*reject_builtin=*/true);
+
+ if (type_unknown_p (expr))
+ expr = instantiate_type (totype, expr, complain);
+ if (expr == null_node
+ && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype))
+ /* If __null has been converted to an integer type, we do not want to
+ continue to warn about uses of EXPR as an integer, rather than as a
+ pointer. */
+ expr = build_int_cst (totype, 0);
+ return expr;
+ case ck_ambig:
+ /* We leave bad_p off ck_ambig because overload resolution considers
+ it valid, it just fails when we try to perform it. So we need to
+ check complain here, too. */
+ if (complain & tf_error)
+ {
+ /* Call build_user_type_conversion again for the error. */
+ int flags = (convs->need_temporary_p
+ ? LOOKUP_IMPLICIT : LOOKUP_NORMAL);
+ build_user_type_conversion (totype, convs->u.expr, flags, complain);
+ gcc_assert (seen_error ());
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+ }
+ return error_mark_node;
+
+ case ck_list:
+ {
+ /* Conversion to std::initializer_list<T>. */
+ tree elttype = TREE_VEC_ELT (CLASSTYPE_TI_ARGS (totype), 0);
+ unsigned len = CONSTRUCTOR_NELTS (expr);
+ tree array;
+
+ if (len)
+ {
+ tree val; unsigned ix;
+
+ tree new_ctor = build_constructor (init_list_type_node, NULL);
+
+ /* Convert all the elements. */
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (expr), ix, val)
+ {
+ tree sub = convert_like (convs->u.list[ix], val, fn,
+ argnum, false, false, complain);
+ if (sub == error_mark_node)
+ return sub;
+ if (!BRACE_ENCLOSED_INITIALIZER_P (val)
+ && !check_narrowing (TREE_TYPE (sub), val, complain))
+ return error_mark_node;
+ CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor),
+ NULL_TREE, sub);
+ if (!TREE_CONSTANT (sub))
+ TREE_CONSTANT (new_ctor) = false;
+ }
+ /* Build up the array. */
+ elttype = cp_build_qualified_type
+ (elttype, cp_type_quals (elttype) | TYPE_QUAL_CONST);
+ array = build_array_of_n_type (elttype, len);
+ array = finish_compound_literal (array, new_ctor, complain);
+ /* Take the address explicitly rather than via decay_conversion
+ to avoid the error about taking the address of a temporary. */
+ array = cp_build_addr_expr (array, complain);
+ }
+ else
+ array = nullptr_node;
+
+ array = cp_convert (build_pointer_type (elttype), array, complain);
+ if (array == error_mark_node)
+ return error_mark_node;
+
+ /* Build up the initializer_list object. Note: fail gracefully
+ if the object cannot be completed because, for example, no
+ definition is provided (c++/80956). */
+ totype = complete_type_or_maybe_complain (totype, NULL_TREE, complain);
+ if (!totype)
+ return error_mark_node;
+ tree field = next_initializable_field (TYPE_FIELDS (totype));
+ vec<constructor_elt, va_gc> *vec = NULL;
+ CONSTRUCTOR_APPEND_ELT (vec, field, array);
+ field = next_initializable_field (DECL_CHAIN (field));
+ CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
+ tree new_ctor = build_constructor (totype, vec);
+ return get_target_expr_sfinae (new_ctor, complain);
+ }
+
+ case ck_aggr:
+ if (TREE_CODE (totype) == COMPLEX_TYPE)
+ {
+ tree real = CONSTRUCTOR_ELT (expr, 0)->value;
+ tree imag = CONSTRUCTOR_ELT (expr, 1)->value;
+ real = perform_implicit_conversion (TREE_TYPE (totype),
+ real, complain);
+ imag = perform_implicit_conversion (TREE_TYPE (totype),
+ imag, complain);
+ expr = build2 (COMPLEX_EXPR, totype, real, imag);
+ return expr;
+ }
+ expr = reshape_init (totype, expr, complain);
+ expr = get_target_expr_sfinae (digest_init (totype, expr, complain),
+ complain);
+ if (expr != error_mark_node)
+ TARGET_EXPR_LIST_INIT_P (expr) = true;
+ return expr;
+
+ default:
+ break;
+ };
+
+ expr = convert_like (next_conversion (convs), expr, fn, argnum,
+ convs->kind == ck_ref_bind
+ ? issue_conversion_warnings : false,
+ c_cast_p, complain & ~tf_no_cleanup);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ switch (convs->kind)
+ {
+ case ck_rvalue:
+ expr = decay_conversion (expr, complain);
+ if (expr == error_mark_node)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ maybe_print_user_conv_context (convs);
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+ }
+ return error_mark_node;
+ }
+
+ if (! MAYBE_CLASS_TYPE_P (totype))
+ return expr;
+
+ /* Don't introduce copies when passing arguments along to the inherited
+ constructor. */
+ if (current_function_decl
+ && flag_new_inheriting_ctors
+ && DECL_INHERITED_CTOR (current_function_decl))
+ return expr;
+
+ if (TREE_CODE (expr) == TARGET_EXPR
+ && TARGET_EXPR_LIST_INIT_P (expr))
+ /* Copy-list-initialization doesn't actually involve a copy. */
+ return expr;
+
+ /* Fall through. */
+ case ck_base:
+ if (convs->kind == ck_base && !convs->need_temporary_p)
+ {
+ /* We are going to bind a reference directly to a base-class
+ subobject of EXPR. */
+ /* Build an expression for `*((base*) &expr)'. */
+ expr = convert_to_base (expr, totype,
+ !c_cast_p, /*nonnull=*/true, complain);
+ return expr;
+ }
+
+ /* Copy-initialization where the cv-unqualified version of the source
+ type is the same class as, or a derived class of, the class of the
+ destination [is treated as direct-initialization]. [dcl.init] */
+ flags = LOOKUP_NORMAL;
+ /* This conversion is being done in the context of a user-defined
+ conversion (i.e. the second step of copy-initialization), so
+ don't allow any more. */
+ if (convs->user_conv_p)
+ flags |= LOOKUP_NO_CONVERSION;
+ /* We might be performing a conversion of the argument
+ to the user-defined conversion, i.e., not a conversion of the
+ result of the user-defined conversion. In which case we skip
+ explicit constructors. */
+ if (convs->copy_init_p)
+ flags |= LOOKUP_ONLYCONVERTING;
+ if (convs->rvaluedness_matches_p)
+ /* standard_conversion got LOOKUP_PREFER_RVALUE. */
+ flags |= LOOKUP_PREFER_RVALUE;
+ expr = build_temp (expr, totype, flags, &diag_kind, complain);
+ if (diag_kind && complain)
+ {
+ auto_diagnostic_group d;
+ maybe_print_user_conv_context (convs);
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+ }
+
+ return build_cplus_new (totype, expr, complain);
+
+ case ck_ref_bind:
+ {
+ tree ref_type = totype;
+
+ /* direct_reference_binding might have inserted a ck_qual under
+ this ck_ref_bind for the benefit of conversion sequence ranking.
+ Ignore the conversion; we'll create our own below. */
+ if (next_conversion (convs)->kind == ck_qual
+ && !convs->need_temporary_p)
+ {
+ gcc_assert (same_type_p (TREE_TYPE (expr),
+ next_conversion (convs)->type));
+ /* Strip the cast created by the ck_qual; cp_build_addr_expr
+ below expects an lvalue. */
+ STRIP_NOPS (expr);
+ }
+
+ if (convs->bad_p && !next_conversion (convs)->bad_p)
+ {
+ tree extype = TREE_TYPE (expr);
+ auto_diagnostic_group d;
+ if (TYPE_REF_IS_RVALUE (ref_type)
+ && lvalue_p (expr))
+ error_at (loc, "cannot bind rvalue reference of type %qH to "
+ "lvalue of type %qI", totype, extype);
+ else if (!TYPE_REF_IS_RVALUE (ref_type) && !lvalue_p (expr)
+ && !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
+ {
+ conversion *next = next_conversion (convs);
+ if (next->kind == ck_std)
+ {
+ next = next_conversion (next);
+ error_at (loc, "cannot bind non-const lvalue reference of "
+ "type %qH to a value of type %qI",
+ totype, next->type);
+ }
+ else if (!CP_TYPE_CONST_P (TREE_TYPE (ref_type)))
+ error_at (loc, "cannot bind non-const lvalue reference of "
+ "type %qH to an rvalue of type %qI", totype, extype);
+ else // extype is volatile
+ error_at (loc, "cannot bind lvalue reference of type "
+ "%qH to an rvalue of type %qI", totype,
+ extype);
+ }
+ else if (!reference_compatible_p (TREE_TYPE (totype), extype))
+ {
+ /* If we're converting from T[] to T[N], don't talk
+ about discarding qualifiers. (Converting from T[N] to
+ T[] is allowed by P0388R4.) */
+ if (TREE_CODE (extype) == ARRAY_TYPE
+ && TYPE_DOMAIN (extype) == NULL_TREE
+ && TREE_CODE (TREE_TYPE (totype)) == ARRAY_TYPE
+ && TYPE_DOMAIN (TREE_TYPE (totype)) != NULL_TREE)
+ error_at (loc, "cannot bind reference of type %qH to %qI "
+ "due to different array bounds", totype, extype);
+ else
+ error_at (loc, "binding reference of type %qH to %qI "
+ "discards qualifiers", totype, extype);
+ }
+ else
+ gcc_unreachable ();
+ maybe_print_user_conv_context (convs);
+ maybe_inform_about_fndecl_for_bogus_argument_init (fn, argnum);
+
+ return error_mark_node;
+ }
+ else if (complain & tf_warning)
+ maybe_warn_array_conv (loc, convs, expr);
+
+ /* If necessary, create a temporary.
+
+ VA_ARG_EXPR and CONSTRUCTOR expressions are special cases
+ that need temporaries, even when their types are reference
+ compatible with the type of reference being bound, so the
+ upcoming call to cp_build_addr_expr doesn't fail. */
+ if (convs->need_temporary_p
+ || TREE_CODE (expr) == CONSTRUCTOR
+ || TREE_CODE (expr) == VA_ARG_EXPR)
+ {
+ /* Otherwise, a temporary of type "cv1 T1" is created and
+ initialized from the initializer expression using the rules
+ for a non-reference copy-initialization (8.5). */
+
+ tree type = TREE_TYPE (ref_type);
+ cp_lvalue_kind lvalue = lvalue_kind (expr);
+
+ gcc_assert (similar_type_p (type, next_conversion (convs)->type));
+ if (!CP_TYPE_CONST_NON_VOLATILE_P (type)
+ && !TYPE_REF_IS_RVALUE (ref_type))
+ {
+ /* If the reference is volatile or non-const, we
+ cannot create a temporary. */
+ if (complain & tf_error)
+ {
+ if (lvalue & clk_bitfield)
+ error_at (loc, "cannot bind bit-field %qE to %qT",
+ expr, ref_type);
+ else if (lvalue & clk_packed)
+ error_at (loc, "cannot bind packed field %qE to %qT",
+ expr, ref_type);
+ else
+ error_at (loc, "cannot bind rvalue %qE to %qT",
+ expr, ref_type);
+ }
+ return error_mark_node;
+ }
+ /* If the source is a packed field, and we must use a copy
+ constructor, then building the target expr will require
+ binding the field to the reference parameter to the
+ copy constructor, and we'll end up with an infinite
+ loop. If we can use a bitwise copy, then we'll be
+ OK. */
+ if ((lvalue & clk_packed)
+ && CLASS_TYPE_P (type)
+ && type_has_nontrivial_copy_init (type))
+ {
+ error_at (loc, "cannot bind packed field %qE to %qT",
+ expr, ref_type);
+ return error_mark_node;
+ }
+ if (lvalue & clk_bitfield)
+ {
+ expr = convert_bitfield_to_declared_type (expr);
+ expr = fold_convert (type, expr);
+ }
+
+ /* Creating &TARGET_EXPR<> in a template would break when
+ tsubsting the expression, so use an IMPLICIT_CONV_EXPR
+ instead. This can happen even when there's no class
+ involved, e.g., when converting an integer to a reference
+ type. */
+ if (processing_template_decl)
+ return build1 (IMPLICIT_CONV_EXPR, totype, expr);
+ expr = build_target_expr_with_type (expr, type, complain);
+ }
+
+ /* Take the address of the thing to which we will bind the
+ reference. */
+ expr = cp_build_addr_expr (expr, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+
+ /* Convert it to a pointer to the type referred to by the
+ reference. This will adjust the pointer if a derived to
+ base conversion is being performed. */
+ expr = cp_convert (build_pointer_type (TREE_TYPE (ref_type)),
+ expr, complain);
+ /* Convert the pointer to the desired reference type. */
+ return build_nop (ref_type, expr);
+ }
+
+ case ck_lvalue:
+ return decay_conversion (expr, complain);
+
+ case ck_fnptr:
+ /* ??? Should the address of a transaction-safe pointer point to the TM
+ clone, and this conversion look up the primary function? */
+ return build_nop (totype, expr);
+
+ case ck_qual:
+ /* Warn about deprecated conversion if appropriate. */
+ if (complain & tf_warning)
+ {
+ string_conv_p (totype, expr, 1);
+ maybe_warn_array_conv (loc, convs, expr);
+ }
+ break;
+
+ case ck_ptr:
+ if (convs->base_p)
+ expr = convert_to_base (expr, totype, !c_cast_p,
+ /*nonnull=*/false, complain);
+ return build_nop (totype, expr);
+
+ case ck_pmem:
+ return convert_ptrmem (totype, expr, /*allow_inverse_p=*/false,
+ c_cast_p, complain);
+
+ default:
+ break;
+ }
+
+ if (convs->check_narrowing
+ && !check_narrowing (totype, expr, complain,
+ convs->check_narrowing_const_only))
+ return error_mark_node;
+
+ warning_sentinel w (warn_zero_as_null_pointer_constant);
+ if (issue_conversion_warnings)
+ expr = cp_convert_and_check (totype, expr, complain);
+ else
+ expr = cp_convert (totype, expr, complain);
+
+ return expr;
+}
+
+/* Return true if converting FROM to TO is unsafe in a template. */
+
+static bool
+conv_unsafe_in_template_p (tree to, tree from)
+{
+ /* Converting classes involves TARGET_EXPR. */
+ if (CLASS_TYPE_P (to) || CLASS_TYPE_P (from))
+ return true;
+
+ /* Converting real to integer produces FIX_TRUNC_EXPR which tsubst
+ doesn't handle. */
+ if (SCALAR_FLOAT_TYPE_P (from) && INTEGRAL_OR_ENUMERATION_TYPE_P (to))
+ return true;
+
+ /* Converting integer to real isn't a trivial conversion, either. */
+ if (INTEGRAL_OR_ENUMERATION_TYPE_P (from) && SCALAR_FLOAT_TYPE_P (to))
+ return true;
+
+ return false;
+}
+
+/* Wrapper for convert_like_internal that handles creating
+ IMPLICIT_CONV_EXPR. */
+
+static tree
+convert_like (conversion *convs, tree expr, tree fn, int argnum,
+ bool issue_conversion_warnings, bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ /* Creating &TARGET_EXPR<> in a template breaks when substituting,
+ and creating a CALL_EXPR in a template breaks in finish_call_expr
+ so use an IMPLICIT_CONV_EXPR for this conversion. We would have
+ created such codes e.g. when calling a user-defined conversion
+ function. */
+ tree conv_expr = NULL_TREE;
+ if (processing_template_decl
+ && convs->kind != ck_identity
+ && conv_unsafe_in_template_p (convs->type, TREE_TYPE (expr)))
+ {
+ conv_expr = build1 (IMPLICIT_CONV_EXPR, convs->type, expr);
+ if (convs->kind != ck_ref_bind)
+ conv_expr = convert_from_reference (conv_expr);
+ if (!convs->bad_p)
+ return conv_expr;
+ /* Do the normal processing to give the bad_p errors. But we still
+ need to return the IMPLICIT_CONV_EXPR, unless we're returning
+ error_mark_node. */
+ }
+ expr = convert_like_internal (convs, expr, fn, argnum,
+ issue_conversion_warnings, c_cast_p, complain);
+ if (expr == error_mark_node)
+ return error_mark_node;
+ return conv_expr ? conv_expr : expr;
+}
+
+/* Convenience wrapper for convert_like. */
+
+static inline tree
+convert_like (conversion *convs, tree expr, tsubst_flags_t complain)
+{
+ return convert_like (convs, expr, NULL_TREE, 0,
+ /*issue_conversion_warnings=*/true,
+ /*c_cast_p=*/false, complain);
+}
+
+/* Convenience wrapper for convert_like. */
+
+static inline tree
+convert_like_with_context (conversion *convs, tree expr, tree fn, int argnum,
+ tsubst_flags_t complain)
+{
+ return convert_like (convs, expr, fn, argnum,
+ /*issue_conversion_warnings=*/true,
+ /*c_cast_p=*/false, complain);
+}
+
+/* ARG is being passed to a varargs function. Perform any conversions
+ required. Return the converted value. */
+
+tree
+convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
+{
+ tree arg_type = TREE_TYPE (arg);
+ location_t loc = cp_expr_loc_or_input_loc (arg);
+
+ /* [expr.call]
+
+ If the argument has integral or enumeration type that is subject
+ to the integral promotions (_conv.prom_), or a floating-point
+ type that is subject to the floating-point promotion
+ (_conv.fpprom_), the value of the argument is converted to the
+ promoted type before the call. */
+ if (TREE_CODE (arg_type) == REAL_TYPE
+ && (TYPE_PRECISION (arg_type)
+ < TYPE_PRECISION (double_type_node))
+ && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (arg_type)))
+ {
+ if ((complain & tf_warning)
+ && warn_double_promotion && !c_inhibit_evaluation_warnings)
+ warning_at (loc, OPT_Wdouble_promotion,
+ "implicit conversion from %qH to %qI when passing "
+ "argument to function",
+ arg_type, double_type_node);
+ arg = mark_rvalue_use (arg);
+ arg = convert_to_real_nofold (double_type_node, arg);
+ }
+ else if (NULLPTR_TYPE_P (arg_type))
+ {
+ arg = mark_rvalue_use (arg);
+ if (TREE_SIDE_EFFECTS (arg))
+ {
+ warning_sentinel w(warn_unused_result);
+ arg = cp_build_compound_expr (arg, null_pointer_node, complain);
+ }
+ else
+ arg = null_pointer_node;
+ }
+ else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type))
+ {
+ if (SCOPED_ENUM_P (arg_type))
+ {
+ tree prom = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg,
+ complain);
+ prom = cp_perform_integral_promotions (prom, complain);
+ if (abi_version_crosses (6)
+ && TYPE_MODE (TREE_TYPE (prom)) != TYPE_MODE (arg_type)
+ && (complain & tf_warning))
+ warning_at (loc, OPT_Wabi, "scoped enum %qT passed through %<...%>"
+ " as %qT before %<-fabi-version=6%>, %qT after",
+ arg_type,
+ TREE_TYPE (prom), ENUM_UNDERLYING_TYPE (arg_type));
+ if (!abi_version_at_least (6))
+ arg = prom;
+ }
+ else
+ arg = cp_perform_integral_promotions (arg, complain);
+ }
+ else
+ /* [expr.call]
+
+ The lvalue-to-rvalue, array-to-pointer, and function-to-pointer
+ standard conversions are performed. */
+ arg = decay_conversion (arg, complain);
+
+ arg = require_complete_type_sfinae (arg, complain);
+ arg_type = TREE_TYPE (arg);
+
+ if (arg != error_mark_node
+ /* In a template (or ill-formed code), we can have an incomplete type
+ even after require_complete_type_sfinae, in which case we don't know
+ whether it has trivial copy or not. */
+ && COMPLETE_TYPE_P (arg_type)
+ && !cp_unevaluated_operand)
+ {
+ /* [expr.call] 5.2.2/7:
+ Passing a potentially-evaluated argument of class type (Clause 9)
+ with a non-trivial copy constructor or a non-trivial destructor
+ with no corresponding parameter is conditionally-supported, with
+ implementation-defined semantics.
+
+ We support it as pass-by-invisible-reference, just like a normal
+ value parameter.
+
+ If the call appears in the context of a sizeof expression,
+ it is not potentially-evaluated. */
+ if (type_has_nontrivial_copy_init (arg_type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (arg_type))
+ {
+ arg = force_rvalue (arg, complain);
+ if (complain & tf_warning)
+ warning (OPT_Wconditionally_supported,
+ "passing objects of non-trivially-copyable "
+ "type %q#T through %<...%> is conditionally supported",
+ arg_type);
+ return build1 (ADDR_EXPR, build_reference_type (arg_type), arg);
+ }
+ /* Build up a real lvalue-to-rvalue conversion in case the
+ copy constructor is trivial but not callable. */
+ else if (CLASS_TYPE_P (arg_type))
+ force_rvalue (arg, complain);
+
+ }
+
+ return arg;
+}
+
+/* va_arg (EXPR, TYPE) is a builtin. Make sure it is not abused. */
+
+tree
+build_x_va_arg (location_t loc, tree expr, tree type)
+{
+ if (processing_template_decl)
+ {
+ tree r = build_min (VA_ARG_EXPR, type, expr);
+ SET_EXPR_LOCATION (r, loc);
+ return r;
+ }
+
+ type = complete_type_or_else (type, NULL_TREE);
+
+ if (expr == error_mark_node || !type)
+ return error_mark_node;
+
+ expr = mark_lvalue_use (expr);
+
+ if (TYPE_REF_P (type))
+ {
+ error ("cannot receive reference type %qT through %<...%>", type);
+ return error_mark_node;
+ }
+
+ if (type_has_nontrivial_copy_init (type)
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ {
+ /* conditionally-supported behavior [expr.call] 5.2.2/7. Let's treat
+ it as pass by invisible reference. */
+ warning_at (loc, OPT_Wconditionally_supported,
+ "receiving objects of non-trivially-copyable type %q#T "
+ "through %<...%> is conditionally-supported", type);
+
+ tree ref = cp_build_reference_type (type, false);
+ expr = build_va_arg (loc, expr, ref);
+ return convert_from_reference (expr);
+ }
+
+ tree ret = build_va_arg (loc, expr, type);
+ if (CLASS_TYPE_P (type))
+ /* Wrap the VA_ARG_EXPR in a TARGET_EXPR now so other code doesn't need to
+ know how to handle it. */
+ ret = get_target_expr (ret);
+ return ret;
+}
+
+/* TYPE has been given to va_arg. Apply the default conversions which
+ would have happened when passed via ellipsis. Return the promoted
+ type, or the passed type if there is no change. */
+
+tree
+cxx_type_promotes_to (tree type)
+{
+ tree promote;
+
+ /* Perform the array-to-pointer and function-to-pointer
+ conversions. */
+ type = type_decays_to (type);
+
+ promote = type_promotes_to (type);
+ if (same_type_p (type, promote))
+ promote = type;
+
+ return promote;
+}
+
+/* ARG is a default argument expression being passed to a parameter of
+ the indicated TYPE, which is a parameter to FN. PARMNUM is the
+ zero-based argument number. Do any required conversions. Return
+ the converted value. */
+
+static GTY(()) vec<tree, va_gc> *default_arg_context;
+void
+push_defarg_context (tree fn)
+{ vec_safe_push (default_arg_context, fn); }
+
+void
+pop_defarg_context (void)
+{ default_arg_context->pop (); }
+
+tree
+convert_default_arg (tree type, tree arg, tree fn, int parmnum,
+ tsubst_flags_t complain)
+{
+ int i;
+ tree t;
+
+ /* See through clones. */
+ fn = DECL_ORIGIN (fn);
+ /* And inheriting ctors. */
+ if (flag_new_inheriting_ctors)
+ fn = strip_inheriting_ctors (fn);
+
+ /* Detect recursion. */
+ FOR_EACH_VEC_SAFE_ELT (default_arg_context, i, t)
+ if (t == fn)
+ {
+ if (complain & tf_error)
+ error ("recursive evaluation of default argument for %q#D", fn);
+ return error_mark_node;
+ }
+
+ /* If the ARG is an unparsed default argument expression, the
+ conversion cannot be performed. */
+ if (TREE_CODE (arg) == DEFERRED_PARSE)
+ {
+ if (complain & tf_error)
+ error ("call to %qD uses the default argument for parameter %P, which "
+ "is not yet defined", fn, parmnum);
+ return error_mark_node;
+ }
+
+ push_defarg_context (fn);
+
+ if (fn && DECL_TEMPLATE_INFO (fn))
+ arg = tsubst_default_argument (fn, parmnum, type, arg, complain);
+
+ /* Due to:
+
+ [dcl.fct.default]
+
+ The names in the expression are bound, and the semantic
+ constraints are checked, at the point where the default
+ expressions appears.
+
+ we must not perform access checks here. */
+ push_deferring_access_checks (dk_no_check);
+ /* We must make a copy of ARG, in case subsequent processing
+ alters any part of it. */
+ arg = break_out_target_exprs (arg, /*clear location*/true);
+
+ arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
+ ICR_DEFAULT_ARGUMENT, fn, parmnum,
+ complain);
+ arg = convert_for_arg_passing (type, arg, complain);
+ pop_deferring_access_checks();
+
+ pop_defarg_context ();
+
+ return arg;
+}
+
+/* Returns the type which will really be used for passing an argument of
+ type TYPE. */
+
+tree
+type_passed_as (tree type)
+{
+ /* Pass classes with copy ctors by invisible reference. */
+ if (TREE_ADDRESSABLE (type))
+ type = build_reference_type (type);
+ else if (targetm.calls.promote_prototypes (NULL_TREE)
+ && INTEGRAL_TYPE_P (type)
+ && COMPLETE_TYPE_P (type)
+ && tree_int_cst_lt (TYPE_SIZE (type), TYPE_SIZE (integer_type_node)))
+ type = integer_type_node;
+
+ return type;
+}
+
+/* Actually perform the appropriate conversion. */
+
+tree
+convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
+{
+ tree bitfield_type;
+
+ /* If VAL is a bitfield, then -- since it has already been converted
+ to TYPE -- it cannot have a precision greater than TYPE.
+
+ If it has a smaller precision, we must widen it here. For
+ example, passing "int f:3;" to a function expecting an "int" will
+ not result in any conversion before this point.
+
+ If the precision is the same we must not risk widening. For
+ example, the COMPONENT_REF for a 32-bit "long long" bitfield will
+ often have type "int", even though the C++ type for the field is
+ "long long". If the value is being passed to a function
+ expecting an "int", then no conversions will be required. But,
+ if we call convert_bitfield_to_declared_type, the bitfield will
+ be converted to "long long". */
+ bitfield_type = is_bitfield_expr_with_lowered_type (val);
+ if (bitfield_type
+ && TYPE_PRECISION (TREE_TYPE (val)) < TYPE_PRECISION (type))
+ val = convert_to_integer_nofold (TYPE_MAIN_VARIANT (bitfield_type), val);
+
+ if (val == error_mark_node)
+ ;
+ /* Pass classes with copy ctors by invisible reference. */
+ else if (TREE_ADDRESSABLE (type))
+ val = build1 (ADDR_EXPR, build_reference_type (type), val);
+ else if (targetm.calls.promote_prototypes (NULL_TREE)
+ && INTEGRAL_TYPE_P (type)
+ && COMPLETE_TYPE_P (type)
+ && tree_int_cst_lt (TYPE_SIZE (type), TYPE_SIZE (integer_type_node)))
+ val = cp_perform_integral_promotions (val, complain);
+ if (complain & tf_warning)
+ {
+ if (warn_suggest_attribute_format)
+ {
+ tree rhstype = TREE_TYPE (val);
+ const enum tree_code coder = TREE_CODE (rhstype);
+ const enum tree_code codel = TREE_CODE (type);
+ if ((codel == POINTER_TYPE || codel == REFERENCE_TYPE)
+ && coder == codel
+ && check_missing_format_attribute (type, rhstype))
+ warning (OPT_Wsuggest_attribute_format,
+ "argument of function call might be a candidate "
+ "for a format attribute");
+ }
+ maybe_warn_parm_abi (type, cp_expr_loc_or_input_loc (val));
+ }
+
+ if (complain & tf_warning)
+ warn_for_address_or_pointer_of_packed_member (type, val);
+
+ return val;
+}
+
+/* Returns non-zero iff FN is a function with magic varargs, i.e. ones for
+ which just decay_conversion or no conversions at all should be done.
+ This is true for some builtins which don't act like normal functions.
+ Return 2 if no conversions at all should be done, 1 if just
+ decay_conversion. Return 3 for special treatment of the 3rd argument
+ for __builtin_*_overflow_p. */
+
+int
+magic_varargs_p (tree fn)
+{
+ if (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (fn))
+ {
+ case BUILT_IN_CLASSIFY_TYPE:
+ case BUILT_IN_CONSTANT_P:
+ case BUILT_IN_NEXT_ARG:
+ case BUILT_IN_VA_START:
+ return 1;
+
+ case BUILT_IN_ADD_OVERFLOW_P:
+ case BUILT_IN_SUB_OVERFLOW_P:
+ case BUILT_IN_MUL_OVERFLOW_P:
+ return 3;
+
+ default:;
+ return lookup_attribute ("type generic",
+ TYPE_ATTRIBUTES (TREE_TYPE (fn))) != 0;
+ }
+
+ return 0;
+}
+
+/* Returns the decl of the dispatcher function if FN is a function version. */
+
+tree
+get_function_version_dispatcher (tree fn)
+{
+ tree dispatcher_decl = NULL;
+
+ if (DECL_LOCAL_DECL_P (fn))
+ fn = DECL_LOCAL_DECL_ALIAS (fn);
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (fn));
+
+ gcc_assert (targetm.get_function_versions_dispatcher);
+ dispatcher_decl = targetm.get_function_versions_dispatcher (fn);
+
+ if (dispatcher_decl == NULL)
+ {
+ error_at (input_location, "use of multiversioned function "
+ "without a default");
+ return NULL;
+ }
+
+ retrofit_lang_decl (dispatcher_decl);
+ gcc_assert (dispatcher_decl != NULL);
+ return dispatcher_decl;
+}
+
+/* fn is a function version dispatcher that is marked used. Mark all the
+ semantically identical function versions it will dispatch as used. */
+
+void
+mark_versions_used (tree fn)
+{
+ struct cgraph_node *node;
+ struct cgraph_function_version_info *node_v;
+ struct cgraph_function_version_info *it_v;
+
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+
+ node = cgraph_node::get (fn);
+ if (node == NULL)
+ return;
+
+ gcc_assert (node->dispatcher_function);
+
+ node_v = node->function_version ();
+ if (node_v == NULL)
+ return;
+
+ /* All semantically identical versions are chained. Traverse and mark each
+ one of them as used. */
+ it_v = node_v->next;
+ while (it_v != NULL)
+ {
+ mark_used (it_v->this_node->decl);
+ it_v = it_v->next;
+ }
+}
+
+/* Build a call to "the copy constructor" for the type of A, even if it
+ wouldn't be selected by normal overload resolution. Used for
+ diagnostics. */
+
+static tree
+call_copy_ctor (tree a, tsubst_flags_t complain)
+{
+ tree ctype = TYPE_MAIN_VARIANT (TREE_TYPE (a));
+ tree binfo = TYPE_BINFO (ctype);
+ tree copy = get_copy_ctor (ctype, complain);
+ copy = build_baselink (binfo, binfo, copy, NULL_TREE);
+ tree ob = build_dummy_object (ctype);
+ releasing_vec args (make_tree_vector_single (a));
+ tree r = build_new_method_call (ob, copy, &args, NULL_TREE,
+ LOOKUP_NORMAL, NULL, complain);
+ return r;
+}
+
+/* Return the base constructor corresponding to COMPLETE_CTOR or NULL_TREE. */
+
+static tree
+base_ctor_for (tree complete_ctor)
+{
+ tree clone;
+ FOR_EACH_CLONE (clone, DECL_CLONED_FUNCTION (complete_ctor))
+ if (DECL_BASE_CONSTRUCTOR_P (clone))
+ return clone;
+ return NULL_TREE;
+}
+
+/* Try to make EXP suitable to be used as the initializer for a base subobject,
+ and return whether we were successful. EXP must have already been cleared
+ by unsafe_copy_elision_p{,_opt}. */
+
+static bool
+make_base_init_ok (tree exp)
+{
+ if (TREE_CODE (exp) == TARGET_EXPR)
+ exp = TARGET_EXPR_INITIAL (exp);
+ while (TREE_CODE (exp) == COMPOUND_EXPR)
+ exp = TREE_OPERAND (exp, 1);
+ if (TREE_CODE (exp) == COND_EXPR)
+ {
+ bool ret = make_base_init_ok (TREE_OPERAND (exp, 2));
+ if (tree op1 = TREE_OPERAND (exp, 1))
+ {
+ bool r1 = make_base_init_ok (op1);
+ /* If unsafe_copy_elision_p was false, the arms should match. */
+ gcc_assert (r1 == ret);
+ }
+ return ret;
+ }
+ if (TREE_CODE (exp) != AGGR_INIT_EXPR)
+ /* A trivial copy is OK. */
+ return true;
+ if (!AGGR_INIT_VIA_CTOR_P (exp))
+ /* unsafe_copy_elision_p_opt must have said this is OK. */
+ return true;
+ tree fn = cp_get_callee_fndecl_nofold (exp);
+ if (DECL_BASE_CONSTRUCTOR_P (fn))
+ return true;
+ gcc_assert (DECL_COMPLETE_CONSTRUCTOR_P (fn));
+ fn = base_ctor_for (fn);
+ if (!fn || DECL_HAS_VTT_PARM_P (fn))
+ /* The base constructor has more parameters, so we can't just change the
+ call target. It would be possible to splice in the appropriate
+ arguments, but probably not worth the complexity. */
+ return false;
+ AGGR_INIT_EXPR_FN (exp) = build_address (fn);
+ return true;
+}
+
+/* Return 2 if T refers to a base, 1 if a potentially-overlapping field,
+ neither of which can be used for return by invisible reference. We avoid
+ doing C++17 mandatory copy elision for either of these cases.
+
+ This returns non-zero even if the type of T has no tail padding that other
+ data could be allocated into, because that depends on the particular ABI.
+ unsafe_copy_elision_p_opt does consider whether there is padding. */
+
+int
+unsafe_return_slot_p (tree t)
+{
+ /* Check empty bases separately, they don't have fields. */
+ if (is_empty_base_ref (t))
+ return 2;
+
+ STRIP_NOPS (t);
+ if (TREE_CODE (t) == ADDR_EXPR)
+ t = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == COMPONENT_REF)
+ t = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) != FIELD_DECL)
+ return false;
+ if (!CLASS_TYPE_P (TREE_TYPE (t)))
+ /* The middle-end will do the right thing for scalar types. */
+ return false;
+ if (DECL_FIELD_IS_BASE (t))
+ return 2;
+ if (lookup_attribute ("no_unique_address", DECL_ATTRIBUTES (t)))
+ return 1;
+ return 0;
+}
+
+/* True IFF EXP is a prvalue that represents return by invisible reference. */
+
+static bool
+init_by_return_slot_p (tree exp)
+{
+ /* Copy elision only happens with a TARGET_EXPR. */
+ if (TREE_CODE (exp) != TARGET_EXPR)
+ return false;
+ tree init = TARGET_EXPR_INITIAL (exp);
+ /* build_compound_expr pushes COMPOUND_EXPR inside TARGET_EXPR. */
+ while (TREE_CODE (init) == COMPOUND_EXPR)
+ init = TREE_OPERAND (init, 1);
+ if (TREE_CODE (init) == COND_EXPR)
+ {
+ /* We'll end up copying from each of the arms of the COND_EXPR directly
+ into the target, so look at them. */
+ if (tree op = TREE_OPERAND (init, 1))
+ if (init_by_return_slot_p (op))
+ return true;
+ return init_by_return_slot_p (TREE_OPERAND (init, 2));
+ }
+ return (TREE_CODE (init) == AGGR_INIT_EXPR
+ && !AGGR_INIT_VIA_CTOR_P (init));
+}
+
+/* We can't elide a copy from a function returning by value to a
+ potentially-overlapping subobject, as the callee might clobber tail padding.
+ Return true iff this could be that case.
+
+ Places that use this function (or _opt) to decide to elide a copy should
+ probably use make_safe_copy_elision instead. */
+
+static bool
+unsafe_copy_elision_p (tree target, tree exp)
+{
+ return unsafe_return_slot_p (target) && init_by_return_slot_p (exp);
+}
+
+/* As above, but for optimization allow more cases that are actually safe. */
+
+static bool
+unsafe_copy_elision_p_opt (tree target, tree exp)
+{
+ tree type = TYPE_MAIN_VARIANT (TREE_TYPE (exp));
+ /* It's safe to elide the copy for a class with no tail padding. */
+ if (!is_empty_class (type)
+ && tree_int_cst_equal (TYPE_SIZE (type), CLASSTYPE_SIZE (type)))
+ return false;
+ return unsafe_copy_elision_p (target, exp);
+}
+
+/* Try to make EXP suitable to be used as the initializer for TARGET,
+ and return whether we were successful. */
+
+bool
+make_safe_copy_elision (tree target, tree exp)
+{
+ int uns = unsafe_return_slot_p (target);
+ if (!uns)
+ return true;
+ if (init_by_return_slot_p (exp))
+ return false;
+ if (uns == 1)
+ return true;
+ return make_base_init_ok (exp);
+}
+
+/* True IFF the result of the conversion C is a prvalue. */
+
+static bool
+conv_is_prvalue (conversion *c)
+{
+ if (c->kind == ck_rvalue)
+ return true;
+ if (c->kind == ck_base && c->need_temporary_p)
+ return true;
+ if (c->kind == ck_user && !TYPE_REF_P (c->type))
+ return true;
+ if (c->kind == ck_identity && c->u.expr
+ && TREE_CODE (c->u.expr) == TARGET_EXPR)
+ return true;
+
+ return false;
+}
+
+/* True iff C is a conversion that binds a reference to a prvalue. */
+
+static bool
+conv_binds_ref_to_prvalue (conversion *c)
+{
+ if (c->kind != ck_ref_bind)
+ return false;
+ if (c->need_temporary_p)
+ return true;
+
+ return conv_is_prvalue (next_conversion (c));
+}
+
+/* True iff converting EXPR to a reference type TYPE does not involve
+ creating a temporary. */
+
+bool
+ref_conv_binds_directly_p (tree type, tree expr)
+{
+ gcc_assert (TYPE_REF_P (type));
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ void *p = conversion_obstack_alloc (0);
+
+ conversion *conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
+ LOOKUP_IMPLICIT, tf_none);
+ bool ret = conv && !conv->bad_p && !conv_binds_ref_to_prvalue (conv);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return ret;
+}
+
+/* Call the trivial destructor for INSTANCE, which can be either an lvalue of
+ class type or a pointer to class type. If NO_PTR_DEREF is true and
+ INSTANCE has pointer type, clobber the pointer rather than what it points
+ to. */
+
+tree
+build_trivial_dtor_call (tree instance, bool no_ptr_deref)
+{
+ gcc_assert (!is_dummy_object (instance));
+
+ if (!flag_lifetime_dse)
+ {
+ no_clobber:
+ return fold_convert (void_type_node, instance);
+ }
+
+ if (INDIRECT_TYPE_P (TREE_TYPE (instance))
+ && (!no_ptr_deref || TYPE_REF_P (TREE_TYPE (instance))))
+ {
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (instance))))
+ goto no_clobber;
+ instance = cp_build_fold_indirect_ref (instance);
+ }
+
+ /* A trivial destructor should still clobber the object. */
+ tree clobber = build_clobber (TREE_TYPE (instance));
+ return build2 (MODIFY_EXPR, void_type_node,
+ instance, clobber);
+}
+
+/* Return true if in an immediate function context, or an unevaluated operand,
+ or a subexpression of an immediate invocation. */
+
+bool
+in_immediate_context ()
+{
+ return (cp_unevaluated_operand != 0
+ || (current_function_decl != NULL_TREE
+ && DECL_IMMEDIATE_FUNCTION_P (current_function_decl))
+ || (current_binding_level->kind == sk_function_parms
+ && current_binding_level->immediate_fn_ctx_p)
+ || in_consteval_if_p);
+}
+
+/* Return true if a call to FN with number of arguments NARGS
+ is an immediate invocation. */
+
+static bool
+immediate_invocation_p (tree fn, int nargs)
+{
+ return (TREE_CODE (fn) == FUNCTION_DECL
+ && DECL_IMMEDIATE_FUNCTION_P (fn)
+ && !in_immediate_context ()
+ /* As an exception, we defer std::source_location::current ()
+ invocations until genericization because LWG3396 mandates
+ special behavior for it. */
+ && (nargs > 1 || !source_location_current_p (fn)));
+}
+
+/* temp_override for in_consteval_if_p, which can't use make_temp_override
+ because it is a bitfield. */
+
+struct in_consteval_if_p_temp_override {
+ bool save_in_consteval_if_p;
+ in_consteval_if_p_temp_override ()
+ : save_in_consteval_if_p (in_consteval_if_p) {}
+ void reset () { in_consteval_if_p = save_in_consteval_if_p; }
+ ~in_consteval_if_p_temp_override ()
+ { reset (); }
+};
+
+/* Subroutine of the various build_*_call functions. Overload resolution
+ has chosen a winning candidate CAND; build up a CALL_EXPR accordingly.
+ ARGS is a TREE_LIST of the unconverted arguments to the call. FLAGS is a
+ bitmask of various LOOKUP_* flags which apply to the call itself. */
+
+static tree
+build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
+{
+ tree fn = cand->fn;
+ const vec<tree, va_gc> *args = cand->args;
+ tree first_arg = cand->first_arg;
+ conversion **convs = cand->convs;
+ conversion *conv;
+ tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
+ int parmlen;
+ tree val;
+ int i = 0;
+ int j = 0;
+ unsigned int arg_index = 0;
+ int is_method = 0;
+ int nargs;
+ tree *argarray;
+ bool already_used = false;
+
+ /* In a template, there is no need to perform all of the work that
+ is normally done. We are only interested in the type of the call
+ expression, i.e., the return type of the function. Any semantic
+ errors will be deferred until the template is instantiated. */
+ if (processing_template_decl)
+ {
+ tree expr, addr;
+ tree return_type;
+ const tree *argarray;
+ unsigned int nargs;
+
+ if (undeduced_auto_decl (fn))
+ mark_used (fn, complain);
+ else
+ /* Otherwise set TREE_USED for the benefit of -Wunused-function.
+ See PR80598. */
+ TREE_USED (fn) = 1;
+
+ return_type = TREE_TYPE (TREE_TYPE (fn));
+ nargs = vec_safe_length (args);
+ if (first_arg == NULL_TREE)
+ argarray = args->address ();
+ else
+ {
+ tree *alcarray;
+ unsigned int ix;
+ tree arg;
+
+ ++nargs;
+ alcarray = XALLOCAVEC (tree, nargs);
+ alcarray[0] = build_this (first_arg);
+ FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
+ alcarray[ix + 1] = arg;
+ argarray = alcarray;
+ }
+
+ addr = build_addr_func (fn, complain);
+ if (addr == error_mark_node)
+ return error_mark_node;
+ expr = build_call_array_loc (input_location, return_type,
+ addr, nargs, argarray);
+ if (TREE_THIS_VOLATILE (fn) && cfun)
+ current_function_returns_abnormally = 1;
+ if (immediate_invocation_p (fn, nargs))
+ {
+ tree obj_arg = NULL_TREE, exprimm = expr;
+ if (DECL_CONSTRUCTOR_P (fn))
+ obj_arg = first_arg;
+ if (obj_arg
+ && is_dummy_object (obj_arg)
+ && !type_dependent_expression_p (obj_arg))
+ {
+ exprimm = build_cplus_new (DECL_CONTEXT (fn), expr, complain);
+ obj_arg = NULL_TREE;
+ }
+ /* Look through *(const T *)&obj. */
+ else if (obj_arg && TREE_CODE (obj_arg) == INDIRECT_REF)
+ {
+ tree addr = TREE_OPERAND (obj_arg, 0);
+ STRIP_NOPS (addr);
+ if (TREE_CODE (addr) == ADDR_EXPR)
+ {
+ tree typeo = TREE_TYPE (obj_arg);
+ tree typei = TREE_TYPE (TREE_OPERAND (addr, 0));
+ if (same_type_ignoring_top_level_qualifiers_p (typeo, typei))
+ obj_arg = TREE_OPERAND (addr, 0);
+ }
+ }
+ fold_non_dependent_expr (exprimm, complain,
+ /*manifestly_const_eval=*/true,
+ obj_arg);
+ }
+ return convert_from_reference (expr);
+ }
+
+ /* Give any warnings we noticed during overload resolution. */
+ if (cand->warnings && (complain & tf_warning))
+ {
+ struct candidate_warning *w;
+ for (w = cand->warnings; w; w = w->next)
+ joust (cand, w->loser, 1, complain);
+ }
+
+ /* Core issue 2327: P0135 doesn't say how to handle the case where the
+ argument to the copy constructor ends up being a prvalue after
+ conversion. Let's do the normal processing, but pretend we aren't
+ actually using the copy constructor. */
+ bool force_elide = false;
+ if (cxx_dialect >= cxx17
+ && cand->num_convs == 1
+ && DECL_COMPLETE_CONSTRUCTOR_P (fn)
+ && (DECL_COPY_CONSTRUCTOR_P (fn)
+ || DECL_MOVE_CONSTRUCTOR_P (fn))
+ && !unsafe_return_slot_p (first_arg)
+ && conv_binds_ref_to_prvalue (convs[0]))
+ {
+ force_elide = true;
+ goto not_really_used;
+ }
+
+ /* OK, we're actually calling this inherited constructor; set its deletedness
+ appropriately. We can get away with doing this here because calling is
+ the only way to refer to a constructor. */
+ if (DECL_INHERITED_CTOR (fn)
+ && !deduce_inheriting_ctor (fn))
+ {
+ if (complain & tf_error)
+ mark_used (fn);
+ return error_mark_node;
+ }
+
+ /* Make =delete work with SFINAE. */
+ if (DECL_DELETED_FN (fn))
+ {
+ if (complain & tf_error)
+ mark_used (fn);
+ return error_mark_node;
+ }
+
+ if (DECL_FUNCTION_MEMBER_P (fn))
+ {
+ tree access_fn;
+ /* If FN is a template function, two cases must be considered.
+ For example:
+
+ struct A {
+ protected:
+ template <class T> void f();
+ };
+ template <class T> struct B {
+ protected:
+ void g();
+ };
+ struct C : A, B<int> {
+ using A::f; // #1
+ using B<int>::g; // #2
+ };
+
+ In case #1 where `A::f' is a member template, DECL_ACCESS is
+ recorded in the primary template but not in its specialization.
+ We check access of FN using its primary template.
+
+ In case #2, where `B<int>::g' has a DECL_TEMPLATE_INFO simply
+ because it is a member of class template B, DECL_ACCESS is
+ recorded in the specialization `B<int>::g'. We cannot use its
+ primary template because `B<T>::g' and `B<int>::g' may have
+ different access. */
+ if (DECL_TEMPLATE_INFO (fn)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn)))
+ access_fn = DECL_TI_TEMPLATE (fn);
+ else
+ access_fn = fn;
+ if (!perform_or_defer_access_check (cand->access_path, access_fn,
+ fn, complain))
+ return error_mark_node;
+ }
+
+ /* If we're checking for implicit delete, don't bother with argument
+ conversions. */
+ if (flags & LOOKUP_SPECULATIVE)
+ {
+ if (cand->viable == 1)
+ return fn;
+ else if (!(complain & tf_error))
+ /* Reject bad conversions now. */
+ return error_mark_node;
+ /* else continue to get conversion error. */
+ }
+
+ not_really_used:
+
+ /* N3276 magic doesn't apply to nested calls. */
+ tsubst_flags_t decltype_flag = (complain & tf_decltype);
+ complain &= ~tf_decltype;
+ /* No-Cleanup doesn't apply to nested calls either. */
+ tsubst_flags_t no_cleanup_complain = complain;
+ complain &= ~tf_no_cleanup;
+
+ /* Find maximum size of vector to hold converted arguments. */
+ parmlen = list_length (parm);
+ nargs = vec_safe_length (args) + (first_arg != NULL_TREE ? 1 : 0);
+ if (parmlen > nargs)
+ nargs = parmlen;
+ argarray = XALLOCAVEC (tree, nargs);
+
+ in_consteval_if_p_temp_override icip;
+ /* If the call is immediate function invocation, make sure
+ taking address of immediate functions is allowed in its arguments. */
+ if (immediate_invocation_p (STRIP_TEMPLATE (fn), nargs))
+ in_consteval_if_p = true;
+
+ /* The implicit parameters to a constructor are not considered by overload
+ resolution, and must be of the proper type. */
+ if (DECL_CONSTRUCTOR_P (fn))
+ {
+ tree object_arg;
+ if (first_arg != NULL_TREE)
+ {
+ object_arg = first_arg;
+ first_arg = NULL_TREE;
+ }
+ else
+ {
+ object_arg = (*args)[arg_index];
+ ++arg_index;
+ }
+ argarray[j++] = build_this (object_arg);
+ parm = TREE_CHAIN (parm);
+ /* We should never try to call the abstract constructor. */
+ gcc_assert (!DECL_HAS_IN_CHARGE_PARM_P (fn));
+
+ if (DECL_HAS_VTT_PARM_P (fn))
+ {
+ argarray[j++] = (*args)[arg_index];
+ ++arg_index;
+ parm = TREE_CHAIN (parm);
+ }
+
+ if (cxx_dialect < cxx20
+ && (cand->flags & LOOKUP_PREFER_RVALUE))
+ {
+ /* The implicit move specified in 15.8.3/3 fails "...if the type of
+ the first parameter of the selected constructor is not an rvalue
+ reference to the object's type (possibly cv-qualified)...." */
+ gcc_assert (!(complain & tf_error));
+ tree ptype = convs[0]->type;
+ /* Allow calling a by-value converting constructor even though it
+ isn't permitted by the above, because we've allowed it since GCC 5
+ (PR58051) and it's allowed in C++20. But don't call a copy
+ constructor. */
+ if ((TYPE_REF_P (ptype) && !TYPE_REF_IS_RVALUE (ptype))
+ || CONVERSION_RANK (convs[0]) > cr_exact)
+ return error_mark_node;
+ }
+ }
+ /* Bypass access control for 'this' parameter. */
+ else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ {
+ tree arg = build_this (first_arg != NULL_TREE
+ ? first_arg
+ : (*args)[arg_index]);
+ tree argtype = TREE_TYPE (arg);
+
+ if (arg == error_mark_node)
+ return error_mark_node;
+
+ if (convs[i]->bad_p)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ if (permerror (input_location, "passing %qT as %<this%> "
+ "argument discards qualifiers",
+ TREE_TYPE (argtype)))
+ inform (DECL_SOURCE_LOCATION (fn), " in call to %qD", fn);
+ }
+ else
+ return error_mark_node;
+ }
+
+ /* The class where FN is defined. */
+ tree ctx = DECL_CONTEXT (fn);
+
+ /* See if the function member or the whole class type is declared
+ final and the call can be devirtualized. */
+ if (DECL_FINAL_P (fn) || CLASSTYPE_FINAL (ctx))
+ flags |= LOOKUP_NONVIRTUAL;
+
+ /* [class.mfct.non-static]: If a non-static member function of a class
+ X is called for an object that is not of type X, or of a type
+ derived from X, the behavior is undefined.
+
+ So we can assume that anything passed as 'this' is non-null, and
+ optimize accordingly. */
+ /* Check that the base class is accessible. */
+ if (!accessible_base_p (TREE_TYPE (argtype),
+ BINFO_TYPE (cand->conversion_path), true))
+ {
+ if (complain & tf_error)
+ error ("%qT is not an accessible base of %qT",
+ BINFO_TYPE (cand->conversion_path),
+ TREE_TYPE (argtype));
+ else
+ return error_mark_node;
+ }
+ /* If fn was found by a using declaration, the conversion path
+ will be to the derived class, not the base declaring fn. We
+ must convert to the base. */
+ tree base_binfo = cand->conversion_path;
+ if (BINFO_TYPE (base_binfo) != ctx)
+ {
+ base_binfo = lookup_base (base_binfo, ctx, ba_unique, NULL, complain);
+ if (base_binfo == error_mark_node)
+ return error_mark_node;
+ }
+
+ /* If we know the dynamic type of the object, look up the final overrider
+ in the BINFO. */
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
+ && resolves_to_fixed_type_p (arg))
+ {
+ tree ov = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
+
+ /* And unwind base_binfo to match. If we don't find the type we're
+ looking for in BINFO_INHERITANCE_CHAIN, we're looking at diamond
+ inheritance; for now do a normal virtual call in that case. */
+ tree octx = DECL_CONTEXT (ov);
+ tree obinfo = base_binfo;
+ while (obinfo && !SAME_BINFO_TYPE_P (BINFO_TYPE (obinfo), octx))
+ obinfo = BINFO_INHERITANCE_CHAIN (obinfo);
+ if (obinfo)
+ {
+ fn = ov;
+ base_binfo = obinfo;
+ flags |= LOOKUP_NONVIRTUAL;
+ }
+ }
+
+ tree converted_arg = build_base_path (PLUS_EXPR, arg,
+ base_binfo, 1, complain);
+
+ argarray[j++] = converted_arg;
+ parm = TREE_CHAIN (parm);
+ if (first_arg != NULL_TREE)
+ first_arg = NULL_TREE;
+ else
+ ++arg_index;
+ ++i;
+ is_method = 1;
+ }
+
+ gcc_assert (first_arg == NULL_TREE);
+ for (; arg_index < vec_safe_length (args) && parm;
+ parm = TREE_CHAIN (parm), ++arg_index, ++i)
+ {
+ tree type = TREE_VALUE (parm);
+ tree arg = (*args)[arg_index];
+ bool conversion_warning = true;
+
+ conv = convs[i];
+
+ /* If the argument is NULL and used to (implicitly) instantiate a
+ template function (and bind one of the template arguments to
+ the type of 'long int'), we don't want to warn about passing NULL
+ to non-pointer argument.
+ For example, if we have this template function:
+
+ template<typename T> void func(T x) {}
+
+ we want to warn (when -Wconversion is enabled) in this case:
+
+ void foo() {
+ func<int>(NULL);
+ }
+
+ but not in this case:
+
+ void foo() {
+ func(NULL);
+ }
+ */
+ if (null_node_p (arg)
+ && DECL_TEMPLATE_INFO (fn)
+ && cand->template_decl
+ && !cand->explicit_targs)
+ conversion_warning = false;
+
+ /* Set user_conv_p on the argument conversions, so rvalue/base handling
+ knows not to allow any more UDCs. This needs to happen after we
+ process cand->warnings. */
+ if (flags & LOOKUP_NO_CONVERSION)
+ conv->user_conv_p = true;
+
+ tsubst_flags_t arg_complain = complain;
+ if (!conversion_warning)
+ arg_complain &= ~tf_warning;
+
+ val = convert_like_with_context (conv, arg, fn, i - is_method,
+ arg_complain);
+ val = convert_for_arg_passing (type, val, arg_complain);
+
+ if (val == error_mark_node)
+ return error_mark_node;
+ else
+ argarray[j++] = val;
+ }
+
+ /* Default arguments */
+ for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm), i++)
+ {
+ if (TREE_VALUE (parm) == error_mark_node)
+ return error_mark_node;
+ val = convert_default_arg (TREE_VALUE (parm),
+ TREE_PURPOSE (parm),
+ fn, i - is_method,
+ complain);
+ if (val == error_mark_node)
+ return error_mark_node;
+ argarray[j++] = val;
+ }
+
+ /* Ellipsis */
+ int magic = magic_varargs_p (fn);
+ for (; arg_index < vec_safe_length (args); ++arg_index)
+ {
+ tree a = (*args)[arg_index];
+ if ((magic == 3 && arg_index == 2) || magic == 2)
+ {
+ /* Do no conversions for certain magic varargs. */
+ a = mark_type_use (a);
+ if (TREE_CODE (a) == FUNCTION_DECL && reject_gcc_builtin (a))
+ return error_mark_node;
+ }
+ else if (magic != 0)
+ /* For other magic varargs only do decay_conversion. */
+ a = decay_conversion (a, complain);
+ else if (DECL_CONSTRUCTOR_P (fn)
+ && same_type_ignoring_top_level_qualifiers_p (DECL_CONTEXT (fn),
+ TREE_TYPE (a)))
+ {
+ /* Avoid infinite recursion trying to call A(...). */
+ if (complain & tf_error)
+ /* Try to call the actual copy constructor for a good error. */
+ call_copy_ctor (a, complain);
+ return error_mark_node;
+ }
+ else
+ a = convert_arg_to_ellipsis (a, complain);
+ if (a == error_mark_node)
+ return error_mark_node;
+ argarray[j++] = a;
+ }
+
+ gcc_assert (j <= nargs);
+ nargs = j;
+ icip.reset ();
+
+ /* Avoid performing argument transformation if warnings are disabled.
+ When tf_warning is set and at least one of the warnings is active
+ the check_function_arguments function might warn about something. */
+
+ bool warned_p = false;
+ if ((complain & tf_warning)
+ && (warn_nonnull
+ || warn_format
+ || warn_suggest_attribute_format
+ || warn_restrict))
+ {
+ tree *fargs = (!nargs ? argarray
+ : (tree *) alloca (nargs * sizeof (tree)));
+ for (j = 0; j < nargs; j++)
+ {
+ /* For -Wformat undo the implicit passing by hidden reference
+ done by convert_arg_to_ellipsis. */
+ if (TREE_CODE (argarray[j]) == ADDR_EXPR
+ && TYPE_REF_P (TREE_TYPE (argarray[j])))
+ fargs[j] = TREE_OPERAND (argarray[j], 0);
+ else
+ fargs[j] = argarray[j];
+ }
+
+ warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
+ nargs, fargs, NULL);
+ }
+
+ if (DECL_INHERITED_CTOR (fn))
+ {
+ /* Check for passing ellipsis arguments to an inherited constructor. We
+ could handle this by open-coding the inherited constructor rather than
+ defining it, but let's not bother now. */
+ if (!cp_unevaluated_operand
+ && cand->num_convs
+ && cand->convs[cand->num_convs-1]->ellipsis_p)
+ {
+ if (complain & tf_error)
+ {
+ sorry ("passing arguments to ellipsis of inherited constructor "
+ "%qD", cand->fn);
+ inform (DECL_SOURCE_LOCATION (cand->fn), "declared here");
+ }
+ return error_mark_node;
+ }
+
+ /* A base constructor inheriting from a virtual base doesn't get the
+ inherited arguments, just this and __vtt. */
+ if (ctor_omit_inherited_parms (fn))
+ nargs = 2;
+ }
+
+ /* Avoid actually calling copy constructors and copy assignment operators,
+ if possible. */
+
+ if (! flag_elide_constructors && !force_elide)
+ /* Do things the hard way. */;
+ else if (cand->num_convs == 1
+ && (DECL_COPY_CONSTRUCTOR_P (fn)
+ || DECL_MOVE_CONSTRUCTOR_P (fn))
+ /* It's unsafe to elide the constructor when handling
+ a noexcept-expression, it may evaluate to the wrong
+ value (c++/53025). */
+ && (force_elide || cp_noexcept_operand == 0))
+ {
+ tree targ;
+ tree arg = argarray[num_artificial_parms_for (fn)];
+ tree fa = argarray[0];
+ bool trivial = trivial_fn_p (fn);
+
+ /* Pull out the real argument, disregarding const-correctness. */
+ targ = arg;
+ /* Strip the reference binding for the constructor parameter. */
+ if (CONVERT_EXPR_P (targ)
+ && TYPE_REF_P (TREE_TYPE (targ)))
+ targ = TREE_OPERAND (targ, 0);
+ /* But don't strip any other reference bindings; binding a temporary to a
+ reference prevents copy elision. */
+ while ((CONVERT_EXPR_P (targ)
+ && !TYPE_REF_P (TREE_TYPE (targ)))
+ || TREE_CODE (targ) == NON_LVALUE_EXPR)
+ targ = TREE_OPERAND (targ, 0);
+ if (TREE_CODE (targ) == ADDR_EXPR)
+ {
+ targ = TREE_OPERAND (targ, 0);
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (arg)), TREE_TYPE (targ)))
+ targ = NULL_TREE;
+ }
+ else
+ targ = NULL_TREE;
+
+ if (targ)
+ arg = targ;
+ else
+ arg = cp_build_fold_indirect_ref (arg);
+
+ /* In C++17 we shouldn't be copying a TARGET_EXPR except into a
+ potentially-overlapping subobject. */
+ if (CHECKING_P && cxx_dialect >= cxx17)
+ gcc_assert (TREE_CODE (arg) != TARGET_EXPR
+ || force_elide
+ /* It's from binding the ref parm to a packed field. */
+ || convs[0]->need_temporary_p
+ || seen_error ()
+ /* See unsafe_copy_elision_p. */
+ || unsafe_return_slot_p (fa));
+
+ bool unsafe = unsafe_copy_elision_p_opt (fa, arg);
+ bool eliding_temp = (TREE_CODE (arg) == TARGET_EXPR && !unsafe);
+
+ /* [class.copy]: the copy constructor is implicitly defined even if the
+ implementation elided its use. But don't warn about deprecation when
+ eliding a temporary, as then no copy is actually performed. */
+ warning_sentinel s (warn_deprecated_copy, eliding_temp);
+ if (force_elide)
+ /* The language says this isn't called. */;
+ else if (!trivial)
+ {
+ if (!mark_used (fn, complain) && !(complain & tf_error))
+ return error_mark_node;
+ already_used = true;
+ }
+ else
+ cp_handle_deprecated_or_unavailable (fn, complain);
+
+ if (eliding_temp && DECL_BASE_CONSTRUCTOR_P (fn)
+ && !make_base_init_ok (arg))
+ unsafe = true;
+
+ /* If we're creating a temp and we already have one, don't create a
+ new one. If we're not creating a temp but we get one, use
+ INIT_EXPR to collapse the temp into our target. Otherwise, if the
+ ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a
+ temp or an INIT_EXPR otherwise. */
+ if (is_dummy_object (fa))
+ {
+ if (TREE_CODE (arg) == TARGET_EXPR)
+ return arg;
+ else if (trivial)
+ return force_target_expr (DECL_CONTEXT (fn), arg, complain);
+ }
+ else if ((trivial || TREE_CODE (arg) == TARGET_EXPR)
+ && !unsafe)
+ {
+ tree to = cp_build_fold_indirect_ref (fa);
+ val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
+ return val;
+ }
+ }
+ else if (DECL_ASSIGNMENT_OPERATOR_P (fn)
+ && DECL_OVERLOADED_OPERATOR_IS (fn, NOP_EXPR)
+ && trivial_fn_p (fn))
+ {
+ tree to = cp_build_fold_indirect_ref (argarray[0]);
+ tree type = TREE_TYPE (to);
+ tree as_base = CLASSTYPE_AS_BASE (type);
+ tree arg = argarray[1];
+ location_t loc = cp_expr_loc_or_input_loc (arg);
+
+ if (is_really_empty_class (type, /*ignore_vptr*/true))
+ {
+ /* Avoid copying empty classes. */
+ val = build2 (COMPOUND_EXPR, type, arg, to);
+ suppress_warning (val, OPT_Wunused);
+ }
+ else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+ {
+ if (is_std_init_list (type)
+ && conv_binds_ref_to_prvalue (convs[1]))
+ warning_at (loc, OPT_Winit_list_lifetime,
+ "assignment from temporary %<initializer_list%> does "
+ "not extend the lifetime of the underlying array");
+ arg = cp_build_fold_indirect_ref (arg);
+ val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
+ }
+ else
+ {
+ /* We must only copy the non-tail padding parts. */
+ tree arg0, arg2, t;
+ tree array_type, alias_set;
+
+ arg2 = TYPE_SIZE_UNIT (as_base);
+ to = cp_stabilize_reference (to);
+ arg0 = cp_build_addr_expr (to, complain);
+
+ array_type = build_array_type (unsigned_char_type_node,
+ build_index_type
+ (size_binop (MINUS_EXPR,
+ arg2, size_int (1))));
+ alias_set = build_int_cst (build_pointer_type (type), 0);
+ t = build2 (MODIFY_EXPR, void_type_node,
+ build2 (MEM_REF, array_type, arg0, alias_set),
+ build2 (MEM_REF, array_type, arg, alias_set));
+ val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to);
+ suppress_warning (val, OPT_Wunused);
+ }
+
+ cp_handle_deprecated_or_unavailable (fn, complain);
+
+ return val;
+ }
+ else if (trivial_fn_p (fn))
+ {
+ if (DECL_DESTRUCTOR_P (fn))
+ return build_trivial_dtor_call (argarray[0]);
+ else if (default_ctor_p (fn))
+ {
+ if (is_dummy_object (argarray[0]))
+ return force_target_expr (DECL_CONTEXT (fn), void_node,
+ no_cleanup_complain);
+ else
+ return cp_build_fold_indirect_ref (argarray[0]);
+ }
+ }
+
+ gcc_assert (!force_elide);
+
+ if (!already_used
+ && !mark_used (fn, complain))
+ return error_mark_node;
+
+ /* Warn if the built-in writes to an object of a non-trivial type. */
+ if (warn_class_memaccess
+ && vec_safe_length (args) >= 2
+ && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
+ maybe_warn_class_memaccess (input_location, fn, args);
+
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
+ {
+ tree t;
+ tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])),
+ DECL_CONTEXT (fn),
+ ba_any, NULL, complain);
+ gcc_assert (binfo && binfo != error_mark_node);
+
+ argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1,
+ complain);
+ if (TREE_SIDE_EFFECTS (argarray[0]))
+ argarray[0] = save_expr (argarray[0]);
+ t = build_pointer_type (TREE_TYPE (fn));
+ fn = build_vfn_ref (argarray[0], DECL_VINDEX (fn));
+ TREE_TYPE (fn) = t;
+ }
+ else
+ {
+ /* If FN is marked deprecated, then we've already issued a deprecated-use
+ warning from mark_used above, so avoid redundantly issuing another one
+ from build_addr_func. */
+ warning_sentinel w (warn_deprecated_decl);
+
+ fn = build_addr_func (fn, complain);
+ if (fn == error_mark_node)
+ return error_mark_node;
+ }
+
+ tree call = build_cxx_call (fn, nargs, argarray, complain|decltype_flag);
+ if (call == error_mark_node)
+ return call;
+ if (cand->flags & LOOKUP_LIST_INIT_CTOR)
+ {
+ tree c = extract_call_expr (call);
+ /* build_new_op will clear this when appropriate. */
+ CALL_EXPR_ORDERED_ARGS (c) = true;
+ }
+ if (warned_p)
+ {
+ tree c = extract_call_expr (call);
+ if (TREE_CODE (c) == CALL_EXPR)
+ suppress_warning (c /* Suppress all warnings. */);
+ }
+ if (TREE_CODE (fn) == ADDR_EXPR)
+ {
+ tree fndecl = STRIP_TEMPLATE (TREE_OPERAND (fn, 0));
+ if (immediate_invocation_p (fndecl, nargs))
+ {
+ tree obj_arg = NULL_TREE;
+ /* Undo convert_from_reference called by build_cxx_call. */
+ if (REFERENCE_REF_P (call))
+ call = TREE_OPERAND (call, 0);
+ if (DECL_CONSTRUCTOR_P (fndecl))
+ obj_arg = cand->first_arg ? cand->first_arg : (*args)[0];
+ if (obj_arg && is_dummy_object (obj_arg))
+ {
+ call = build_cplus_new (DECL_CONTEXT (fndecl), call, complain);
+ obj_arg = NULL_TREE;
+ }
+ /* Look through *(const T *)&obj. */
+ else if (obj_arg && TREE_CODE (obj_arg) == INDIRECT_REF)
+ {
+ tree addr = TREE_OPERAND (obj_arg, 0);
+ STRIP_NOPS (addr);
+ if (TREE_CODE (addr) == ADDR_EXPR)
+ {
+ tree typeo = TREE_TYPE (obj_arg);
+ tree typei = TREE_TYPE (TREE_OPERAND (addr, 0));
+ if (same_type_ignoring_top_level_qualifiers_p (typeo, typei))
+ obj_arg = TREE_OPERAND (addr, 0);
+ }
+ }
+ call = cxx_constant_value (call, obj_arg);
+ if (obj_arg && !error_operand_p (call))
+ call = build2 (INIT_EXPR, void_type_node, obj_arg, call);
+ call = convert_from_reference (call);
+ }
+ }
+ return call;
+}
+
+namespace
+{
+
+/* Return the DECL of the first non-static subobject of class TYPE
+ that satisfies the predicate PRED or null if none can be found. */
+
+template <class Predicate>
+tree
+first_non_static_field (tree type, Predicate pred)
+{
+ if (!type || !CLASS_TYPE_P (type))
+ return NULL_TREE;
+
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ {
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+ if (TREE_STATIC (field))
+ continue;
+ if (pred (field))
+ return field;
+ }
+
+ int i = 0;
+
+ for (tree base_binfo, binfo = TYPE_BINFO (type);
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree base = TREE_TYPE (base_binfo);
+ if (pred (base))
+ return base;
+ if (tree field = first_non_static_field (base, pred))
+ return field;
+ }
+
+ return NULL_TREE;
+}
+
+struct NonPublicField
+{
+ bool operator() (const_tree t) const
+ {
+ return DECL_P (t) && (TREE_PRIVATE (t) || TREE_PROTECTED (t));
+ }
+};
+
+/* Return the DECL of the first non-public subobject of class TYPE
+ or null if none can be found. */
+
+static inline tree
+first_non_public_field (tree type)
+{
+ return first_non_static_field (type, NonPublicField ());
+}
+
+struct NonTrivialField
+{
+ bool operator() (const_tree t) const
+ {
+ return !trivial_type_p (DECL_P (t) ? TREE_TYPE (t) : t);
+ }
+};
+
+/* Return the DECL of the first non-trivial subobject of class TYPE
+ or null if none can be found. */
+
+static inline tree
+first_non_trivial_field (tree type)
+{
+ return first_non_static_field (type, NonTrivialField ());
+}
+
+} /* unnamed namespace */
+
+/* Return true if all copy and move assignment operator overloads for
+ class TYPE are trivial and at least one of them is not deleted and,
+ when ACCESS is set, accessible. Return false otherwise. Set
+ HASASSIGN to true when the TYPE has a (not necessarily trivial)
+ copy or move assignment. */
+
+static bool
+has_trivial_copy_assign_p (tree type, bool access, bool *hasassign)
+{
+ tree fns = get_class_binding (type, assign_op_identifier);
+ bool all_trivial = true;
+
+ /* Iterate over overloads of the assignment operator, checking
+ accessible copy assignments for triviality. */
+
+ for (tree f : ovl_range (fns))
+ {
+ /* Skip operators that aren't copy assignments. */
+ if (!copy_fn_p (f))
+ continue;
+
+ bool accessible = (!access || !(TREE_PRIVATE (f) || TREE_PROTECTED (f))
+ || accessible_p (TYPE_BINFO (type), f, true));
+
+ /* Skip template assignment operators and deleted functions. */
+ if (TREE_CODE (f) != FUNCTION_DECL || DECL_DELETED_FN (f))
+ continue;
+
+ if (accessible)
+ *hasassign = true;
+
+ if (!accessible || !trivial_fn_p (f))
+ all_trivial = false;
+
+ /* Break early when both properties have been determined. */
+ if (*hasassign && !all_trivial)
+ break;
+ }
+
+ /* Return true if they're all trivial and one of the expressions
+ TYPE() = TYPE() or TYPE() = (TYPE&)() is valid. */
+ tree ref = cp_build_reference_type (type, false);
+ return (all_trivial
+ && (is_trivially_xible (MODIFY_EXPR, type, type)
+ || is_trivially_xible (MODIFY_EXPR, type, ref)));
+}
+
+/* Return true if all copy and move ctor overloads for class TYPE are
+ trivial and at least one of them is not deleted and, when ACCESS is
+ set, accessible. Return false otherwise. Set each element of HASCTOR[]
+ to true when the TYPE has a (not necessarily trivial) default and copy
+ (or move) ctor, respectively. */
+
+static bool
+has_trivial_copy_p (tree type, bool access, bool hasctor[2])
+{
+ tree fns = get_class_binding (type, complete_ctor_identifier);
+ bool all_trivial = true;
+
+ for (tree f : ovl_range (fns))
+ {
+ /* Skip template constructors. */
+ if (TREE_CODE (f) != FUNCTION_DECL)
+ continue;
+
+ bool cpy_or_move_ctor_p = copy_fn_p (f);
+
+ /* Skip ctors other than default, copy, and move. */
+ if (!cpy_or_move_ctor_p && !default_ctor_p (f))
+ continue;
+
+ if (DECL_DELETED_FN (f))
+ continue;
+
+ bool accessible = (!access || !(TREE_PRIVATE (f) || TREE_PROTECTED (f))
+ || accessible_p (TYPE_BINFO (type), f, true));
+
+ if (accessible)
+ hasctor[cpy_or_move_ctor_p] = true;
+
+ if (cpy_or_move_ctor_p && (!accessible || !trivial_fn_p (f)))
+ all_trivial = false;
+
+ /* Break early when both properties have been determined. */
+ if (hasctor[0] && hasctor[1] && !all_trivial)
+ break;
+ }
+
+ return all_trivial;
+}
+
+/* Issue a warning on a call to the built-in function FNDECL if it is
+ a raw memory write whose destination is not an object of (something
+ like) trivial or standard layout type with a non-deleted assignment
+ and copy ctor. Detects const correctness violations, corrupting
+ references, virtual table pointers, and bypassing non-trivial
+ assignments. */
+
+static void
+maybe_warn_class_memaccess (location_t loc, tree fndecl,
+ const vec<tree, va_gc> *args)
+{
+ /* Except for bcopy where it's second, the destination pointer is
+ the first argument for all functions handled here. Compute
+ the index of the destination and source arguments. */
+ unsigned dstidx = DECL_FUNCTION_CODE (fndecl) == BUILT_IN_BCOPY;
+ unsigned srcidx = !dstidx;
+
+ tree dest = (*args)[dstidx];
+ if (!TREE_TYPE (dest)
+ || (TREE_CODE (TREE_TYPE (dest)) != ARRAY_TYPE
+ && !INDIRECT_TYPE_P (TREE_TYPE (dest))))
+ return;
+
+ tree srctype = NULL_TREE;
+
+ /* Determine the type of the pointed-to object and whether it's
+ a complete class type. */
+ tree desttype = TREE_TYPE (TREE_TYPE (dest));
+
+ if (!desttype || !COMPLETE_TYPE_P (desttype) || !CLASS_TYPE_P (desttype))
+ return;
+
+ /* Check to see if the raw memory call is made by a non-static member
+ function with THIS as the destination argument for the destination
+ type. If so, and if the class has no non-trivial bases or members,
+ be more permissive. */
+ if (current_function_decl
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (current_function_decl)
+ && is_this_parameter (tree_strip_nop_conversions (dest)))
+ {
+ tree ctx = DECL_CONTEXT (current_function_decl);
+ bool special = same_type_ignoring_top_level_qualifiers_p (ctx, desttype);
+ tree binfo = TYPE_BINFO (ctx);
+
+ if (special
+ && !BINFO_VTABLE (binfo)
+ && !first_non_trivial_field (desttype))
+ return;
+ }
+
+ /* True if the class is trivial. */
+ bool trivial = trivial_type_p (desttype);
+
+ /* Set to true if DESTYPE has an accessible copy assignment. */
+ bool hasassign = false;
+ /* True if all of the class' overloaded copy assignment operators
+ are all trivial (and not deleted) and at least one of them is
+ accessible. */
+ bool trivassign = has_trivial_copy_assign_p (desttype, true, &hasassign);
+
+ /* Set to true if DESTTYPE has an accessible default and copy ctor,
+ respectively. */
+ bool hasctors[2] = { false, false };
+
+ /* True if all of the class' overloaded copy constructors are all
+ trivial (and not deleted) and at least one of them is accessible. */
+ bool trivcopy = has_trivial_copy_p (desttype, true, hasctors);
+
+ /* Set FLD to the first private/protected member of the class. */
+ tree fld = trivial ? first_non_public_field (desttype) : NULL_TREE;
+
+ /* The warning format string. */
+ const char *warnfmt = NULL;
+ /* A suggested alternative to offer instead of the raw memory call.
+ Empty string when none can be come up with. */
+ const char *suggest = "";
+ bool warned = false;
+
+ switch (DECL_FUNCTION_CODE (fndecl))
+ {
+ case BUILT_IN_MEMSET:
+ if (!integer_zerop (maybe_constant_value ((*args)[1])))
+ {
+ /* Diagnose setting non-copy-assignable or non-trivial types,
+ or types with a private member, to (potentially) non-zero
+ bytes. Since the value of the bytes being written is unknown,
+ suggest using assignment instead (if one exists). Also warn
+ for writes into objects for which zero-initialization doesn't
+ mean all bits clear (pointer-to-member data, where null is all
+ bits set). Since the value being written is (most likely)
+ non-zero, simply suggest assignment (but not copy assignment). */
+ suggest = "; use assignment instead";
+ if (!trivassign)
+ warnfmt = G_("%qD writing to an object of type %#qT with "
+ "no trivial copy-assignment");
+ else if (!trivial)
+ warnfmt = G_("%qD writing to an object of non-trivial type %#qT%s");
+ else if (fld)
+ {
+ const char *access = TREE_PRIVATE (fld) ? "private" : "protected";
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ "%qD writing to an object of type %#qT with "
+ "%qs member %qD",
+ fndecl, desttype, access, fld);
+ }
+ else if (!zero_init_p (desttype))
+ warnfmt = G_("%qD writing to an object of type %#qT containing "
+ "a pointer to data member%s");
+
+ break;
+ }
+ /* Fall through. */
+
+ case BUILT_IN_BZERO:
+ /* Similarly to the above, diagnose clearing non-trivial or non-
+ standard layout objects, or objects of types with no assignmenmt.
+ Since the value being written is known to be zero, suggest either
+ copy assignment, copy ctor, or default ctor as an alternative,
+ depending on what's available. */
+
+ if (hasassign && hasctors[0])
+ suggest = G_("; use assignment or value-initialization instead");
+ else if (hasassign)
+ suggest = G_("; use assignment instead");
+ else if (hasctors[0])
+ suggest = G_("; use value-initialization instead");
+
+ if (!trivassign)
+ warnfmt = G_("%qD clearing an object of type %#qT with "
+ "no trivial copy-assignment%s");
+ else if (!trivial)
+ warnfmt = G_("%qD clearing an object of non-trivial type %#qT%s");
+ else if (!zero_init_p (desttype))
+ warnfmt = G_("%qD clearing an object of type %#qT containing "
+ "a pointer-to-member%s");
+ break;
+
+ case BUILT_IN_BCOPY:
+ case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMPCPY:
+ /* Determine the type of the source object. */
+ srctype = TREE_TYPE ((*args)[srcidx]);
+ if (!srctype || !INDIRECT_TYPE_P (srctype))
+ srctype = void_type_node;
+ else
+ srctype = TREE_TYPE (srctype);
+
+ /* Since it's impossible to determine wheter the byte copy is
+ being used in place of assignment to an existing object or
+ as a substitute for initialization, assume it's the former.
+ Determine the best alternative to use instead depending on
+ what's not deleted. */
+ if (hasassign && hasctors[1])
+ suggest = G_("; use copy-assignment or copy-initialization instead");
+ else if (hasassign)
+ suggest = G_("; use copy-assignment instead");
+ else if (hasctors[1])
+ suggest = G_("; use copy-initialization instead");
+
+ if (!trivassign)
+ warnfmt = G_("%qD writing to an object of type %#qT with no trivial "
+ "copy-assignment%s");
+ else if (!trivially_copyable_p (desttype))
+ warnfmt = G_("%qD writing to an object of non-trivially copyable "
+ "type %#qT%s");
+ else if (!trivcopy)
+ warnfmt = G_("%qD writing to an object with a deleted copy constructor");
+
+ else if (!trivial
+ && !VOID_TYPE_P (srctype)
+ && !is_byte_access_type (srctype)
+ && !same_type_ignoring_top_level_qualifiers_p (desttype,
+ srctype))
+ {
+ /* Warn when copying into a non-trivial object from an object
+ of a different type other than void or char. */
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ "%qD copying an object of non-trivial type "
+ "%#qT from an array of %#qT",
+ fndecl, desttype, srctype);
+ }
+ else if (fld
+ && !VOID_TYPE_P (srctype)
+ && !is_byte_access_type (srctype)
+ && !same_type_ignoring_top_level_qualifiers_p (desttype,
+ srctype))
+ {
+ const char *access = TREE_PRIVATE (fld) ? "private" : "protected";
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ "%qD copying an object of type %#qT with "
+ "%qs member %qD from an array of %#qT; use "
+ "assignment or copy-initialization instead",
+ fndecl, desttype, access, fld, srctype);
+ }
+ else if (!trivial && vec_safe_length (args) > 2)
+ {
+ tree sz = maybe_constant_value ((*args)[2]);
+ if (!tree_fits_uhwi_p (sz))
+ break;
+
+ /* Finally, warn on partial copies. */
+ unsigned HOST_WIDE_INT typesize
+ = tree_to_uhwi (TYPE_SIZE_UNIT (desttype));
+ if (unsigned HOST_WIDE_INT partial = tree_to_uhwi (sz) % typesize)
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ (typesize - partial > 1
+ ? G_("%qD writing to an object of "
+ "a non-trivial type %#qT leaves %wu "
+ "bytes unchanged")
+ : G_("%qD writing to an object of "
+ "a non-trivial type %#qT leaves %wu "
+ "byte unchanged")),
+ fndecl, desttype, typesize - partial);
+ }
+ break;
+
+ case BUILT_IN_REALLOC:
+
+ if (!trivially_copyable_p (desttype))
+ warnfmt = G_("%qD moving an object of non-trivially copyable type "
+ "%#qT; use %<new%> and %<delete%> instead");
+ else if (!trivcopy)
+ warnfmt = G_("%qD moving an object of type %#qT with deleted copy "
+ "constructor; use %<new%> and %<delete%> instead");
+ else if (!get_dtor (desttype, tf_none))
+ warnfmt = G_("%qD moving an object of type %#qT with deleted "
+ "destructor");
+ else if (!trivial)
+ {
+ tree sz = maybe_constant_value ((*args)[1]);
+ if (TREE_CODE (sz) == INTEGER_CST
+ && tree_int_cst_lt (sz, TYPE_SIZE_UNIT (desttype)))
+ /* Finally, warn on reallocation into insufficient space. */
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ "%qD moving an object of non-trivial type "
+ "%#qT and size %E into a region of size %E",
+ fndecl, desttype, TYPE_SIZE_UNIT (desttype),
+ sz);
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ if (warnfmt)
+ {
+ if (suggest)
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ warnfmt, fndecl, desttype, suggest);
+ else
+ warned = warning_at (loc, OPT_Wclass_memaccess,
+ warnfmt, fndecl, desttype);
+ }
+
+ if (warned)
+ inform (location_of (desttype), "%#qT declared here", desttype);
+}
+
+/* Build and return a call to FN, using NARGS arguments in ARGARRAY.
+ If FN is the result of resolving an overloaded target built-in,
+ ORIG_FNDECL is the original function decl, otherwise it is null.
+ This function performs no overload resolution, conversion, or other
+ high-level operations. */
+
+tree
+build_cxx_call (tree fn, int nargs, tree *argarray,
+ tsubst_flags_t complain, tree orig_fndecl)
+{
+ tree fndecl;
+
+ /* Remember roughly where this call is. */
+ location_t loc = cp_expr_loc_or_input_loc (fn);
+ fn = build_call_a (fn, nargs, argarray);
+ SET_EXPR_LOCATION (fn, loc);
+
+ fndecl = get_callee_fndecl (fn);
+ if (!orig_fndecl)
+ orig_fndecl = fndecl;
+
+ /* Check that arguments to builtin functions match the expectations. */
+ if (fndecl
+ && !processing_template_decl
+ && fndecl_built_in_p (fndecl))
+ {
+ int i;
+
+ /* We need to take care that values to BUILT_IN_NORMAL
+ are reduced. */
+ for (i = 0; i < nargs; i++)
+ argarray[i] = maybe_constant_value (argarray[i]);
+
+ if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
+ orig_fndecl, nargs, argarray))
+ return error_mark_node;
+ }
+
+ if (VOID_TYPE_P (TREE_TYPE (fn)))
+ return fn;
+
+ /* 5.2.2/11: If a function call is a prvalue of object type: if the
+ function call is either the operand of a decltype-specifier or the
+ right operand of a comma operator that is the operand of a
+ decltype-specifier, a temporary object is not introduced for the
+ prvalue. The type of the prvalue may be incomplete. */
+ if (!(complain & tf_decltype))
+ {
+ fn = require_complete_type_sfinae (fn, complain);
+ if (fn == error_mark_node)
+ return error_mark_node;
+
+ if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
+ {
+ fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
+ maybe_warn_parm_abi (TREE_TYPE (fn), loc);
+ }
+ }
+ return convert_from_reference (fn);
+}
+
+/* Returns the value to use for the in-charge parameter when making a
+ call to a function with the indicated NAME.
+
+ FIXME:Can't we find a neater way to do this mapping? */
+
+tree
+in_charge_arg_for_name (tree name)
+{
+ if (IDENTIFIER_CTOR_P (name))
+ {
+ if (name == complete_ctor_identifier)
+ return integer_one_node;
+ gcc_checking_assert (name == base_ctor_identifier);
+ }
+ else
+ {
+ if (name == complete_dtor_identifier)
+ return integer_two_node;
+ else if (name == deleting_dtor_identifier)
+ return integer_three_node;
+ gcc_checking_assert (name == base_dtor_identifier);
+ }
+
+ return integer_zero_node;
+}
+
+/* We've built up a constructor call RET. Complain if it delegates to the
+ constructor we're currently compiling. */
+
+static void
+check_self_delegation (tree ret)
+{
+ if (TREE_CODE (ret) == TARGET_EXPR)
+ ret = TARGET_EXPR_INITIAL (ret);
+ tree fn = cp_get_callee_fndecl_nofold (ret);
+ if (fn && DECL_ABSTRACT_ORIGIN (fn) == current_function_decl)
+ error ("constructor delegates to itself");
+}
+
+/* Build a call to a constructor, destructor, or an assignment
+ operator for INSTANCE, an expression with class type. NAME
+ indicates the special member function to call; *ARGS are the
+ arguments. ARGS may be NULL. This may change ARGS. BINFO
+ indicates the base of INSTANCE that is to be passed as the `this'
+ parameter to the member function called.
+
+ FLAGS are the LOOKUP_* flags to use when processing the call.
+
+ If NAME indicates a complete object constructor, INSTANCE may be
+ NULL_TREE. In this case, the caller will call build_cplus_new to
+ store the newly constructed object into a VAR_DECL. */
+
+tree
+build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
+ tree binfo, int flags, tsubst_flags_t complain)
+{
+ tree fns;
+ /* The type of the subobject to be constructed or destroyed. */
+ tree class_type;
+ vec<tree, va_gc> *allocated = NULL;
+ tree ret;
+
+ gcc_assert (IDENTIFIER_CDTOR_P (name) || name == assign_op_identifier);
+
+ if (error_operand_p (instance))
+ return error_mark_node;
+
+ if (IDENTIFIER_DTOR_P (name))
+ {
+ gcc_assert (args == NULL || vec_safe_is_empty (*args));
+ if (!type_build_dtor_call (TREE_TYPE (instance)))
+ /* Shortcut to avoid lazy destructor declaration. */
+ return build_trivial_dtor_call (instance);
+ }
+
+ if (TYPE_P (binfo))
+ {
+ /* Resolve the name. */
+ if (!complete_type_or_maybe_complain (binfo, NULL_TREE, complain))
+ return error_mark_node;
+
+ binfo = TYPE_BINFO (binfo);
+ }
+
+ gcc_assert (binfo != NULL_TREE);
+
+ class_type = BINFO_TYPE (binfo);
+
+ /* Handle the special case where INSTANCE is NULL_TREE. */
+ if (name == complete_ctor_identifier && !instance)
+ instance = build_dummy_object (class_type);
+ else
+ {
+ /* Convert to the base class, if necessary. */
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (instance), BINFO_TYPE (binfo)))
+ {
+ if (IDENTIFIER_CDTOR_P (name))
+ /* For constructors and destructors, either the base is
+ non-virtual, or it is virtual but we are doing the
+ conversion from a constructor or destructor for the
+ complete object. In either case, we can convert
+ statically. */
+ instance = convert_to_base_statically (instance, binfo);
+ else
+ {
+ /* However, for assignment operators, we must convert
+ dynamically if the base is virtual. */
+ gcc_checking_assert (name == assign_op_identifier);
+ instance = build_base_path (PLUS_EXPR, instance,
+ binfo, /*nonnull=*/1, complain);
+ }
+ }
+ }
+
+ gcc_assert (instance != NULL_TREE);
+
+ /* In C++17, "If the initializer expression is a prvalue and the
+ cv-unqualified version of the source type is the same class as the class
+ of the destination, the initializer expression is used to initialize the
+ destination object." Handle that here to avoid doing overload
+ resolution. */
+ if (cxx_dialect >= cxx17
+ && args && vec_safe_length (*args) == 1
+ && !unsafe_return_slot_p (instance))
+ {
+ tree arg = (**args)[0];
+
+ if (BRACE_ENCLOSED_INITIALIZER_P (arg)
+ && !TYPE_HAS_LIST_CTOR (class_type)
+ && !CONSTRUCTOR_IS_DESIGNATED_INIT (arg)
+ && CONSTRUCTOR_NELTS (arg) == 1)
+ arg = CONSTRUCTOR_ELT (arg, 0)->value;
+
+ if ((TREE_CODE (arg) == TARGET_EXPR
+ || TREE_CODE (arg) == CONSTRUCTOR)
+ && (same_type_ignoring_top_level_qualifiers_p
+ (class_type, TREE_TYPE (arg))))
+ {
+ if (is_dummy_object (instance))
+ return arg;
+ else if (TREE_CODE (arg) == TARGET_EXPR)
+ TARGET_EXPR_DIRECT_INIT_P (arg) = true;
+
+ if ((complain & tf_error)
+ && (flags & LOOKUP_DELEGATING_CONS))
+ check_self_delegation (arg);
+ /* Avoid change of behavior on Wunused-var-2.C. */
+ instance = mark_lvalue_use (instance);
+ return build2 (INIT_EXPR, class_type, instance, arg);
+ }
+ }
+
+ fns = lookup_fnfields (binfo, name, 1, complain);
+
+ /* When making a call to a constructor or destructor for a subobject
+ that uses virtual base classes, pass down a pointer to a VTT for
+ the subobject. */
+ if ((name == base_ctor_identifier
+ || name == base_dtor_identifier)
+ && CLASSTYPE_VBASECLASSES (class_type))
+ {
+ tree vtt;
+ tree sub_vtt;
+
+ /* If the current function is a complete object constructor
+ or destructor, then we fetch the VTT directly.
+ Otherwise, we look it up using the VTT we were given. */
+ vtt = DECL_CHAIN (CLASSTYPE_VTABLES (current_class_type));
+ vtt = decay_conversion (vtt, complain);
+ if (vtt == error_mark_node)
+ return error_mark_node;
+ vtt = build_if_in_charge (vtt, current_vtt_parm);
+ if (BINFO_SUBVTT_INDEX (binfo))
+ sub_vtt = fold_build_pointer_plus (vtt, BINFO_SUBVTT_INDEX (binfo));
+ else
+ sub_vtt = vtt;
+
+ if (args == NULL)
+ {
+ allocated = make_tree_vector ();
+ args = &allocated;
+ }
+
+ vec_safe_insert (*args, 0, sub_vtt);
+ }
+
+ ret = build_new_method_call (instance, fns, args,
+ TYPE_BINFO (BINFO_TYPE (binfo)),
+ flags, /*fn=*/NULL,
+ complain);
+
+ if (allocated != NULL)
+ release_tree_vector (allocated);
+
+ if ((complain & tf_error)
+ && (flags & LOOKUP_DELEGATING_CONS)
+ && name == complete_ctor_identifier)
+ check_self_delegation (ret);
+
+ return ret;
+}
+
+/* Return the NAME, as a C string. The NAME indicates a function that
+ is a member of TYPE. *FREE_P is set to true if the caller must
+ free the memory returned.
+
+ Rather than go through all of this, we should simply set the names
+ of constructors and destructors appropriately, and dispense with
+ ctor_identifier, dtor_identifier, etc. */
+
+static char *
+name_as_c_string (tree name, tree type, bool *free_p)
+{
+ const char *pretty_name;
+
+ /* Assume that we will not allocate memory. */
+ *free_p = false;
+ /* Constructors and destructors are special. */
+ if (IDENTIFIER_CDTOR_P (name))
+ {
+ pretty_name
+ = identifier_to_locale (IDENTIFIER_POINTER (constructor_name (type)));
+ /* For a destructor, add the '~'. */
+ if (IDENTIFIER_DTOR_P (name))
+ {
+ pretty_name = concat ("~", pretty_name, NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ }
+ else if (IDENTIFIER_CONV_OP_P (name))
+ {
+ pretty_name = concat ("operator ",
+ type_as_string_translate (TREE_TYPE (name),
+ TFF_PLAIN_IDENTIFIER),
+ NULL);
+ /* Remember that we need to free the memory allocated. */
+ *free_p = true;
+ }
+ else
+ pretty_name = identifier_to_locale (IDENTIFIER_POINTER (name));
+
+ return CONST_CAST (char *, pretty_name);
+}
+
+/* If CANDIDATES contains exactly one candidate, return it, otherwise
+ return NULL. */
+
+static z_candidate *
+single_z_candidate (z_candidate *candidates)
+{
+ if (candidates == NULL)
+ return NULL;
+
+ if (candidates->next)
+ return NULL;
+
+ return candidates;
+}
+
+/* If CANDIDATE is invalid due to a bad argument type, return the
+ pertinent conversion_info.
+
+ Otherwise, return NULL. */
+
+static const conversion_info *
+maybe_get_bad_conversion_for_unmatched_call (const z_candidate *candidate)
+{
+ /* Must be an rr_arg_conversion or rr_bad_arg_conversion. */
+ rejection_reason *r = candidate->reason;
+
+ if (r == NULL)
+ return NULL;
+
+ switch (r->code)
+ {
+ default:
+ return NULL;
+
+ case rr_arg_conversion:
+ return &r->u.conversion;
+
+ case rr_bad_arg_conversion:
+ return &r->u.bad_conversion;
+ }
+}
+
+/* Issue an error and note complaining about a bad argument type at a
+ callsite with a single candidate FNDECL.
+
+ ARG_LOC is the location of the argument (or UNKNOWN_LOCATION, in which
+ case input_location is used).
+ FROM_TYPE is the type of the actual argument; TO_TYPE is the type of
+ the formal parameter. */
+
+void
+complain_about_bad_argument (location_t arg_loc,
+ tree from_type, tree to_type,
+ tree fndecl, int parmnum)
+{
+ auto_diagnostic_group d;
+ range_label_for_type_mismatch rhs_label (from_type, to_type);
+ range_label *label = &rhs_label;
+ if (arg_loc == UNKNOWN_LOCATION)
+ {
+ arg_loc = input_location;
+ label = NULL;
+ }
+ gcc_rich_location richloc (arg_loc, label);
+ error_at (&richloc,
+ "cannot convert %qH to %qI",
+ from_type, to_type);
+ maybe_inform_about_fndecl_for_bogus_argument_init (fndecl,
+ parmnum);
+}
+
+/* Subroutine of build_new_method_call_1, for where there are no viable
+ candidates for the call. */
+
+static void
+complain_about_no_candidates_for_method_call (tree instance,
+ z_candidate *candidates,
+ tree explicit_targs,
+ tree basetype,
+ tree optype, tree name,
+ bool skip_first_for_error,
+ vec<tree, va_gc> *user_args)
+{
+ auto_diagnostic_group d;
+ if (!COMPLETE_OR_OPEN_TYPE_P (basetype))
+ cxx_incomplete_type_error (instance, basetype);
+ else if (optype)
+ error ("no matching function for call to %<%T::operator %T(%A)%#V%>",
+ basetype, optype, build_tree_list_vec (user_args),
+ TREE_TYPE (instance));
+ else
+ {
+ /* Special-case for when there's a single candidate that's failing
+ due to a bad argument type. */
+ if (z_candidate *candidate = single_z_candidate (candidates))
+ if (const conversion_info *conv
+ = maybe_get_bad_conversion_for_unmatched_call (candidate))
+ {
+ tree from_type = conv->from;
+ if (!TYPE_P (conv->from))
+ from_type = lvalue_type (conv->from);
+ complain_about_bad_argument (conv->loc,
+ from_type, conv->to_type,
+ candidate->fn, conv->n_arg);
+ return;
+ }
+
+ tree arglist = build_tree_list_vec (user_args);
+ tree errname = name;
+ bool twiddle = false;
+ if (IDENTIFIER_CDTOR_P (errname))
+ {
+ twiddle = IDENTIFIER_DTOR_P (errname);
+ errname = constructor_name (basetype);
+ }
+ if (explicit_targs)
+ errname = lookup_template_function (errname, explicit_targs);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
+ error ("no matching function for call to %<%T::%s%E(%A)%#V%>",
+ basetype, &"~"[!twiddle], errname, arglist,
+ TREE_TYPE (instance));
+ }
+ print_z_candidates (location_of (name), candidates);
+}
+
+/* Build a call to "INSTANCE.FN (ARGS)". If FN_P is non-NULL, it will
+ be set, upon return, to the function called. ARGS may be NULL.
+ This may change ARGS. */
+
+tree
+build_new_method_call (tree instance, tree fns, vec<tree, va_gc> **args,
+ tree conversion_path, int flags,
+ tree *fn_p, tsubst_flags_t complain)
+{
+ struct z_candidate *candidates = 0, *cand;
+ tree explicit_targs = NULL_TREE;
+ tree basetype = NULL_TREE;
+ tree access_binfo;
+ tree optype;
+ tree first_mem_arg = NULL_TREE;
+ tree name;
+ bool skip_first_for_error;
+ vec<tree, va_gc> *user_args;
+ tree call;
+ tree fn;
+ int template_only = 0;
+ bool any_viable_p;
+ tree orig_instance;
+ tree orig_fns;
+ vec<tree, va_gc> *orig_args = NULL;
+ void *p;
+
+ auto_cond_timevar tv (TV_OVERLOAD);
+
+ gcc_assert (instance != NULL_TREE);
+
+ /* We don't know what function we're going to call, yet. */
+ if (fn_p)
+ *fn_p = NULL_TREE;
+
+ if (error_operand_p (instance)
+ || !fns || error_operand_p (fns))
+ return error_mark_node;
+
+ if (!BASELINK_P (fns))
+ {
+ if (complain & tf_error)
+ error ("call to non-function %qD", fns);
+ return error_mark_node;
+ }
+
+ orig_instance = instance;
+ orig_fns = fns;
+
+ /* Dismantle the baselink to collect all the information we need. */
+ if (!conversion_path)
+ conversion_path = BASELINK_BINFO (fns);
+ access_binfo = BASELINK_ACCESS_BINFO (fns);
+ optype = BASELINK_OPTYPE (fns);
+ fns = BASELINK_FUNCTIONS (fns);
+ if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
+ {
+ explicit_targs = TREE_OPERAND (fns, 1);
+ fns = TREE_OPERAND (fns, 0);
+ template_only = 1;
+ }
+ gcc_assert (OVL_P (fns));
+ fn = OVL_FIRST (fns);
+ name = DECL_NAME (fn);
+
+ basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance));
+ gcc_assert (CLASS_TYPE_P (basetype));
+
+ user_args = args == NULL ? NULL : *args;
+ /* Under DR 147 A::A() is an invalid constructor call,
+ not a functional cast. */
+ if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn))
+ {
+ if (! (complain & tf_error))
+ return error_mark_node;
+
+ basetype = DECL_CONTEXT (fn);
+ name = constructor_name (basetype);
+ auto_diagnostic_group d;
+ if (permerror (input_location,
+ "cannot call constructor %<%T::%D%> directly",
+ basetype, name))
+ inform (input_location, "for a function-style cast, remove the "
+ "redundant %<::%D%>", name);
+ call = build_functional_cast (input_location, basetype,
+ build_tree_list_vec (user_args),
+ complain);
+ return call;
+ }
+
+ if (processing_template_decl)
+ {
+ orig_args = args == NULL ? NULL : make_tree_vector_copy (*args);
+ instance = build_non_dependent_expr (instance);
+ if (args != NULL)
+ make_args_non_dependent (*args);
+ }
+
+ /* Process the argument list. */
+ if (args != NULL && *args != NULL)
+ {
+ *args = resolve_args (*args, complain);
+ if (*args == NULL)
+ return error_mark_node;
+ user_args = *args;
+ }
+
+ /* Consider the object argument to be used even if we end up selecting a
+ static member function. */
+ instance = mark_type_use (instance);
+
+ /* Figure out whether to skip the first argument for the error
+ message we will display to users if an error occurs. We don't
+ want to display any compiler-generated arguments. The "this"
+ pointer hasn't been added yet. However, we must remove the VTT
+ pointer if this is a call to a base-class constructor or
+ destructor. */
+ skip_first_for_error = false;
+ if (IDENTIFIER_CDTOR_P (name))
+ {
+ /* Callers should explicitly indicate whether they want to ctor
+ the complete object or just the part without virtual bases. */
+ gcc_assert (name != ctor_identifier);
+
+ /* Remove the VTT pointer, if present. */
+ if ((name == base_ctor_identifier || name == base_dtor_identifier)
+ && CLASSTYPE_VBASECLASSES (basetype))
+ skip_first_for_error = true;
+
+ /* It's OK to call destructors and constructors on cv-qualified
+ objects. Therefore, convert the INSTANCE to the unqualified
+ type, if necessary. */
+ if (!same_type_p (basetype, TREE_TYPE (instance)))
+ {
+ instance = build_this (instance);
+ instance = build_nop (build_pointer_type (basetype), instance);
+ instance = build_fold_indirect_ref (instance);
+ }
+ }
+ else
+ gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn));
+
+ /* For the overload resolution we need to find the actual `this`
+ that would be captured if the call turns out to be to a
+ non-static member function. Do not actually capture it at this
+ point. */
+ if (DECL_CONSTRUCTOR_P (fn))
+ /* Constructors don't use the enclosing 'this'. */
+ first_mem_arg = instance;
+ else
+ first_mem_arg = maybe_resolve_dummy (instance, false);
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ /* The number of arguments artificial parms in ARGS; we subtract one because
+ there's no 'this' in ARGS. */
+ unsigned skip = num_artificial_parms_for (fn) - 1;
+
+ /* If CONSTRUCTOR_IS_DIRECT_INIT is set, this was a T{ } form
+ initializer, not T({ }). */
+ if (DECL_CONSTRUCTOR_P (fn)
+ && vec_safe_length (user_args) > skip
+ && DIRECT_LIST_INIT_P ((*user_args)[skip]))
+ {
+ tree init_list = (*user_args)[skip];
+ tree init = NULL_TREE;
+
+ gcc_assert (user_args->length () == skip + 1
+ && !(flags & LOOKUP_ONLYCONVERTING));
+
+ /* If the initializer list has no elements and T is a class type with
+ a default constructor, the object is value-initialized. Handle
+ this here so we don't need to handle it wherever we use
+ build_special_member_call. */
+ if (CONSTRUCTOR_NELTS (init_list) == 0
+ && TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
+ /* For a user-provided default constructor, use the normal
+ mechanisms so that protected access works. */
+ && type_has_non_user_provided_default_constructor (basetype)
+ && !processing_template_decl)
+ init = build_value_init (basetype, complain);
+
+ /* If BASETYPE is an aggregate, we need to do aggregate
+ initialization. */
+ else if (CP_AGGREGATE_TYPE_P (basetype))
+ {
+ init = reshape_init (basetype, init_list, complain);
+ init = digest_init (basetype, init, complain);
+ }
+
+ if (init)
+ {
+ if (is_dummy_object (instance))
+ return get_target_expr_sfinae (init, complain);
+ init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
+ TREE_SIDE_EFFECTS (init) = true;
+ return init;
+ }
+
+ /* Otherwise go ahead with overload resolution. */
+ add_list_candidates (fns, first_mem_arg, user_args,
+ basetype, explicit_targs, template_only,
+ conversion_path, access_binfo, flags,
+ &candidates, complain);
+ }
+ else
+ add_candidates (fns, first_mem_arg, user_args, optype,
+ explicit_targs, template_only, conversion_path,
+ access_binfo, flags, &candidates, complain);
+
+ any_viable_p = false;
+ candidates = splice_viable (candidates, false, &any_viable_p);
+
+ if (!any_viable_p)
+ {
+ /* [dcl.init], 17.6.2.2:
+
+ Otherwise, if no constructor is viable, the destination type is
+ a (possibly cv-qualified) aggregate class A, and the initializer
+ is a parenthesized expression-list, the object is initialized as
+ follows...
+
+ We achieve this by building up a CONSTRUCTOR, as for list-init,
+ and setting CONSTRUCTOR_IS_PAREN_INIT to distinguish between
+ the two. */
+ if (DECL_CONSTRUCTOR_P (fn)
+ && !(flags & LOOKUP_ONLYCONVERTING)
+ && cxx_dialect >= cxx20
+ && CP_AGGREGATE_TYPE_P (basetype)
+ && !vec_safe_is_empty (user_args))
+ {
+ /* Create a CONSTRUCTOR from ARGS, e.g. {1, 2} from <1, 2>. */
+ tree ctor = build_constructor_from_vec (init_list_type_node,
+ user_args);
+ CONSTRUCTOR_IS_DIRECT_INIT (ctor) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (ctor) = true;
+ if (is_dummy_object (instance))
+ return ctor;
+ else
+ {
+ ctor = digest_init (basetype, ctor, complain);
+ if (ctor == error_mark_node)
+ return error_mark_node;
+ ctor = build2 (INIT_EXPR, TREE_TYPE (instance), instance, ctor);
+ TREE_SIDE_EFFECTS (ctor) = true;
+ return ctor;
+ }
+ }
+ if (complain & tf_error)
+ complain_about_no_candidates_for_method_call (instance, candidates,
+ explicit_targs, basetype,
+ optype, name,
+ skip_first_for_error,
+ user_args);
+ call = error_mark_node;
+ }
+ else
+ {
+ cand = tourney (candidates, complain);
+ if (cand == 0)
+ {
+ char *pretty_name;
+ bool free_p;
+ tree arglist;
+
+ if (complain & tf_error)
+ {
+ pretty_name = name_as_c_string (name, basetype, &free_p);
+ arglist = build_tree_list_vec (user_args);
+ if (skip_first_for_error)
+ arglist = TREE_CHAIN (arglist);
+ auto_diagnostic_group d;
+ if (!any_strictly_viable (candidates))
+ error ("no matching function for call to %<%s(%A)%>",
+ pretty_name, arglist);
+ else
+ error ("call of overloaded %<%s(%A)%> is ambiguous",
+ pretty_name, arglist);
+ print_z_candidates (location_of (name), candidates);
+ if (free_p)
+ free (pretty_name);
+ }
+ call = error_mark_node;
+ if (fn_p)
+ *fn_p = error_mark_node;
+ }
+ else
+ {
+ fn = cand->fn;
+ call = NULL_TREE;
+
+ if (!(flags & LOOKUP_NONVIRTUAL)
+ && DECL_PURE_VIRTUAL_P (fn)
+ && instance == current_class_ref
+ && (complain & tf_warning))
+ {
+ /* This is not an error, it is runtime undefined
+ behavior. */
+ if (!current_function_decl)
+ warning (0, "pure virtual %q#D called from "
+ "non-static data member initializer", fn);
+ else if (DECL_CONSTRUCTOR_P (current_function_decl)
+ || DECL_DESTRUCTOR_P (current_function_decl))
+ warning (0, (DECL_CONSTRUCTOR_P (current_function_decl)
+ ? G_("pure virtual %q#D called from constructor")
+ : G_("pure virtual %q#D called from destructor")),
+ fn);
+ }
+
+ if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE
+ && !DECL_CONSTRUCTOR_P (fn)
+ && is_dummy_object (instance))
+ {
+ instance = maybe_resolve_dummy (instance, true);
+ if (instance == error_mark_node)
+ call = error_mark_node;
+ else if (!is_dummy_object (instance))
+ {
+ /* We captured 'this' in the current lambda now that
+ we know we really need it. */
+ cand->first_arg = instance;
+ }
+ else if (current_class_ptr && any_dependent_bases_p ())
+ /* We can't tell until instantiation time whether we can use
+ *this as the implicit object argument. */;
+ else
+ {
+ if (complain & tf_error)
+ error ("cannot call member function %qD without object",
+ fn);
+ call = error_mark_node;
+ }
+ }
+
+ if (call != error_mark_node)
+ {
+ /* Now we know what function is being called. */
+ if (fn_p)
+ *fn_p = fn;
+ /* Build the actual CALL_EXPR. */
+ call = build_over_call (cand, flags, complain);
+ /* In an expression of the form `a->f()' where `f' turns
+ out to be a static member function, `a' is
+ none-the-less evaluated. */
+ if (TREE_CODE (TREE_TYPE (fn)) != METHOD_TYPE
+ && !is_dummy_object (instance)
+ && TREE_SIDE_EFFECTS (instance))
+ {
+ /* But avoid the implicit lvalue-rvalue conversion when 'a'
+ is volatile. */
+ tree a = instance;
+ if (TREE_THIS_VOLATILE (a))
+ a = build_this (a);
+ if (TREE_SIDE_EFFECTS (a))
+ call = build2 (COMPOUND_EXPR, TREE_TYPE (call), a, call);
+ }
+ else if (call != error_mark_node
+ && DECL_DESTRUCTOR_P (cand->fn)
+ && !VOID_TYPE_P (TREE_TYPE (call)))
+ /* An explicit call of the form "x->~X()" has type
+ "void". However, on platforms where destructors
+ return "this" (i.e., those where
+ targetm.cxx.cdtor_returns_this is true), such calls
+ will appear to have a return value of pointer type
+ to the low-level call machinery. We do not want to
+ change the low-level machinery, since we want to be
+ able to optimize "delete f()" on such platforms as
+ "operator delete(~X(f()))" (rather than generating
+ "t = f(), ~X(t), operator delete (t)"). */
+ call = build_nop (void_type_node, call);
+ }
+ }
+ }
+
+ if (processing_template_decl && call != error_mark_node)
+ {
+ bool cast_to_void = false;
+
+ if (TREE_CODE (call) == COMPOUND_EXPR)
+ call = TREE_OPERAND (call, 1);
+ else if (TREE_CODE (call) == NOP_EXPR)
+ {
+ cast_to_void = true;
+ call = TREE_OPERAND (call, 0);
+ }
+ if (INDIRECT_REF_P (call))
+ call = TREE_OPERAND (call, 0);
+
+ /* Prune all but the selected function from the original overload
+ set so that we can avoid some duplicate work at instantiation time. */
+ if (really_overloaded_fn (fns))
+ {
+ if (DECL_TEMPLATE_INFO (fn)
+ && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (fn))
+ && dependent_type_p (DECL_CONTEXT (fn)))
+ {
+ /* FIXME: We're not prepared to fully instantiate "inside-out"
+ partial instantiations such as A<T>::f<int>(). So instead
+ use the selected template, not the specialization. */
+
+ if (OVL_SINGLE_P (fns))
+ /* If the original overload set consists of a single function
+ template, this isn't beneficial. */
+ goto skip_prune;
+
+ fn = ovl_make (DECL_TI_TEMPLATE (fn));
+ if (template_only)
+ fn = lookup_template_function (fn, explicit_targs);
+ }
+ orig_fns = copy_node (orig_fns);
+ BASELINK_FUNCTIONS (orig_fns) = fn;
+ BASELINK_FUNCTIONS_MAYBE_INCOMPLETE_P (orig_fns) = true;
+ }
+
+skip_prune:
+ call = (build_min_non_dep_call_vec
+ (call,
+ build_min (COMPONENT_REF, TREE_TYPE (CALL_EXPR_FN (call)),
+ orig_instance, orig_fns, NULL_TREE),
+ orig_args));
+ SET_EXPR_LOCATION (call, input_location);
+ call = convert_from_reference (call);
+ if (cast_to_void)
+ call = build_nop (void_type_node, call);
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ if (orig_args != NULL)
+ release_tree_vector (orig_args);
+
+ return call;
+}
+
+/* Returns true iff standard conversion sequence ICS1 is a proper
+ subsequence of ICS2. */
+
+static bool
+is_subseq (conversion *ics1, conversion *ics2)
+{
+ /* We can assume that a conversion of the same code
+ between the same types indicates a subsequence since we only get
+ here if the types we are converting from are the same. */
+
+ while (ics1->kind == ck_rvalue
+ || ics1->kind == ck_lvalue)
+ ics1 = next_conversion (ics1);
+
+ while (1)
+ {
+ while (ics2->kind == ck_rvalue
+ || ics2->kind == ck_lvalue)
+ ics2 = next_conversion (ics2);
+
+ if (ics2->kind == ck_user
+ || !has_next (ics2->kind))
+ /* At this point, ICS1 cannot be a proper subsequence of
+ ICS2. We can get a USER_CONV when we are comparing the
+ second standard conversion sequence of two user conversion
+ sequences. */
+ return false;
+
+ ics2 = next_conversion (ics2);
+
+ while (ics2->kind == ck_rvalue
+ || ics2->kind == ck_lvalue)
+ ics2 = next_conversion (ics2);
+
+ if (ics2->kind == ics1->kind
+ && same_type_p (ics2->type, ics1->type)
+ && (ics1->kind == ck_identity
+ || same_type_p (next_conversion (ics2)->type,
+ next_conversion (ics1)->type)))
+ return true;
+ }
+}
+
+/* Returns nonzero iff DERIVED is derived from BASE. The inputs may
+ be any _TYPE nodes. */
+
+bool
+is_properly_derived_from (tree derived, tree base)
+{
+ if (!CLASS_TYPE_P (derived) || !CLASS_TYPE_P (base))
+ return false;
+
+ /* We only allow proper derivation here. The DERIVED_FROM_P macro
+ considers every class derived from itself. */
+ return (!same_type_ignoring_top_level_qualifiers_p (derived, base)
+ && DERIVED_FROM_P (base, derived));
+}
+
+/* We build the ICS for an implicit object parameter as a pointer
+ conversion sequence. However, such a sequence should be compared
+ as if it were a reference conversion sequence. If ICS is the
+ implicit conversion sequence for an implicit object parameter,
+ modify it accordingly. */
+
+static void
+maybe_handle_implicit_object (conversion **ics)
+{
+ if ((*ics)->this_p)
+ {
+ /* [over.match.funcs]
+
+ For non-static member functions, the type of the
+ implicit object parameter is "reference to cv X"
+ where X is the class of which the function is a
+ member and cv is the cv-qualification on the member
+ function declaration. */
+ conversion *t = *ics;
+ tree reference_type;
+
+ /* The `this' parameter is a pointer to a class type. Make the
+ implicit conversion talk about a reference to that same class
+ type. */
+ reference_type = TREE_TYPE (t->type);
+ reference_type = build_reference_type (reference_type);
+
+ if (t->kind == ck_qual)
+ t = next_conversion (t);
+ if (t->kind == ck_ptr)
+ t = next_conversion (t);
+ t = build_identity_conv (TREE_TYPE (t->type), NULL_TREE);
+ t = direct_reference_binding (reference_type, t);
+ t->this_p = 1;
+ t->rvaluedness_matches_p = 0;
+ *ics = t;
+ }
+}
+
+/* If *ICS is a REF_BIND set *ICS to the remainder of the conversion,
+ and return the initial reference binding conversion. Otherwise,
+ leave *ICS unchanged and return NULL. */
+
+static conversion *
+maybe_handle_ref_bind (conversion **ics)
+{
+ if ((*ics)->kind == ck_ref_bind)
+ {
+ conversion *old_ics = *ics;
+ *ics = next_conversion (old_ics);
+ (*ics)->user_conv_p = old_ics->user_conv_p;
+ return old_ics;
+ }
+
+ return NULL;
+}
+
+/* Get the expression at the beginning of the conversion chain C. */
+
+static tree
+conv_get_original_expr (conversion *c)
+{
+ for (; c; c = next_conversion (c))
+ if (c->kind == ck_identity || c->kind == ck_ambig || c->kind == ck_aggr)
+ return c->u.expr;
+ return NULL_TREE;
+}
+
+/* Return a tree representing the number of elements initialized by the
+ list-initialization C. The caller must check that C converts to an
+ array type. */
+
+static tree
+nelts_initialized_by_list_init (conversion *c)
+{
+ /* If the array we're converting to has a dimension, we'll use that. */
+ if (TYPE_DOMAIN (c->type))
+ return array_type_nelts_top (c->type);
+ else
+ {
+ /* Otherwise, we look at how many elements the constructor we're
+ initializing from has. */
+ tree ctor = conv_get_original_expr (c);
+ return size_int (CONSTRUCTOR_NELTS (ctor));
+ }
+}
+
+/* True iff C is a conversion that binds a reference or a pointer to
+ an array of unknown bound. */
+
+static inline bool
+conv_binds_to_array_of_unknown_bound (conversion *c)
+{
+ /* ck_ref_bind won't have the reference stripped. */
+ tree type = non_reference (c->type);
+ /* ck_qual won't have the pointer stripped. */
+ type = strip_pointer_operator (type);
+ return (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_DOMAIN (type) == NULL_TREE);
+}
+
+/* Compare two implicit conversion sequences according to the rules set out in
+ [over.ics.rank]. Return values:
+
+ 1: ics1 is better than ics2
+ -1: ics2 is better than ics1
+ 0: ics1 and ics2 are indistinguishable */
+
+static int
+compare_ics (conversion *ics1, conversion *ics2)
+{
+ tree from_type1;
+ tree from_type2;
+ tree to_type1;
+ tree to_type2;
+ tree deref_from_type1 = NULL_TREE;
+ tree deref_from_type2 = NULL_TREE;
+ tree deref_to_type1 = NULL_TREE;
+ tree deref_to_type2 = NULL_TREE;
+ conversion_rank rank1, rank2;
+
+ /* REF_BINDING is nonzero if the result of the conversion sequence
+ is a reference type. In that case REF_CONV is the reference
+ binding conversion. */
+ conversion *ref_conv1;
+ conversion *ref_conv2;
+
+ /* Compare badness before stripping the reference conversion. */
+ if (ics1->bad_p > ics2->bad_p)
+ return -1;
+ else if (ics1->bad_p < ics2->bad_p)
+ return 1;
+
+ /* Handle implicit object parameters. */
+ maybe_handle_implicit_object (&ics1);
+ maybe_handle_implicit_object (&ics2);
+
+ /* Handle reference parameters. */
+ ref_conv1 = maybe_handle_ref_bind (&ics1);
+ ref_conv2 = maybe_handle_ref_bind (&ics2);
+
+ /* List-initialization sequence L1 is a better conversion sequence than
+ list-initialization sequence L2 if L1 converts to
+ std::initializer_list<X> for some X and L2 does not. */
+ if (ics1->kind == ck_list && ics2->kind != ck_list)
+ return 1;
+ if (ics2->kind == ck_list && ics1->kind != ck_list)
+ return -1;
+
+ /* [over.ics.rank]
+
+ When comparing the basic forms of implicit conversion sequences (as
+ defined in _over.best.ics_)
+
+ --a standard conversion sequence (_over.ics.scs_) is a better
+ conversion sequence than a user-defined conversion sequence
+ or an ellipsis conversion sequence, and
+
+ --a user-defined conversion sequence (_over.ics.user_) is a
+ better conversion sequence than an ellipsis conversion sequence
+ (_over.ics.ellipsis_). */
+ /* Use BAD_CONVERSION_RANK because we already checked for a badness
+ mismatch. If both ICS are bad, we try to make a decision based on
+ what would have happened if they'd been good. This is not an
+ extension, we'll still give an error when we build up the call; this
+ just helps us give a more helpful error message. */
+ rank1 = BAD_CONVERSION_RANK (ics1);
+ rank2 = BAD_CONVERSION_RANK (ics2);
+
+ if (rank1 > rank2)
+ return -1;
+ else if (rank1 < rank2)
+ return 1;
+
+ if (ics1->ellipsis_p)
+ /* Both conversions are ellipsis conversions. */
+ return 0;
+
+ /* User-defined conversion sequence U1 is a better conversion sequence
+ than another user-defined conversion sequence U2 if they contain the
+ same user-defined conversion operator or constructor and if the sec-
+ ond standard conversion sequence of U1 is better than the second
+ standard conversion sequence of U2. */
+
+ /* Handle list-conversion with the same code even though it isn't always
+ ranked as a user-defined conversion and it doesn't have a second
+ standard conversion sequence; it will still have the desired effect.
+ Specifically, we need to do the reference binding comparison at the
+ end of this function. */
+
+ if (ics1->user_conv_p || ics1->kind == ck_list
+ || ics1->kind == ck_aggr || ics2->kind == ck_aggr)
+ {
+ conversion *t1 = strip_standard_conversion (ics1);
+ conversion *t2 = strip_standard_conversion (ics2);
+
+ if (!t1 || !t2 || t1->kind != t2->kind)
+ return 0;
+ else if (t1->kind == ck_user)
+ {
+ tree f1 = t1->cand ? t1->cand->fn : t1->type;
+ tree f2 = t2->cand ? t2->cand->fn : t2->type;
+ if (f1 != f2)
+ return 0;
+ }
+ /* List-initialization sequence L1 is a better conversion sequence than
+ list-initialization sequence L2 if
+
+ -- L1 and L2 convert to arrays of the same element type, and either
+ the number of elements n1 initialized by L1 is less than the number
+ of elements n2 initialized by L2, or n1=n2 and L2 converts to an array
+ of unknown bound and L1 does not. (Added in CWG 1307 and extended by
+ P0388R4.) */
+ else if (t1->kind == ck_aggr
+ && TREE_CODE (t1->type) == ARRAY_TYPE
+ && TREE_CODE (t2->type) == ARRAY_TYPE)
+ {
+ /* The type of the array elements must be the same. */
+ if (!same_type_p (TREE_TYPE (t1->type), TREE_TYPE (t2->type)))
+ return 0;
+
+ tree n1 = nelts_initialized_by_list_init (t1);
+ tree n2 = nelts_initialized_by_list_init (t2);
+ if (tree_int_cst_lt (n1, n2))
+ return 1;
+ else if (tree_int_cst_lt (n2, n1))
+ return -1;
+ /* The n1 == n2 case. */
+ bool c1 = conv_binds_to_array_of_unknown_bound (t1);
+ bool c2 = conv_binds_to_array_of_unknown_bound (t2);
+ if (c1 && !c2)
+ return -1;
+ else if (!c1 && c2)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ {
+ /* For ambiguous or aggregate conversions, use the target type as
+ a proxy for the conversion function. */
+ if (!same_type_ignoring_top_level_qualifiers_p (t1->type, t2->type))
+ return 0;
+ }
+
+ /* We can just fall through here, after setting up
+ FROM_TYPE1 and FROM_TYPE2. */
+ from_type1 = t1->type;
+ from_type2 = t2->type;
+ }
+ else
+ {
+ conversion *t1;
+ conversion *t2;
+
+ /* We're dealing with two standard conversion sequences.
+
+ [over.ics.rank]
+
+ Standard conversion sequence S1 is a better conversion
+ sequence than standard conversion sequence S2 if
+
+ --S1 is a proper subsequence of S2 (comparing the conversion
+ sequences in the canonical form defined by _over.ics.scs_,
+ excluding any Lvalue Transformation; the identity
+ conversion sequence is considered to be a subsequence of
+ any non-identity conversion sequence */
+
+ t1 = ics1;
+ while (t1->kind != ck_identity)
+ t1 = next_conversion (t1);
+ from_type1 = t1->type;
+
+ t2 = ics2;
+ while (t2->kind != ck_identity)
+ t2 = next_conversion (t2);
+ from_type2 = t2->type;
+ }
+
+ /* One sequence can only be a subsequence of the other if they start with
+ the same type. They can start with different types when comparing the
+ second standard conversion sequence in two user-defined conversion
+ sequences. */
+ if (same_type_p (from_type1, from_type2))
+ {
+ if (is_subseq (ics1, ics2))
+ return 1;
+ if (is_subseq (ics2, ics1))
+ return -1;
+ }
+
+ /* [over.ics.rank]
+
+ Or, if not that,
+
+ --the rank of S1 is better than the rank of S2 (by the rules
+ defined below):
+
+ Standard conversion sequences are ordered by their ranks: an Exact
+ Match is a better conversion than a Promotion, which is a better
+ conversion than a Conversion.
+
+ Two conversion sequences with the same rank are indistinguishable
+ unless one of the following rules applies:
+
+ --A conversion that does not a convert a pointer, pointer to member,
+ or std::nullptr_t to bool is better than one that does.
+
+ The ICS_STD_RANK automatically handles the pointer-to-bool rule,
+ so that we do not have to check it explicitly. */
+ if (ics1->rank < ics2->rank)
+ return 1;
+ else if (ics2->rank < ics1->rank)
+ return -1;
+
+ to_type1 = ics1->type;
+ to_type2 = ics2->type;
+
+ /* A conversion from scalar arithmetic type to complex is worse than a
+ conversion between scalar arithmetic types. */
+ if (same_type_p (from_type1, from_type2)
+ && ARITHMETIC_TYPE_P (from_type1)
+ && ARITHMETIC_TYPE_P (to_type1)
+ && ARITHMETIC_TYPE_P (to_type2)
+ && ((TREE_CODE (to_type1) == COMPLEX_TYPE)
+ != (TREE_CODE (to_type2) == COMPLEX_TYPE)))
+ {
+ if (TREE_CODE (to_type1) == COMPLEX_TYPE)
+ return -1;
+ else
+ return 1;
+ }
+
+ if (TYPE_PTR_P (from_type1)
+ && TYPE_PTR_P (from_type2)
+ && TYPE_PTR_P (to_type1)
+ && TYPE_PTR_P (to_type2))
+ {
+ deref_from_type1 = TREE_TYPE (from_type1);
+ deref_from_type2 = TREE_TYPE (from_type2);
+ deref_to_type1 = TREE_TYPE (to_type1);
+ deref_to_type2 = TREE_TYPE (to_type2);
+ }
+ /* The rules for pointers to members A::* are just like the rules
+ for pointers A*, except opposite: if B is derived from A then
+ A::* converts to B::*, not vice versa. For that reason, we
+ switch the from_ and to_ variables here. */
+ else if ((TYPE_PTRDATAMEM_P (from_type1) && TYPE_PTRDATAMEM_P (from_type2)
+ && TYPE_PTRDATAMEM_P (to_type1) && TYPE_PTRDATAMEM_P (to_type2))
+ || (TYPE_PTRMEMFUNC_P (from_type1)
+ && TYPE_PTRMEMFUNC_P (from_type2)
+ && TYPE_PTRMEMFUNC_P (to_type1)
+ && TYPE_PTRMEMFUNC_P (to_type2)))
+ {
+ deref_to_type1 = TYPE_PTRMEM_CLASS_TYPE (from_type1);
+ deref_to_type2 = TYPE_PTRMEM_CLASS_TYPE (from_type2);
+ deref_from_type1 = TYPE_PTRMEM_CLASS_TYPE (to_type1);
+ deref_from_type2 = TYPE_PTRMEM_CLASS_TYPE (to_type2);
+ }
+
+ if (deref_from_type1 != NULL_TREE
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type1))
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_from_type2)))
+ {
+ /* This was one of the pointer or pointer-like conversions.
+
+ [over.ics.rank]
+
+ --If class B is derived directly or indirectly from class A,
+ conversion of B* to A* is better than conversion of B* to
+ void*, and conversion of A* to void* is better than
+ conversion of B* to void*. */
+ if (VOID_TYPE_P (deref_to_type1)
+ && VOID_TYPE_P (deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type1,
+ deref_from_type2))
+ return -1;
+ else if (is_properly_derived_from (deref_from_type2,
+ deref_from_type1))
+ return 1;
+ }
+ else if (VOID_TYPE_P (deref_to_type1)
+ || VOID_TYPE_P (deref_to_type2))
+ {
+ if (same_type_p (deref_from_type1, deref_from_type2))
+ {
+ if (VOID_TYPE_P (deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type1,
+ deref_to_type1))
+ return 1;
+ }
+ /* We know that DEREF_TO_TYPE1 is `void' here. */
+ else if (is_properly_derived_from (deref_from_type1,
+ deref_to_type2))
+ return -1;
+ }
+ }
+ else if (RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type1))
+ && RECORD_OR_UNION_CODE_P (TREE_CODE (deref_to_type2)))
+ {
+ /* [over.ics.rank]
+
+ --If class B is derived directly or indirectly from class A
+ and class C is derived directly or indirectly from B,
+
+ --conversion of C* to B* is better than conversion of C* to
+ A*,
+
+ --conversion of B* to A* is better than conversion of C* to
+ A* */
+ if (same_type_p (deref_from_type1, deref_from_type2))
+ {
+ if (is_properly_derived_from (deref_to_type1,
+ deref_to_type2))
+ return 1;
+ else if (is_properly_derived_from (deref_to_type2,
+ deref_to_type1))
+ return -1;
+ }
+ else if (same_type_p (deref_to_type1, deref_to_type2))
+ {
+ if (is_properly_derived_from (deref_from_type2,
+ deref_from_type1))
+ return 1;
+ else if (is_properly_derived_from (deref_from_type1,
+ deref_from_type2))
+ return -1;
+ }
+ }
+ }
+ else if (CLASS_TYPE_P (non_reference (from_type1))
+ && same_type_p (from_type1, from_type2))
+ {
+ tree from = non_reference (from_type1);
+
+ /* [over.ics.rank]
+
+ --binding of an expression of type C to a reference of type
+ B& is better than binding an expression of type C to a
+ reference of type A&
+
+ --conversion of C to B is better than conversion of C to A, */
+ if (is_properly_derived_from (from, to_type1)
+ && is_properly_derived_from (from, to_type2))
+ {
+ if (is_properly_derived_from (to_type1, to_type2))
+ return 1;
+ else if (is_properly_derived_from (to_type2, to_type1))
+ return -1;
+ }
+ }
+ else if (CLASS_TYPE_P (non_reference (to_type1))
+ && same_type_p (to_type1, to_type2))
+ {
+ tree to = non_reference (to_type1);
+
+ /* [over.ics.rank]
+
+ --binding of an expression of type B to a reference of type
+ A& is better than binding an expression of type C to a
+ reference of type A&,
+
+ --conversion of B to A is better than conversion of C to A */
+ if (is_properly_derived_from (from_type1, to)
+ && is_properly_derived_from (from_type2, to))
+ {
+ if (is_properly_derived_from (from_type2, from_type1))
+ return 1;
+ else if (is_properly_derived_from (from_type1, from_type2))
+ return -1;
+ }
+ }
+
+ /* [over.ics.rank]
+
+ --S1 and S2 differ only in their qualification conversion and yield
+ similar types T1 and T2 (_conv.qual_), respectively, and the cv-
+ qualification signature of type T1 is a proper subset of the cv-
+ qualification signature of type T2 */
+ if (ics1->kind == ck_qual
+ && ics2->kind == ck_qual
+ && same_type_p (from_type1, from_type2))
+ {
+ int result = comp_cv_qual_signature (to_type1, to_type2);
+ if (result != 0)
+ return result;
+ }
+
+ /* [over.ics.rank]
+
+ --S1 and S2 are reference bindings (_dcl.init.ref_) and neither refers
+ to an implicit object parameter of a non-static member function
+ declared without a ref-qualifier, and either S1 binds an lvalue
+ reference to an lvalue and S2 binds an rvalue reference or S1 binds an
+ rvalue reference to an rvalue and S2 binds an lvalue reference (C++0x
+ draft standard, 13.3.3.2)
+
+ --S1 and S2 are reference bindings (_dcl.init.ref_), and the
+ types to which the references refer are the same type except for
+ top-level cv-qualifiers, and the type to which the reference
+ initialized by S2 refers is more cv-qualified than the type to
+ which the reference initialized by S1 refers.
+
+ DR 1328 [over.match.best]: the context is an initialization by
+ conversion function for direct reference binding (13.3.1.6) of a
+ reference to function type, the return type of F1 is the same kind of
+ reference (i.e. lvalue or rvalue) as the reference being initialized,
+ and the return type of F2 is not. */
+
+ if (ref_conv1 && ref_conv2)
+ {
+ if (!ref_conv1->this_p && !ref_conv2->this_p
+ && (ref_conv1->rvaluedness_matches_p
+ != ref_conv2->rvaluedness_matches_p)
+ && (same_type_p (ref_conv1->type, ref_conv2->type)
+ || (TYPE_REF_IS_RVALUE (ref_conv1->type)
+ != TYPE_REF_IS_RVALUE (ref_conv2->type))))
+ {
+ if (ref_conv1->bad_p
+ && !same_type_p (TREE_TYPE (ref_conv1->type),
+ TREE_TYPE (ref_conv2->type)))
+ /* Don't prefer a bad conversion that drops cv-quals to a bad
+ conversion with the wrong rvalueness. */
+ return 0;
+ return (ref_conv1->rvaluedness_matches_p
+ - ref_conv2->rvaluedness_matches_p);
+ }
+
+ if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
+ {
+ /* Per P0388R4:
+
+ void f (int(&)[]), // (1)
+ f (int(&)[1]), // (2)
+ f (int*); // (3)
+
+ (2) is better than (1), but (3) should be equal to (1) and to
+ (2). For that reason we don't use ck_qual for (1) which would
+ give it the cr_exact rank while (3) remains ck_identity.
+ Therefore we compare (1) and (2) here. For (1) we'll have
+
+ ck_ref_bind <- ck_identity
+ int[] & int[1]
+
+ so to handle this we must look at ref_conv. */
+ bool c1 = conv_binds_to_array_of_unknown_bound (ref_conv1);
+ bool c2 = conv_binds_to_array_of_unknown_bound (ref_conv2);
+ if (c1 && !c2)
+ return -1;
+ else if (!c1 && c2)
+ return 1;
+
+ int q1 = cp_type_quals (TREE_TYPE (ref_conv1->type));
+ int q2 = cp_type_quals (TREE_TYPE (ref_conv2->type));
+ if (ref_conv1->bad_p)
+ {
+ /* Prefer the one that drops fewer cv-quals. */
+ tree ftype = next_conversion (ref_conv1)->type;
+ int fquals = cp_type_quals (ftype);
+ q1 ^= fquals;
+ q2 ^= fquals;
+ }
+ return comp_cv_qualification (q2, q1);
+ }
+ }
+
+ /* [over.ics.rank]
+
+ Per CWG 1601:
+ -- A conversion that promotes an enumeration whose underlying type
+ is fixed to its underlying type is better than one that promotes to
+ the promoted underlying type, if the two are different. */
+ if (ics1->rank == cr_promotion
+ && ics2->rank == cr_promotion
+ && UNSCOPED_ENUM_P (from_type1)
+ && ENUM_FIXED_UNDERLYING_TYPE_P (from_type1)
+ && same_type_p (from_type1, from_type2))
+ {
+ tree utype = ENUM_UNDERLYING_TYPE (from_type1);
+ tree prom = type_promotes_to (from_type1);
+ if (!same_type_p (utype, prom))
+ {
+ if (same_type_p (to_type1, utype)
+ && same_type_p (to_type2, prom))
+ return 1;
+ else if (same_type_p (to_type2, utype)
+ && same_type_p (to_type1, prom))
+ return -1;
+ }
+ }
+
+ /* Neither conversion sequence is better than the other. */
+ return 0;
+}
+
+/* The source type for this standard conversion sequence. */
+
+static tree
+source_type (conversion *t)
+{
+ return strip_standard_conversion (t)->type;
+}
+
+/* Note a warning about preferring WINNER to LOSER. We do this by storing
+ a pointer to LOSER and re-running joust to produce the warning if WINNER
+ is actually used. */
+
+static void
+add_warning (struct z_candidate *winner, struct z_candidate *loser)
+{
+ candidate_warning *cw = (candidate_warning *)
+ conversion_obstack_alloc (sizeof (candidate_warning));
+ cw->loser = loser;
+ cw->next = winner->warnings;
+ winner->warnings = cw;
+}
+
+/* CAND is a constructor candidate in joust in C++17 and up. If it copies a
+ prvalue returned from a conversion function, replace CAND with the candidate
+ for the conversion and return true. Otherwise, return false. */
+
+static bool
+joust_maybe_elide_copy (z_candidate *&cand)
+{
+ tree fn = cand->fn;
+ if (!DECL_COPY_CONSTRUCTOR_P (fn) && !DECL_MOVE_CONSTRUCTOR_P (fn))
+ return false;
+ conversion *conv = cand->convs[0];
+ gcc_checking_assert (conv->kind == ck_ref_bind);
+ conv = next_conversion (conv);
+ if (conv->kind == ck_user && !TYPE_REF_P (conv->type))
+ {
+ gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
+ (conv->type, DECL_CONTEXT (fn)));
+ z_candidate *uc = conv->cand;
+ if (DECL_CONV_FN_P (uc->fn))
+ {
+ cand = uc;
+ return true;
+ }
+ }
+ return false;
+}
+
+/* True if the defining declarations of the two candidates have equivalent
+ parameters. */
+
+static bool
+cand_parms_match (z_candidate *c1, z_candidate *c2)
+{
+ tree fn1 = c1->fn;
+ tree fn2 = c2->fn;
+ if (fn1 == fn2)
+ return true;
+ if (identifier_p (fn1) || identifier_p (fn2))
+ return false;
+ /* We don't look at c1->template_decl because that's only set for primary
+ templates, not e.g. non-template member functions of class templates. */
+ tree t1 = most_general_template (fn1);
+ tree t2 = most_general_template (fn2);
+ if (t1 || t2)
+ {
+ if (!t1 || !t2)
+ return false;
+ if (t1 == t2)
+ return true;
+ fn1 = DECL_TEMPLATE_RESULT (t1);
+ fn2 = DECL_TEMPLATE_RESULT (t2);
+ }
+ tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn1));
+ tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (fn2));
+ if (DECL_FUNCTION_MEMBER_P (fn1)
+ && DECL_FUNCTION_MEMBER_P (fn2)
+ && (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn1)
+ != DECL_NONSTATIC_MEMBER_FUNCTION_P (fn2)))
+ {
+ /* Ignore 'this' when comparing the parameters of a static member
+ function with those of a non-static one. */
+ parms1 = skip_artificial_parms_for (fn1, parms1);
+ parms2 = skip_artificial_parms_for (fn2, parms2);
+ }
+ return compparms (parms1, parms2);
+}
+
+/* Compare two candidates for overloading as described in
+ [over.match.best]. Return values:
+
+ 1: cand1 is better than cand2
+ -1: cand2 is better than cand1
+ 0: cand1 and cand2 are indistinguishable */
+
+static int
+joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn,
+ tsubst_flags_t complain)
+{
+ int winner = 0;
+ int off1 = 0, off2 = 0;
+ size_t i;
+ size_t len;
+
+ /* Candidates that involve bad conversions are always worse than those
+ that don't. */
+ if (cand1->viable > cand2->viable)
+ return 1;
+ if (cand1->viable < cand2->viable)
+ return -1;
+
+ /* If we have two pseudo-candidates for conversions to the same type,
+ or two candidates for the same function, arbitrarily pick one. */
+ if (cand1->fn == cand2->fn
+ && cand1->reversed () == cand2->reversed ()
+ && (IS_TYPE_OR_DECL_P (cand1->fn)))
+ return 1;
+
+ /* Prefer a non-deleted function over an implicitly deleted move
+ constructor or assignment operator. This differs slightly from the
+ wording for issue 1402 (which says the move op is ignored by overload
+ resolution), but this way produces better error messages. */
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_DELETED_FN (cand1->fn) != DECL_DELETED_FN (cand2->fn))
+ {
+ if (DECL_DELETED_FN (cand1->fn) && DECL_DEFAULTED_FN (cand1->fn)
+ && move_fn_p (cand1->fn))
+ return -1;
+ if (DECL_DELETED_FN (cand2->fn) && DECL_DEFAULTED_FN (cand2->fn)
+ && move_fn_p (cand2->fn))
+ return 1;
+ }
+
+ /* a viable function F1
+ is defined to be a better function than another viable function F2 if
+ for all arguments i, ICSi(F1) is not a worse conversion sequence than
+ ICSi(F2), and then */
+
+ /* for some argument j, ICSj(F1) is a better conversion sequence than
+ ICSj(F2) */
+
+ /* For comparing static and non-static member functions, we ignore
+ the implicit object parameter of the non-static function. The
+ standard says to pretend that the static function has an object
+ parm, but that won't work with operator overloading. */
+ len = cand1->num_convs;
+ if (len != cand2->num_convs)
+ {
+ int static_1 = DECL_STATIC_FUNCTION_P (cand1->fn);
+ int static_2 = DECL_STATIC_FUNCTION_P (cand2->fn);
+
+ if (DECL_CONSTRUCTOR_P (cand1->fn)
+ && is_list_ctor (cand1->fn) != is_list_ctor (cand2->fn))
+ /* We're comparing a near-match list constructor and a near-match
+ non-list constructor. Just treat them as unordered. */
+ return 0;
+
+ gcc_assert (static_1 != static_2);
+
+ if (static_1)
+ off2 = 1;
+ else
+ {
+ off1 = 1;
+ --len;
+ }
+ }
+
+ /* Handle C++17 copy elision in [over.match.ctor] (direct-init) context. The
+ standard currently says that only constructors are candidates, but if one
+ copies a prvalue returned by a conversion function we want to treat the
+ conversion as the candidate instead.
+
+ Clang does something similar, as discussed at
+ http://lists.isocpp.org/core/2017/10/3166.php
+ http://lists.isocpp.org/core/2019/03/5721.php */
+ int elided_tiebreaker = 0;
+ if (len == 1 && cxx_dialect >= cxx17
+ && DECL_P (cand1->fn)
+ && DECL_COMPLETE_CONSTRUCTOR_P (cand1->fn)
+ && !(cand1->flags & LOOKUP_ONLYCONVERTING))
+ {
+ bool elided1 = joust_maybe_elide_copy (cand1);
+ bool elided2 = joust_maybe_elide_copy (cand2);
+ /* As a tiebreaker below we will prefer a constructor to a conversion
+ operator exposed this way. */
+ elided_tiebreaker = elided2 - elided1;
+ }
+
+ for (i = 0; i < len; ++i)
+ {
+ conversion *t1 = cand1->convs[i + off1];
+ conversion *t2 = cand2->convs[i + off2];
+ int comp = compare_ics (t1, t2);
+
+ if (comp != 0)
+ {
+ if ((complain & tf_warning)
+ && warn_sign_promo
+ && (CONVERSION_RANK (t1) + CONVERSION_RANK (t2)
+ == cr_std + cr_promotion)
+ && t1->kind == ck_std
+ && t2->kind == ck_std
+ && TREE_CODE (t1->type) == INTEGER_TYPE
+ && TREE_CODE (t2->type) == INTEGER_TYPE
+ && (TYPE_PRECISION (t1->type)
+ == TYPE_PRECISION (t2->type))
+ && (TYPE_UNSIGNED (next_conversion (t1)->type)
+ || (TREE_CODE (next_conversion (t1)->type)
+ == ENUMERAL_TYPE)))
+ {
+ tree type = next_conversion (t1)->type;
+ tree type1, type2;
+ struct z_candidate *w, *l;
+ if (comp > 0)
+ type1 = t1->type, type2 = t2->type,
+ w = cand1, l = cand2;
+ else
+ type1 = t2->type, type2 = t1->type,
+ w = cand2, l = cand1;
+
+ if (warn)
+ {
+ warning (OPT_Wsign_promo, "passing %qT chooses %qT over %qT",
+ type, type1, type2);
+ warning (OPT_Wsign_promo, " in call to %qD", w->fn);
+ }
+ else
+ add_warning (w, l);
+ }
+
+ if (winner && comp != winner)
+ {
+ /* Ambiguity between normal and reversed comparison operators
+ with the same parameter types; prefer the normal one. */
+ if ((cand1->reversed () != cand2->reversed ())
+ && cand_parms_match (cand1, cand2))
+ return cand1->reversed () ? -1 : 1;
+
+ winner = 0;
+ goto tweak;
+ }
+ winner = comp;
+ }
+ }
+
+ /* warn about confusing overload resolution for user-defined conversions,
+ either between a constructor and a conversion op, or between two
+ conversion ops. */
+ if ((complain & tf_warning)
+ /* In C++17, the constructor might have been elided, which means that
+ an originally null ->second_conv could become non-null. */
+ && winner && warn_conversion && cand1->second_conv && cand2->second_conv
+ && (!DECL_CONSTRUCTOR_P (cand1->fn) || !DECL_CONSTRUCTOR_P (cand2->fn))
+ && winner != compare_ics (cand1->second_conv, cand2->second_conv))
+ {
+ struct z_candidate *w, *l;
+ bool give_warning = false;
+
+ if (winner == 1)
+ w = cand1, l = cand2;
+ else
+ w = cand2, l = cand1;
+
+ /* We don't want to complain about `X::operator T1 ()'
+ beating `X::operator T2 () const', when T2 is a no less
+ cv-qualified version of T1. */
+ if (DECL_CONTEXT (w->fn) == DECL_CONTEXT (l->fn)
+ && !DECL_CONSTRUCTOR_P (w->fn) && !DECL_CONSTRUCTOR_P (l->fn))
+ {
+ tree t = TREE_TYPE (TREE_TYPE (l->fn));
+ tree f = TREE_TYPE (TREE_TYPE (w->fn));
+
+ if (TREE_CODE (t) == TREE_CODE (f) && INDIRECT_TYPE_P (t))
+ {
+ t = TREE_TYPE (t);
+ f = TREE_TYPE (f);
+ }
+ if (!comp_ptr_ttypes (t, f))
+ give_warning = true;
+ }
+ else
+ give_warning = true;
+
+ if (!give_warning)
+ /*NOP*/;
+ else if (warn)
+ {
+ tree source = source_type (w->convs[0]);
+ if (INDIRECT_TYPE_P (source))
+ source = TREE_TYPE (source);
+ auto_diagnostic_group d;
+ if (warning (OPT_Wconversion, "choosing %qD over %qD", w->fn, l->fn)
+ && warning (OPT_Wconversion, " for conversion from %qH to %qI",
+ source, w->second_conv->type))
+ {
+ inform (input_location, " because conversion sequence "
+ "for the argument is better");
+ }
+ }
+ else
+ add_warning (w, l);
+ }
+
+ if (winner)
+ return winner;
+
+ /* Put this tiebreaker first, so that we don't try to look at second_conv of
+ a constructor candidate that doesn't have one. */
+ if (elided_tiebreaker)
+ return elided_tiebreaker;
+
+ /* DR 495 moved this tiebreaker above the template ones. */
+ /* or, if not that,
+ the context is an initialization by user-defined conversion (see
+ _dcl.init_ and _over.match.user_) and the standard conversion
+ sequence from the return type of F1 to the destination type (i.e.,
+ the type of the entity being initialized) is a better conversion
+ sequence than the standard conversion sequence from the return type
+ of F2 to the destination type. */
+
+ if (cand1->second_conv)
+ {
+ winner = compare_ics (cand1->second_conv, cand2->second_conv);
+ if (winner)
+ return winner;
+ }
+
+ /* or, if not that,
+ F1 is a non-template function and F2 is a template function
+ specialization. */
+
+ if (!cand1->template_decl && cand2->template_decl)
+ return 1;
+ else if (cand1->template_decl && !cand2->template_decl)
+ return -1;
+
+ /* or, if not that,
+ F1 and F2 are template functions and the function template for F1 is
+ more specialized than the template for F2 according to the partial
+ ordering rules. */
+
+ if (cand1->template_decl && cand2->template_decl)
+ {
+ winner = more_specialized_fn
+ (TI_TEMPLATE (cand1->template_decl),
+ TI_TEMPLATE (cand2->template_decl),
+ /* [temp.func.order]: The presence of unused ellipsis and default
+ arguments has no effect on the partial ordering of function
+ templates. add_function_candidate() will not have
+ counted the "this" argument for constructors. */
+ cand1->num_convs + DECL_CONSTRUCTOR_P (cand1->fn));
+ if (winner)
+ return winner;
+ }
+
+ /* Concepts: F1 and F2 are non-template functions with the same
+ parameter-type-lists, and F1 is more constrained than F2 according to the
+ partial ordering of constraints described in 13.5.4. */
+
+ if (flag_concepts && DECL_P (cand1->fn) && DECL_P (cand2->fn)
+ && !cand1->template_decl && !cand2->template_decl
+ && cand_parms_match (cand1, cand2))
+ {
+ winner = more_constrained (cand1->fn, cand2->fn);
+ if (winner)
+ return winner;
+ }
+
+ /* F2 is a rewritten candidate (12.4.1.2) and F1 is not, or F1 and F2 are
+ rewritten candidates, and F2 is a synthesized candidate with reversed
+ order of parameters and F1 is not. */
+ if (cand1->rewritten ())
+ {
+ if (!cand2->rewritten ())
+ return -1;
+ if (!cand1->reversed () && cand2->reversed ())
+ return 1;
+ if (cand1->reversed () && !cand2->reversed ())
+ return -1;
+ }
+ else if (cand2->rewritten ())
+ return 1;
+
+ /* F1 is generated from a deduction-guide (13.3.1.8) and F2 is not */
+ if (deduction_guide_p (cand1->fn))
+ {
+ gcc_assert (deduction_guide_p (cand2->fn));
+ /* We distinguish between candidates from an explicit deduction guide and
+ candidates built from a constructor based on DECL_ARTIFICIAL. */
+ int art1 = DECL_ARTIFICIAL (cand1->fn);
+ int art2 = DECL_ARTIFICIAL (cand2->fn);
+ if (art1 != art2)
+ return art2 - art1;
+
+ if (art1)
+ {
+ /* Prefer the special copy guide over a declared copy/move
+ constructor. */
+ if (copy_guide_p (cand1->fn))
+ return 1;
+ if (copy_guide_p (cand2->fn))
+ return -1;
+
+ /* Prefer a candidate generated from a non-template constructor. */
+ int tg1 = template_guide_p (cand1->fn);
+ int tg2 = template_guide_p (cand2->fn);
+ if (tg1 != tg2)
+ return tg2 - tg1;
+ }
+ }
+
+ /* F1 is a member of a class D, F2 is a member of a base class B of D, and
+ for all arguments the corresponding parameters of F1 and F2 have the same
+ type (CWG 2273/2277). */
+ if (DECL_P (cand1->fn) && DECL_CLASS_SCOPE_P (cand1->fn)
+ && !DECL_CONV_FN_P (cand1->fn)
+ && DECL_P (cand2->fn) && DECL_CLASS_SCOPE_P (cand2->fn)
+ && !DECL_CONV_FN_P (cand2->fn))
+ {
+ tree base1 = DECL_CONTEXT (strip_inheriting_ctors (cand1->fn));
+ tree base2 = DECL_CONTEXT (strip_inheriting_ctors (cand2->fn));
+
+ bool used1 = false;
+ bool used2 = false;
+ if (base1 == base2)
+ /* No difference. */;
+ else if (DERIVED_FROM_P (base1, base2))
+ used1 = true;
+ else if (DERIVED_FROM_P (base2, base1))
+ used2 = true;
+
+ if (int diff = used2 - used1)
+ {
+ for (i = 0; i < len; ++i)
+ {
+ conversion *t1 = cand1->convs[i + off1];
+ conversion *t2 = cand2->convs[i + off2];
+ if (!same_type_p (t1->type, t2->type))
+ break;
+ }
+ if (i == len)
+ return diff;
+ }
+ }
+
+ /* Check whether we can discard a builtin candidate, either because we
+ have two identical ones or matching builtin and non-builtin candidates.
+
+ (Pedantically in the latter case the builtin which matched the user
+ function should not be added to the overload set, but we spot it here.
+
+ [over.match.oper]
+ ... the builtin candidates include ...
+ - do not have the same parameter type list as any non-template
+ non-member candidate. */
+
+ if (identifier_p (cand1->fn) || identifier_p (cand2->fn))
+ {
+ for (i = 0; i < len; ++i)
+ if (!same_type_p (cand1->convs[i]->type,
+ cand2->convs[i]->type))
+ break;
+ if (i == cand1->num_convs)
+ {
+ if (cand1->fn == cand2->fn)
+ /* Two built-in candidates; arbitrarily pick one. */
+ return 1;
+ else if (identifier_p (cand1->fn))
+ /* cand1 is built-in; prefer cand2. */
+ return -1;
+ else
+ /* cand2 is built-in; prefer cand1. */
+ return 1;
+ }
+ }
+
+ /* For candidates of a multi-versioned function, make the version with
+ the highest priority win. This version will be checked for dispatching
+ first. If this version can be inlined into the caller, the front-end
+ will simply make a direct call to this function. */
+
+ if (TREE_CODE (cand1->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand1->fn)
+ && TREE_CODE (cand2->fn) == FUNCTION_DECL
+ && DECL_FUNCTION_VERSIONED (cand2->fn))
+ {
+ tree f1 = TREE_TYPE (cand1->fn);
+ tree f2 = TREE_TYPE (cand2->fn);
+ tree p1 = TYPE_ARG_TYPES (f1);
+ tree p2 = TYPE_ARG_TYPES (f2);
+
+ /* Check if cand1->fn and cand2->fn are versions of the same function. It
+ is possible that cand1->fn and cand2->fn are function versions but of
+ different functions. Check types to see if they are versions of the same
+ function. */
+ if (compparms (p1, p2)
+ && same_type_p (TREE_TYPE (f1), TREE_TYPE (f2)))
+ {
+ /* Always make the version with the higher priority, more
+ specialized, win. */
+ gcc_assert (targetm.compare_version_priority);
+ if (targetm.compare_version_priority (cand1->fn, cand2->fn) >= 0)
+ return 1;
+ else
+ return -1;
+ }
+ }
+
+ /* If the two function declarations represent the same function (this can
+ happen with declarations in multiple scopes and arg-dependent lookup),
+ arbitrarily choose one. But first make sure the default args we're
+ using match. */
+ if (DECL_P (cand1->fn) && DECL_P (cand2->fn)
+ && equal_functions (cand1->fn, cand2->fn))
+ {
+ tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (cand1->fn));
+ tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (cand2->fn));
+
+ gcc_assert (!DECL_CONSTRUCTOR_P (cand1->fn));
+
+ for (i = 0; i < len; ++i)
+ {
+ /* Don't crash if the fn is variadic. */
+ if (!parms1)
+ break;
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ if (off1)
+ parms1 = TREE_CHAIN (parms1);
+ else if (off2)
+ parms2 = TREE_CHAIN (parms2);
+
+ for (; parms1; ++i)
+ {
+ if (!cp_tree_equal (TREE_PURPOSE (parms1),
+ TREE_PURPOSE (parms2)))
+ {
+ if (warn)
+ {
+ if (complain & tf_error)
+ {
+ auto_diagnostic_group d;
+ if (permerror (input_location,
+ "default argument mismatch in "
+ "overload resolution"))
+ {
+ inform (DECL_SOURCE_LOCATION (cand1->fn),
+ " candidate 1: %q#F", cand1->fn);
+ inform (DECL_SOURCE_LOCATION (cand2->fn),
+ " candidate 2: %q#F", cand2->fn);
+ }
+ }
+ else
+ return 0;
+ }
+ else
+ add_warning (cand1, cand2);
+ break;
+ }
+ parms1 = TREE_CHAIN (parms1);
+ parms2 = TREE_CHAIN (parms2);
+ }
+
+ return 1;
+ }
+
+tweak:
+
+ /* Extension: If the worst conversion for one candidate is better than the
+ worst conversion for the other, take the first. */
+ if (!pedantic && (complain & tf_warning_or_error))
+ {
+ conversion_rank rank1 = cr_identity, rank2 = cr_identity;
+ struct z_candidate *w = 0, *l = 0;
+
+ for (i = 0; i < len; ++i)
+ {
+ if (CONVERSION_RANK (cand1->convs[i+off1]) > rank1)
+ rank1 = CONVERSION_RANK (cand1->convs[i+off1]);
+ if (CONVERSION_RANK (cand2->convs[i + off2]) > rank2)
+ rank2 = CONVERSION_RANK (cand2->convs[i + off2]);
+ }
+ if (rank1 < rank2)
+ winner = 1, w = cand1, l = cand2;
+ if (rank1 > rank2)
+ winner = -1, w = cand2, l = cand1;
+ if (winner)
+ {
+ /* Don't choose a deleted function over ambiguity. */
+ if (DECL_P (w->fn) && DECL_DELETED_FN (w->fn))
+ return 0;
+ if (warn)
+ {
+ auto_diagnostic_group d;
+ if (pedwarn (input_location, 0,
+ "ISO C++ says that these are ambiguous, even "
+ "though the worst conversion for the first is "
+ "better than the worst conversion for the second:"))
+ {
+ print_z_candidate (input_location, N_("candidate 1:"), w);
+ print_z_candidate (input_location, N_("candidate 2:"), l);
+ }
+ }
+ else
+ add_warning (w, l);
+ return winner;
+ }
+ }
+
+ gcc_assert (!winner);
+ return 0;
+}
+
+/* Given a list of candidates for overloading, find the best one, if any.
+ This algorithm has a worst case of O(2n) (winner is last), and a best
+ case of O(n/2) (totally ambiguous); much better than a sorting
+ algorithm. */
+
+static struct z_candidate *
+tourney (struct z_candidate *candidates, tsubst_flags_t complain)
+{
+ struct z_candidate *champ = candidates, *challenger;
+ int fate;
+ int champ_compared_to_predecessor = 0;
+
+ /* Walk through the list once, comparing each current champ to the next
+ candidate, knocking out a candidate or two with each comparison. */
+
+ for (challenger = champ->next; challenger; )
+ {
+ fate = joust (champ, challenger, 0, complain);
+ if (fate == 1)
+ challenger = challenger->next;
+ else
+ {
+ if (fate == 0)
+ {
+ champ = challenger->next;
+ if (champ == 0)
+ return NULL;
+ champ_compared_to_predecessor = 0;
+ }
+ else
+ {
+ champ = challenger;
+ champ_compared_to_predecessor = 1;
+ }
+
+ challenger = champ->next;
+ }
+ }
+
+ /* Make sure the champ is better than all the candidates it hasn't yet
+ been compared to. */
+
+ for (challenger = candidates;
+ challenger != champ
+ && !(champ_compared_to_predecessor && challenger->next == champ);
+ challenger = challenger->next)
+ {
+ fate = joust (champ, challenger, 0, complain);
+ if (fate != 1)
+ return NULL;
+ }
+
+ return champ;
+}
+
+/* Returns nonzero if things of type FROM can be converted to TO. */
+
+bool
+can_convert (tree to, tree from, tsubst_flags_t complain)
+{
+ tree arg = NULL_TREE;
+ /* implicit_conversion only considers user-defined conversions
+ if it has an expression for the call argument list. */
+ if (CLASS_TYPE_P (from) || CLASS_TYPE_P (to))
+ arg = build_stub_object (from);
+ return can_convert_arg (to, from, arg, LOOKUP_IMPLICIT, complain);
+}
+
+/* Returns nonzero if things of type FROM can be converted to TO with a
+ standard conversion. */
+
+bool
+can_convert_standard (tree to, tree from, tsubst_flags_t complain)
+{
+ return can_convert_arg (to, from, NULL_TREE, LOOKUP_IMPLICIT, complain);
+}
+
+/* Returns nonzero if ARG (of type FROM) can be converted to TO. */
+
+bool
+can_convert_arg (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *t;
+ void *p;
+ bool ok_p;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+ /* We want to discard any access checks done for this test,
+ as we might not be in the appropriate access context and
+ we'll do the check again when we actually perform the
+ conversion. */
+ push_deferring_access_checks (dk_deferred);
+
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ flags, complain);
+ ok_p = (t && !t->bad_p);
+
+ /* Discard the access checks now. */
+ pop_deferring_access_checks ();
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return ok_p;
+}
+
+/* Like can_convert_arg, but allows dubious conversions as well. */
+
+bool
+can_convert_arg_bad (tree to, tree from, tree arg, int flags,
+ tsubst_flags_t complain)
+{
+ conversion *t;
+ void *p;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+ /* Try to perform the conversion. */
+ t = implicit_conversion (to, from, arg, /*c_cast_p=*/false,
+ flags, complain);
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return t != NULL;
+}
+
+/* Convert EXPR to TYPE. Return the converted expression.
+
+ Note that we allow bad conversions here because by the time we get to
+ this point we are committed to doing the conversion. If we end up
+ doing a bad conversion, convert_like will complain. */
+
+tree
+perform_implicit_conversion_flags (tree type, tree expr,
+ tsubst_flags_t complain, int flags)
+{
+ conversion *conv;
+ void *p;
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+
+ if (TYPE_REF_P (type))
+ expr = mark_lvalue_use (expr);
+ else
+ expr = mark_rvalue_use (expr);
+
+ if (error_operand_p (expr))
+ return error_mark_node;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ /*c_cast_p=*/false,
+ flags, complain);
+
+ if (!conv)
+ {
+ if (complain & tf_error)
+ implicit_conversion_error (loc, type, expr);
+ expr = error_mark_node;
+ }
+ else if (processing_template_decl && conv->kind != ck_identity)
+ {
+ /* In a template, we are only concerned about determining the
+ type of non-dependent expressions, so we do not have to
+ perform the actual conversion. But for initializers, we
+ need to be able to perform it at instantiation
+ (or instantiate_non_dependent_expr) time. */
+ expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
+ if (!(flags & LOOKUP_ONLYCONVERTING))
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
+ if (flags & LOOKUP_NO_NARROWING)
+ IMPLICIT_CONV_EXPR_BRACED_INIT (expr) = true;
+ }
+ else
+ {
+ /* Give a conversion call the same location as expr. */
+ iloc_sentinel il (loc);
+ expr = convert_like (conv, expr, complain);
+ }
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+tree
+perform_implicit_conversion (tree type, tree expr, tsubst_flags_t complain)
+{
+ return perform_implicit_conversion_flags (type, expr, complain,
+ LOOKUP_IMPLICIT);
+}
+
+/* Convert EXPR to TYPE (as a direct-initialization) if that is
+ permitted. If the conversion is valid, the converted expression is
+ returned. Otherwise, NULL_TREE is returned, except in the case
+ that TYPE is a class type; in that case, an error is issued. If
+ C_CAST_P is true, then this direct-initialization is taking
+ place as part of a static_cast being attempted as part of a C-style
+ cast. */
+
+tree
+perform_direct_initialization_if_possible (tree type,
+ tree expr,
+ bool c_cast_p,
+ tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+ /* [dcl.init]
+
+ If the destination type is a (possibly cv-qualified) class type:
+
+ -- If the initialization is direct-initialization ...,
+ constructors are considered.
+
+ -- If overload resolution is successful, the selected constructor
+ is called to initialize the object, with the initializer expression
+ or expression-list as its argument(s).
+
+ -- Otherwise, if no constructor is viable, the destination type is
+ a (possibly cv-qualified) aggregate class A, and the initializer is
+ a parenthesized expression-list, the object is initialized as
+ follows... */
+ if (CLASS_TYPE_P (type))
+ {
+ releasing_vec args (make_tree_vector_single (expr));
+ expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
+ &args, type, LOOKUP_NORMAL, complain);
+ return build_cplus_new (type, expr, complain);
+ }
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = implicit_conversion (type, TREE_TYPE (expr), expr,
+ c_cast_p,
+ LOOKUP_NORMAL, complain);
+ if (!conv || conv->bad_p)
+ expr = NULL_TREE;
+ else if (processing_template_decl && conv->kind != ck_identity)
+ {
+ /* In a template, we are only concerned about determining the
+ type of non-dependent expressions, so we do not have to
+ perform the actual conversion. But for initializers, we
+ need to be able to perform it at instantiation
+ (or instantiate_non_dependent_expr) time. */
+ expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
+ }
+ else
+ expr = convert_like (conv, expr, NULL_TREE, 0,
+ /*issue_conversion_warnings=*/false,
+ c_cast_p, complain);
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* When initializing a reference that lasts longer than a full-expression,
+ this special rule applies:
+
+ [class.temporary]
+
+ The temporary to which the reference is bound or the temporary
+ that is the complete object to which the reference is bound
+ persists for the lifetime of the reference.
+
+ The temporaries created during the evaluation of the expression
+ initializing the reference, except the temporary to which the
+ reference is bound, are destroyed at the end of the
+ full-expression in which they are created.
+
+ In that case, we store the converted expression into a new
+ VAR_DECL in a new scope.
+
+ However, we want to be careful not to create temporaries when
+ they are not required. For example, given:
+
+ struct B {};
+ struct D : public B {};
+ D f();
+ const B& b = f();
+
+ there is no need to copy the return value from "f"; we can just
+ extend its lifetime. Similarly, given:
+
+ struct S {};
+ struct T { operator S(); };
+ T t;
+ const S& s = t;
+
+ we can extend the lifetime of the return value of the conversion
+ operator.
+
+ The next several functions are involved in this lifetime extension. */
+
+/* DECL is a VAR_DECL or FIELD_DECL whose type is a REFERENCE_TYPE. The
+ reference is being bound to a temporary. Create and return a new
+ VAR_DECL with the indicated TYPE; this variable will store the value to
+ which the reference is bound. */
+
+tree
+make_temporary_var_for_ref_to_temp (tree decl, tree type)
+{
+ tree var = create_temporary_var (type);
+
+ /* Register the variable. */
+ if (VAR_P (decl)
+ && (TREE_STATIC (decl) || CP_DECL_THREAD_LOCAL_P (decl)))
+ {
+ /* Namespace-scope or local static; give it a mangled name. */
+
+ /* If an initializer is visible to multiple translation units, those
+ translation units must agree on the addresses of the
+ temporaries. Therefore the temporaries must be given a consistent name
+ and vague linkage. The mangled name of a temporary is the name of the
+ non-temporary object in whose initializer they appear, prefixed with
+ GR and suffixed with a sequence number mangled using the usual rules
+ for a seq-id. Temporaries are numbered with a pre-order, depth-first,
+ left-to-right walk of the complete initializer. */
+ copy_linkage (var, decl);
+
+ tree name = mangle_ref_init_variable (decl);
+ DECL_NAME (var) = name;
+ SET_DECL_ASSEMBLER_NAME (var, name);
+ }
+ else
+ /* Create a new cleanup level if necessary. */
+ maybe_push_cleanup_level (type);
+
+ return pushdecl (var);
+}
+
+/* EXPR is the initializer for a variable DECL of reference or
+ std::initializer_list type. Create, push and return a new VAR_DECL
+ for the initializer so that it will live as long as DECL. Any
+ cleanup for the new variable is returned through CLEANUP, and the
+ code to initialize the new variable is returned through INITP. */
+
+static tree
+set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
+ tree *initp, tree *cond_guard)
+{
+ tree init;
+ tree type;
+ tree var;
+
+ /* Create the temporary variable. */
+ type = TREE_TYPE (expr);
+ var = make_temporary_var_for_ref_to_temp (decl, type);
+ layout_decl (var, 0);
+ /* If the rvalue is the result of a function call it will be
+ a TARGET_EXPR. If it is some other construct (such as a
+ member access expression where the underlying object is
+ itself the result of a function call), turn it into a
+ TARGET_EXPR here. It is important that EXPR be a
+ TARGET_EXPR below since otherwise the INIT_EXPR will
+ attempt to make a bitwise copy of EXPR to initialize
+ VAR. */
+ if (TREE_CODE (expr) != TARGET_EXPR)
+ expr = get_target_expr (expr);
+ else if (TREE_ADDRESSABLE (expr))
+ TREE_ADDRESSABLE (var) = 1;
+
+ if (TREE_CODE (decl) == FIELD_DECL
+ && extra_warnings && !warning_suppressed_p (decl))
+ {
+ warning (OPT_Wextra, "a temporary bound to %qD only persists "
+ "until the constructor exits", decl);
+ suppress_warning (decl);
+ }
+
+ /* Recursively extend temps in this initializer. */
+ TARGET_EXPR_INITIAL (expr)
+ = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups,
+ cond_guard);
+
+ /* Any reference temp has a non-trivial initializer. */
+ DECL_NONTRIVIALLY_INITIALIZED_P (var) = true;
+
+ /* If the initializer is constant, put it in DECL_INITIAL so we get
+ static initialization and use in constant expressions. */
+ init = maybe_constant_init (expr);
+ /* As in store_init_value. */
+ init = cp_fully_fold (init);
+ if (TREE_CONSTANT (init))
+ {
+ if (literal_type_p (type) && CP_TYPE_CONST_NON_VOLATILE_P (type))
+ {
+ /* 5.19 says that a constant expression can include an
+ lvalue-rvalue conversion applied to "a glvalue of literal type
+ that refers to a non-volatile temporary object initialized
+ with a constant expression". Rather than try to communicate
+ that this VAR_DECL is a temporary, just mark it constexpr. */
+ DECL_DECLARED_CONSTEXPR_P (var) = true;
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = true;
+ TREE_CONSTANT (var) = true;
+ TREE_READONLY (var) = true;
+ }
+ DECL_INITIAL (var) = init;
+ init = NULL_TREE;
+ }
+ else
+ /* Create the INIT_EXPR that will initialize the temporary
+ variable. */
+ init = split_nonconstant_init (var, expr);
+ if (at_function_scope_p ())
+ {
+ add_decl_expr (var);
+
+ if (TREE_STATIC (var))
+ init = add_stmt_to_compound (init, register_dtor_fn (var));
+ else
+ {
+ tree cleanup = cxx_maybe_build_cleanup (var, tf_warning_or_error);
+ if (cleanup)
+ {
+ if (cond_guard && cleanup != error_mark_node)
+ {
+ if (*cond_guard == NULL_TREE)
+ {
+ *cond_guard = build_local_temp (boolean_type_node);
+ add_decl_expr (*cond_guard);
+ tree set = cp_build_modify_expr (UNKNOWN_LOCATION,
+ *cond_guard, NOP_EXPR,
+ boolean_false_node,
+ tf_warning_or_error);
+ finish_expr_stmt (set);
+ }
+ cleanup = build3 (COND_EXPR, void_type_node,
+ *cond_guard, cleanup, NULL_TREE);
+ }
+ vec_safe_push (*cleanups, cleanup);
+ }
+ }
+
+ /* We must be careful to destroy the temporary only
+ after its initialization has taken place. If the
+ initialization throws an exception, then the
+ destructor should not be run. We cannot simply
+ transform INIT into something like:
+
+ (INIT, ({ CLEANUP_STMT; }))
+
+ because emit_local_var always treats the
+ initializer as a full-expression. Thus, the
+ destructor would run too early; it would run at the
+ end of initializing the reference variable, rather
+ than at the end of the block enclosing the
+ reference variable.
+
+ The solution is to pass back a cleanup expression
+ which the caller is responsible for attaching to
+ the statement tree. */
+ }
+ else
+ {
+ rest_of_decl_compilation (var, /*toplev=*/1, at_eof);
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+ {
+ if (CP_DECL_THREAD_LOCAL_P (var))
+ tls_aggregates = tree_cons (NULL_TREE, var,
+ tls_aggregates);
+ else
+ static_aggregates = tree_cons (NULL_TREE, var,
+ static_aggregates);
+ }
+ else
+ /* Check whether the dtor is callable. */
+ cxx_maybe_build_cleanup (var, tf_warning_or_error);
+ }
+ /* Avoid -Wunused-variable warning (c++/38958). */
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+ && VAR_P (decl))
+ TREE_USED (decl) = DECL_READ_P (decl) = true;
+
+ *initp = init;
+ return var;
+}
+
+/* Convert EXPR to the indicated reference TYPE, in a way suitable for
+ initializing a variable of that TYPE. */
+
+tree
+initialize_reference (tree type, tree expr,
+ int flags, tsubst_flags_t complain)
+{
+ conversion *conv;
+ void *p;
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+
+ if (type == error_mark_node || error_operand_p (expr))
+ return error_mark_node;
+
+ /* Get the high-water mark for the CONVERSION_OBSTACK. */
+ p = conversion_obstack_alloc (0);
+
+ conv = reference_binding (type, TREE_TYPE (expr), expr, /*c_cast_p=*/false,
+ flags, complain);
+ /* If this conversion failed, we're in C++20, and we have something like
+ A& a(b) where A is an aggregate, try again, this time as A& a{b}. */
+ if ((!conv || conv->bad_p)
+ && (flags & LOOKUP_AGGREGATE_PAREN_INIT))
+ {
+ tree e = build_constructor_single (init_list_type_node, NULL_TREE, expr);
+ CONSTRUCTOR_IS_DIRECT_INIT (e) = true;
+ CONSTRUCTOR_IS_PAREN_INIT (e) = true;
+ conversion *c = reference_binding (type, TREE_TYPE (e), e,
+ /*c_cast_p=*/false, flags, complain);
+ /* If this worked, use it. */
+ if (c && !c->bad_p)
+ expr = e, conv = c;
+ }
+ if (!conv || conv->bad_p)
+ {
+ if (complain & tf_error)
+ {
+ if (conv)
+ convert_like (conv, expr, complain);
+ else if (!CP_TYPE_CONST_P (TREE_TYPE (type))
+ && !TYPE_REF_IS_RVALUE (type)
+ && !lvalue_p (expr))
+ error_at (loc, "invalid initialization of non-const reference of "
+ "type %qH from an rvalue of type %qI",
+ type, TREE_TYPE (expr));
+ else
+ error_at (loc, "invalid initialization of reference of type "
+ "%qH from expression of type %qI", type,
+ TREE_TYPE (expr));
+ }
+ return error_mark_node;
+ }
+
+ if (conv->kind == ck_ref_bind)
+ /* Perform the conversion. */
+ expr = convert_like (conv, expr, complain);
+ else if (conv->kind == ck_ambig)
+ /* We gave an error in build_user_type_conversion_1. */
+ expr = error_mark_node;
+ else
+ gcc_unreachable ();
+
+ /* Free all the conversions we allocated. */
+ obstack_free (&conversion_obstack, p);
+
+ return expr;
+}
+
+/* If *P is an xvalue expression, prevent temporary lifetime extension if it
+ gets used to initialize a reference. */
+
+static tree
+prevent_lifetime_extension (tree t)
+{
+ tree *p = &t;
+ while (TREE_CODE (*p) == COMPOUND_EXPR)
+ p = &TREE_OPERAND (*p, 1);
+ while (handled_component_p (*p))
+ p = &TREE_OPERAND (*p, 0);
+ /* Change a TARGET_EXPR from prvalue to xvalue. */
+ if (TREE_CODE (*p) == TARGET_EXPR)
+ *p = build2 (COMPOUND_EXPR, TREE_TYPE (*p), *p,
+ move (TARGET_EXPR_SLOT (*p)));
+ return t;
+}
+
+/* Subroutine of extend_ref_init_temps. Possibly extend one initializer,
+ which is bound either to a reference or a std::initializer_list. */
+
+static tree
+extend_ref_init_temps_1 (tree decl, tree init, vec<tree, va_gc> **cleanups,
+ tree *cond_guard)
+{
+ tree sub = init;
+ tree *p;
+ STRIP_NOPS (sub);
+ if (TREE_CODE (sub) == COMPOUND_EXPR)
+ {
+ TREE_OPERAND (sub, 1)
+ = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups,
+ cond_guard);
+ return init;
+ }
+ if (TREE_CODE (sub) == COND_EXPR)
+ {
+ tree cur_cond_guard = NULL_TREE;
+ if (TREE_OPERAND (sub, 1))
+ TREE_OPERAND (sub, 1)
+ = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 1), cleanups,
+ &cur_cond_guard);
+ if (cur_cond_guard)
+ {
+ tree set = cp_build_modify_expr (UNKNOWN_LOCATION, cur_cond_guard,
+ NOP_EXPR, boolean_true_node,
+ tf_warning_or_error);
+ TREE_OPERAND (sub, 1)
+ = cp_build_compound_expr (set, TREE_OPERAND (sub, 1),
+ tf_warning_or_error);
+ }
+ cur_cond_guard = NULL_TREE;
+ if (TREE_OPERAND (sub, 2))
+ TREE_OPERAND (sub, 2)
+ = extend_ref_init_temps_1 (decl, TREE_OPERAND (sub, 2), cleanups,
+ &cur_cond_guard);
+ if (cur_cond_guard)
+ {
+ tree set = cp_build_modify_expr (UNKNOWN_LOCATION, cur_cond_guard,
+ NOP_EXPR, boolean_true_node,
+ tf_warning_or_error);
+ TREE_OPERAND (sub, 2)
+ = cp_build_compound_expr (set, TREE_OPERAND (sub, 2),
+ tf_warning_or_error);
+ }
+ return init;
+ }
+ if (TREE_CODE (sub) != ADDR_EXPR)
+ return init;
+ /* Deal with binding to a subobject. */
+ for (p = &TREE_OPERAND (sub, 0);
+ TREE_CODE (*p) == COMPONENT_REF || TREE_CODE (*p) == ARRAY_REF; )
+ p = &TREE_OPERAND (*p, 0);
+ if (TREE_CODE (*p) == TARGET_EXPR)
+ {
+ tree subinit = NULL_TREE;
+ *p = set_up_extended_ref_temp (decl, *p, cleanups, &subinit, cond_guard);
+ recompute_tree_invariant_for_addr_expr (sub);
+ if (init != sub)
+ init = fold_convert (TREE_TYPE (init), sub);
+ if (subinit)
+ init = build2 (COMPOUND_EXPR, TREE_TYPE (init), subinit, init);
+ }
+ return init;
+}
+
+/* INIT is part of the initializer for DECL. If there are any
+ reference or initializer lists being initialized, extend their
+ lifetime to match that of DECL. */
+
+tree
+extend_ref_init_temps (tree decl, tree init, vec<tree, va_gc> **cleanups,
+ tree *cond_guard)
+{
+ tree type = TREE_TYPE (init);
+ if (processing_template_decl)
+ return init;
+ if (TYPE_REF_P (type))
+ init = extend_ref_init_temps_1 (decl, init, cleanups, cond_guard);
+ else
+ {
+ tree ctor = init;
+ if (TREE_CODE (ctor) == TARGET_EXPR)
+ ctor = TARGET_EXPR_INITIAL (ctor);
+ if (TREE_CODE (ctor) == CONSTRUCTOR)
+ {
+ /* [dcl.init] When initializing an aggregate from a parenthesized list
+ of values... a temporary object bound to a reference does not have
+ its lifetime extended. */
+ if (CONSTRUCTOR_IS_PAREN_INIT (ctor))
+ return init;
+
+ if (is_std_init_list (type))
+ {
+ /* The temporary array underlying a std::initializer_list
+ is handled like a reference temporary. */
+ tree array = CONSTRUCTOR_ELT (ctor, 0)->value;
+ array = extend_ref_init_temps_1 (decl, array, cleanups,
+ cond_guard);
+ CONSTRUCTOR_ELT (ctor, 0)->value = array;
+ }
+ else
+ {
+ unsigned i;
+ constructor_elt *p;
+ vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
+ FOR_EACH_VEC_SAFE_ELT (elts, i, p)
+ p->value = extend_ref_init_temps (decl, p->value, cleanups,
+ cond_guard);
+ }
+ recompute_constructor_flags (ctor);
+ if (decl_maybe_constant_var_p (decl) && TREE_CONSTANT (ctor))
+ DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
+ }
+ }
+
+ return init;
+}
+
+/* Returns true iff an initializer for TYPE could contain temporaries that
+ need to be extended because they are bound to references or
+ std::initializer_list. */
+
+bool
+type_has_extended_temps (tree type)
+{
+ type = strip_array_types (type);
+ if (TYPE_REF_P (type))
+ return true;
+ if (CLASS_TYPE_P (type))
+ {
+ if (is_std_init_list (type))
+ return true;
+ for (tree f = next_initializable_field (TYPE_FIELDS (type));
+ f; f = next_initializable_field (DECL_CHAIN (f)))
+ if (type_has_extended_temps (TREE_TYPE (f)))
+ return true;
+ }
+ return false;
+}
+
+/* Returns true iff TYPE is some variant of std::initializer_list. */
+
+bool
+is_std_init_list (tree type)
+{
+ if (!TYPE_P (type))
+ return false;
+ if (cxx_dialect == cxx98)
+ return false;
+ /* Look through typedefs. */
+ type = TYPE_MAIN_VARIANT (type);
+ return (CLASS_TYPE_P (type)
+ && CP_TYPE_CONTEXT (type) == std_node
+ && init_list_identifier == DECL_NAME (TYPE_NAME (type)));
+}
+
+/* Returns true iff DECL is a list constructor: i.e. a constructor which
+ will accept an argument list of a single std::initializer_list<T>. */
+
+bool
+is_list_ctor (tree decl)
+{
+ tree args = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree arg;
+
+ if (!args || args == void_list_node)
+ return false;
+
+ arg = non_reference (TREE_VALUE (args));
+ if (!is_std_init_list (arg))
+ return false;
+
+ args = TREE_CHAIN (args);
+
+ if (args && args != void_list_node && !TREE_PURPOSE (args))
+ /* There are more non-defaulted parms. */
+ return false;
+
+ return true;
+}
+
+#include "gt-cp-call.h"