Bug 92158 - Missed -Wsign-conversion in C++ when -1 enum converted to unsigned int
Summary: Missed -Wsign-conversion in C++ when -1 enum converted to unsigned int
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2019-10-19 14:17 UTC by Jonny Grant
Modified: 2024-03-27 08:20 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-10-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonny Grant 2019-10-19 14:17:45 UTC
Could warnings for this be added for C and C++?

I tested on godbolt trunk today 19 Oct 2019.

There isn't any warning output when 'a_t' is converted to 'int'. Or even if it was converted to an 'unsigned int'

https://gcc.gnu.org/ml/gcc-help/2019-07/msg00014.html


//-O2 -Wall -Wextra -Wconversion -Werror

#include <stddef.h>
typedef enum
{
    a = -1
} a_t;

a_t f()
{
    return a;
}

int main()
{
    int b = f();
    return b;
}
Comment 1 Jonathan Wakely 2019-10-21 10:29:28 UTC
Converting to integral types is a feature of enums, I see no reason to warn.
Comment 2 Jonathan Wakely 2019-10-21 10:32:34 UTC
At least when the sign doesn't change, i.e. for conversion to int.

Please clarify what exactly you want a warning to do.
Comment 3 Jonathan Wakely 2019-10-21 10:45:42 UTC
Your example doesn't warn with Clang or Clang++ either.
Comment 4 Jonny Grant 2019-10-22 15:40:50 UTC
Hello

Implicit conversion can introduce bugs. I would like to detect implicit enum conversions to other types in C and C++. How about just adding the C++ warnings first to match clang in example below?

The following example does produce warnings in C++ with Clang trunk, but not C. Likewise with MSVC, C++ warning, but no C warning.

G++ only warns on line (19), clang has the additional line (15) and line (17)
warnings.

Could G++ also add the additions warnings?




-O2 -Wall -Wextra -Wconversion -Werror

#include <stdio.h>

typedef enum
{
    a = -1
} a_t;

a_t f()
{
    return a;
}

int main()
{
    unsigned int b = f();

    a_t test = b;
    printf("%u %u", test, b);
    return b;
}


#1 with x86-64 clang (trunk)
<source>:15:22: error: implicit conversion changes signedness: 'a_t' to 'unsigned int' [-Werror,-Wsign-conversion]
    unsigned int b = f();
                 ~   ^~~
<source>:17:9: error: cannot initialize a variable of type 'a_t' with an lvalue of type 'unsigned int'
    a_t test = b;
        ^      ~
<source>:19:12: error: implicit conversion changes signedness: 'unsigned int' to 'int' [-Werror,-Wsign-conversion]
    return b;
    ~~~~~~ ^
3 errors generated.
Compiler returned: 1




#1 with x64 msvc v19.22
example.cpp
<source>(18): error C2440: 'initializing': cannot convert from 'unsigned int' to 'a_t'
<source>(18): note: Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)
Compiler returned: 2



x86-64 gcc (trunk) - 484ms
#1 with x86-64 gcc (trunk)
<source>: In function 'int main()':
<source>:17:16: error: invalid conversion from 'unsigned int' to 'a_t' [-fpermissive]
   17 |     a_t test = b;
      |                ^
      |                |
      |                unsigned int
Compiler returned: 1
Comment 5 Jonathan Wakely 2019-10-25 10:26:24 UTC
Thank you for the corrected testcase, although compiling with -Werror when asking for warnings is not very helpful (it obscures what's a warning and what's an error) and posting code that doesn't even compile is not very helpful either.

Confirming as a diagnostic enhancement for the following testcase:

enum E { a = -1 } ;
unsigned i = a;

Clang warns with -Wsign-conversion (not enabled by -Wall or -Wextra):

e.cc:2:14: warning: implicit conversion changes signedness: 'E' to 'unsigned int' [-Wsign-conversion]
unsigned i = a;
         ~   ^
1 warning generated.
Comment 6 Jonny Grant 2019-10-25 11:45:47 UTC
Many thanks for your reply. Would you rather I close this and create a new ticket with just your test case so it is clearer on bugzilla?

Just to note, gcc trunk shows a warning in C - but oddly g++ does not for C++

-Wsign-conversion

enum E { a = -1 } ;
unsigned i = a;


Would it be better if I re-file this ticket as implement -Wsign-conversion for C++ ?
Comment 7 Jonny Grant 2019-10-25 11:46:53 UTC
 
> Would it be better if I re-file this ticket as implement -Wsign-conversion
> for C++ ?

I mean expand -Wsign-conversion for C++ to detect the enum conversion that the same option does for C code.
Comment 8 Jonathan Wakely 2019-10-25 12:39:57 UTC
No, there's no need for a new bug.
Comment 9 Eric Gallager 2019-11-21 09:13:45 UTC
(In reply to Jonny Grant from comment #7)
>  
> > Would it be better if I re-file this ticket as implement -Wsign-conversion
> > for C++ ?
> 
> I mean expand -Wsign-conversion for C++ to detect the enum conversion that
> the same option does for C code.

(In reply to Jonathan Wakely from comment #8)
> No, there's no need for a new bug.

Retitling this one then.
Comment 10 Jonny Grant 2019-11-21 15:14:37 UTC
C++ 'enum class' gives a nice error for conversion to unsigned.

Example:

enum class E { a = 1 } ;
unsigned i = E::a;


I've asked this before, will just write again so it is on a ticket. I understand C++ allows implicit conversion of enum's, it would be good to generate a warning with the following example in C++. So I could make the conversion explicit 

enum E { a = 1 } ;
unsigned i = a;