[cfe-dev] Unsound assumptions about exhaustiveness of enum switch cases?

Stephan Bergmann via cfe-dev cfe-dev at lists.llvm.org
Fri Sep 11 04:46:31 PDT 2015


For a test.cc input of

> enum E1 { E1_0, E1_1 };
> enum E2 { E2_0, E2_1, E2_2 };
> enum class E3 { E3_0, E3_1 };
> int x;
> int f(E1 e1, E2 e2, E3 e3) {
>     int n1 = x;
>     switch (e1) {
>     case E1_0: n1 = 0; break;
>     case E1_1: n1 = 1; break;
>     }
>     int n2 = x;
>     switch (e2) {
>     case E2_0: n2 = 0; break;
>     case E2_1: n2 = 1; break;
>     case E2_2: n2 = 2; break;
>     }
>     int n3 = x;
>     switch (e3) {
>     case E3::E3_0: n3 = 0; break;
>     case E3::E3_1: n3 = 1; break;
>     }
>     return n1 + n2 + n3;
> }

(where x is needed to work around heuristics in clang-tidy when not to 
warn about redundant initializations), calling (at least for a recent 
Clang trunk build)

> clang-tidy -checks=clang-analyzer-deadcode.DeadStores test.cc -- -std=c++11

causes clang-analyzer-deadcode.DeadStores warnings about the 
initializations of all three of n1, n2, n3.  Apparently on the grounds 
that each switch statement is exhaustive.

But from my understanding of the C++ standard, the ranges of enumeration 
values for E2, E3 are such that f can legally be called with values for 
e2, e3 that are not covered by the case branches of the respective 
switches, e.g. as

> f(E1_0, E2(3), E3(std::numeric_limits<int>::max()));

Is this analysis deliberately unsound, on the assumption that objects of 
enumeration type take only enumerator values?  If yes, is it deliberate 
to do so for both scoped and unscoped enumerations?



More information about the cfe-dev mailing list