[Bug 265181] Strange C++ error on armv6: it can't implicitly convert integer to float

From: <bugzilla-noreply_at_freebsd.org>
Date: Wed, 13 Jul 2022 03:33:44 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=265181

Mark Millard <marklmi26-fbsd@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |marklmi26-fbsd@yahoo.com

--- Comment #1 from Mark Millard <marklmi26-fbsd@yahoo.com> ---
(In reply to Yuri Victorovich from comment #0)

The port does a patch that involves:

@@ -983,7 +991,7 @@ char *Alsa_pcmi::play_floatre (const float *src, char
     while (nfrm--)
     {
         d = *src;
-        *((float *) dst) = __bswap_32 (d);
+        *((float *) dst) = bswap_32 (d);
         dst += _play_step;
         src += step;
     }
@@ -1105,7 +1113,7 @@ const char *Alsa_pcmi::capt_floatre (const char *src,
     while (nfrm--)
     {
         d = *((float *) src);
-        *dst = __bswap_32 (d);
+        *dst = bswap_32 (d);
         dst += step;
         src += _capt_step;
     }

I'll use Alsa_pcmi::play_floatre as the example to
carry my points.

The complaint is about (after expansion  but with
some text replaced by "MORE_NOT_SHOWN"):

*((float *) dst) = ((((d) & 0xff000000U) >> 24) | MORE_NOT_SHOWN

via:

zita-alsa-pcmi.cc:994:28: error: invalid operands to binary expression ('float'
and 'unsigned int')
        *((float *) dst) = bswap_32 (d);
                           ^~~~~~~~~~~~
/usr/include/infiniband/byteswap.h:39:25: note: expanded from macro 'bswap_32'
#define bswap_32        bswap32
                        ^
/usr/include/sys/endian.h:62:20: note: expanded from macro 'bswap32'
#define bswap32(x)      __bswap32(x)
                        ^~~~~~~~~~~~
/usr/include/machine/endian.h:134:6: note: expanded from macro '__bswap32'
     __bswap32_constant(x) :                    \
     ^~~~~~~~~~~~~~~~~~~~~
/usr/include/machine/endian.h:118:12: note: expanded from macro
'__bswap32_constant'
    ((((x) & 0xff000000U) >> 24) |      \
       ~~~ ^ ~~~~~~~~~~~

But the original unpatched code is (note the type of d):

char *Alsa_pcmi::play_floatre (const float *src, char *dst, int nfrm, int step)
{
    float d;

    while (nfrm--)
    {
        d = *src;
        *((float *) dst) = __bswap_32 (d);
        dst += _play_step;
        src += step;
    }
    return dst;
}

So the end result after patching and expanding
looks like:

char *Alsa_pcmi::play_floatre (const float *src, char *dst, int nfrm, int step)
{
    float d;

    while (nfrm--)
    {
        d = *src;
        *((float *) dst) = ((((d) & 0xff000000U) >> 24) | MORE_NOT_SHOWN;
        dst += _play_step;
        src += step;
    }
    return dst;
}

So d is if type float.

So (d) is of type float.

So (d) & 0xff000000U has & taking a mix of float on the left
and unsigned int on the right. This is what the complaint is
about.

This is not an example of integer converting to float. For
& the language rules are:

QUOTE
The operands shall be of integral or unscoped enumeration type.
The usual arithmetic conversions (7.4) are performed.
END QUOTE

The rule in 7.4 relative to float is:

QUOTE (after scoped enumeration, long double, and double for "either operand"):
Otherwise, if either operand is float, the other shall be converted to float.
END QUOTE

Thus (d) & 0xff000000U turns into:

(d) & static_cast<float>(0xff000000U)

And then neither operand is an "integral or unscoped enumeration
type". Thus the reported error.

Looks like a correct message to me.

-- 
You are receiving this mail because:
You are the assignee for the bug.