[libvirt] [PATCH v2 2/3] Fix more switch fallthrough identified by gcc8
Daniel P. Berrangé
berrange at redhat.com
Tue Feb 13 17:54:44 UTC 2018
On Tue, Feb 13, 2018 at 04:57:06PM +0000, Daniel P. Berrangé wrote:
> GCC 8 became more fussy/clear about detecting switch
> fallthroughs. First it doesn't like it if you have
> a fallthrough attribute that is not before a case
> statement. e.g.
>
> FOO:
> BAR:
> WIZZ:
> ATTRIBUTE_FALLTHROUGH;
>
> Is unacceptable as there's no final case statement,
> so while FOO & BAR are falling through, WIZZ is
> not falling through. IOW, GCC wants us to write
>
> FOO:
> BAR:
> ATTRIBUTE_FALLTHROUGH;
> WIZZ:
>
> Second, it will report risk of fallthrough even if you
> have a case statement for every single enum value, but
> only if the switch is nested inside another switch and
> the outer case statement has no final break. This is
> is in fact valid because despite the fact that we have
> cast from "int" to the enum typedef, nothing guarantees
> that the variable we're switching on only contains values
> that have corresponding switch labels. e.g.
>
> int domstate = 87539319;
> switch ((virDomainState)domstate) {
> ...
> }
>
> will not match enum value, but also not raise any kind
> of compiler warning. So it is right to complain about
> risk of fallthrough if no default: is present.
Arrrgh, and indeed we've really got such brokenness in our
code.
virDomainControllerDefNew() sets model == -1, when
qemuDomainDeviceCalculatePCIConnectFlags() is run, for the
auto-added USB controller we fallthrough to the case
statement that handles IDE. Fixing the broken fallthrough
in qemuDomainDeviceCalculatePCIConnectFlags() in turn
breaks many of the qemu test cases :-( What a horrible
mess.
This is a really strong sign that we should *never* rely
on listing all enum values in a switch() and must always
have a default: too.
Anyway NACK to this patch for now until I can figure out
how to unbreak the existing flaws.
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
> src/qemu/qemu_domain.c | 14 +++++++-------
> src/qemu/qemu_domain_address.c | 11 +++++++++++
> 2 files changed, 18 insertions(+), 7 deletions(-)
>
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index f6e28447d..e262588c3 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -175,9 +175,9 @@ qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
> case QEMU_ASYNC_JOB_NONE:
> case QEMU_ASYNC_JOB_LAST:
> ATTRIBUTE_FALLTHROUGH;
> + default:
> + return "none";
> }
> -
> - return "none";
> }
>
> int
> @@ -199,12 +199,12 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
> case QEMU_ASYNC_JOB_NONE:
> case QEMU_ASYNC_JOB_LAST:
> ATTRIBUTE_FALLTHROUGH;
> + default:
> + if (STREQ(phase, "none"))
> + return 0;
> + else
> + return -1;
> }
> -
> - if (STREQ(phase, "none"))
> - return 0;
> - else
> - return -1;
> }
>
>
> diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
> index e28119e4b..42c7c0b12 100644
> --- a/src/qemu/qemu_domain_address.c
> +++ b/src/qemu/qemu_domain_address.c
> @@ -532,6 +532,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB2: /* xen only */
> case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE:
> case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST:
> + default:
> return 0;
> }
>
> @@ -553,6 +554,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> return pciFlags;
>
> case VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST:
> + default:
> return 0;
> }
>
> @@ -562,6 +564,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_CONTROLLER_TYPE_FDC:
> case VIR_DOMAIN_CONTROLLER_TYPE_CCID:
> case VIR_DOMAIN_CONTROLLER_TYPE_LAST:
> + default:
> /* should be 0 */
> return pciFlags;
> }
> @@ -605,6 +608,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_SOUND_MODEL_PCSPK:
> case VIR_DOMAIN_SOUND_MODEL_USB:
> case VIR_DOMAIN_SOUND_MODEL_LAST:
> + default:
> return 0;
> }
>
> @@ -622,6 +626,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_DISK_BUS_SATA:
> case VIR_DOMAIN_DISK_BUS_SD:
> case VIR_DOMAIN_DISK_BUS_LAST:
> + default:
> return 0;
> }
>
> @@ -734,6 +739,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_MEMBALLOON_MODEL_XEN:
> case VIR_DOMAIN_MEMBALLOON_MODEL_NONE:
> case VIR_DOMAIN_MEMBALLOON_MODEL_LAST:
> + default:
> return 0;
> }
>
> @@ -743,6 +749,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> return virtioFlags;
>
> case VIR_DOMAIN_RNG_MODEL_LAST:
> + default:
> return 0;
> }
>
> @@ -755,6 +762,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_WATCHDOG_MODEL_IB700:
> case VIR_DOMAIN_WATCHDOG_MODEL_DIAG288:
> case VIR_DOMAIN_WATCHDOG_MODEL_LAST:
> + default:
> return 0;
> }
>
> @@ -775,6 +783,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_VIDEO_TYPE_DEFAULT:
> case VIR_DOMAIN_VIDEO_TYPE_GOP:
> case VIR_DOMAIN_VIDEO_TYPE_LAST:
> + default:
> return 0;
> }
>
> @@ -791,6 +800,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_INPUT_BUS_XEN:
> case VIR_DOMAIN_INPUT_BUS_PARALLELS:
> case VIR_DOMAIN_INPUT_BUS_LAST:
> + default:
> return 0;
> }
>
> @@ -806,6 +816,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev,
> case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_SCLP:
> case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_NONE:
> case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_LAST:
> + default:
> return 0;
> }
>
> --
> 2.16.1
>
Regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
More information about the libvir-list
mailing list