Bug 46457 - Bogus warning about bitwise combination of enum flags in case statement
Summary: Bogus warning about bitwise combination of enum flags in case statement
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.1
: P3 normal
Target Milestone: ---
Assignee: Jason Merrill
URL: https://gcc.gnu.org/pipermail/gcc-pat...
Keywords: diagnostic, patch
Depends on:
Blocks:
 
Reported: 2010-11-12 22:12 UTC by Ben Hutchings
Modified: 2025-01-10 17:00 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2010-11-13 00:13:35


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Hutchings 2010-11-12 22:12:51 UTC
The -Wswitch warning option is documented as resulting in warnings about "`case' labels outside the enumeration range". This appears to be a change from gcc 4.4. I have no objection to the documented behaviour, but the actual behaviour is to warn about any value that does not equal an enumerator.

It is common practice to define flags as enumerators and to combine them with the '|' operator. The C++98 standard supports this practice by requiring that the underlying type for an enumerated type must be capable of storing such bitwise combinations and zero (7.2p6).

Test case:

enum flags {
    one = 1,
    two = 2,
};

const char *f(enum flags fl)
{
    switch (fl) {
    case 0:
	return "zero";
    case one:
	return "one";
    case two:
	return "two";
    case one | two:
	return "three";
    default:
	return "bogus";
    }
}

$ c++ -c -Wall test.cc
test.cc: In function ‘const char* f(flags)’:
test.cc:9:5: warning: case value ‘0’ not in enumerated type ‘flags’
test.cc:15:5: warning: case value ‘3’ not in enumerated type ‘flags’

This also applies to the C front-end, though the C standard does not explicit specify this requirement on the underlying type (or "compatible type").
Comment 1 Jonathan Wakely 2010-11-13 00:13:35 UTC
(In reply to comment #0)
> I have no objection to the documented behaviour, but the actual
> behaviour is to warn about any value that does not equal an enumerator.

I agree this is not a helpful warning to have at -Wall, there's no requirement for the values of an enumeration to have a corresponding enumerator.

I find the "not handled in switch" warning from -Wswitch very useful, but not the "not in enumerated type" warning, they should be separate.

In any case, the documentation talks about the range of the type while the actual warning text talks about values not being "in" the enumerated type, which is not true when the value is within range of the type.
Comment 2 Eric Gallager 2024-09-04 15:29:57 UTC
Jason has a patch: https://gcc.gnu.org/pipermail/gcc-patches/2024-September/662214.html
Comment 3 GCC Commits 2024-09-06 01:41:39 UTC
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:1914ca8791ce4e0ba821e818cb6f86c76afdb6f2

commit r15-3500-g1914ca8791ce4e0ba821e818cb6f86c76afdb6f2
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Aug 29 11:09:21 2024 -0400

    c-family: add attribute flag_enum [PR81665]
    
    Several PRs complain about -Wswitch warning about a case for a bitwise
    combination of enumerators.  Clang has an attribute flag_enum to prevent
    this; let's adopt that approach as well.
    
    This also recognizes the attribute as [[clang::flag_enum]], introducing
    handling of the clang attribute namespace.
    
            PR c++/46457
            PR c++/81665
    
    gcc/c-family/ChangeLog:
    
            * c-attribs.cc (handle_flag_enum_attribute): New.
            (c_common_gnu_attributes): Add it.
            (c_common_clang_attributes, c_common_clang_attribute_table): New.
            * c-common.h: Declare c_common_clang_attribute_table.
            * c-warn.cc (c_do_switch_warnings): Handle flag_enum.
    
    gcc/c/ChangeLog:
    
            * c-objc-common.h (c_objc_attribute_table): Add
            c_common_clang_attribute_table.
    
    gcc/cp/ChangeLog:
    
            * cp-objcp-common.h (cp_objcp_attribute_table): Add
            c_common_clang_attribute_table.
    
    gcc/testsuite/ChangeLog:
    
            * c-c++-common/attr-flag-enum-1.c: New test.
    
    gcc/ChangeLog:
    
            * doc/extend.texi: Document flag_enum attribute.
            * doc/invoke.texi: Mention flag_enum in -Wswitch.
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/regex_constants.h: Use flag_enum.
Comment 4 Marek Polacek 2025-01-10 17:00:40 UTC
Fixed?