<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - Clang incorrectly throws -Wtautological-constant-out-of-range-compare with enums"
href="http://llvm.org/bugs/show_bug.cgi?id=16154">16154</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>Clang incorrectly throws -Wtautological-constant-out-of-range-compare with enums
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>Frontend
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>tc+llvm@traviscross.com
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>Given this code:
#include <stdlib.h>
#include <stdio.h>
typedef enum {
alpha=0, bravo, charlie, delta, echo
} named_t;
int main(int argc, char **argv) {
named_t foo=alpha;
if (argc < 2) {
fprintf(stderr,"%s","usage: <int>\n");
return 1;
}
foo = atoi(argv[1]);
printf("foo is %d\n", foo);
if (foo > 42)
printf("foo is larger than life!\n");
return 0;
}
Clang warns as follows:
$ /usr/src/llvm/Release+Asserts/bin/clang -o test 20130527-clang-enum-test.c
20130527-clang-enum-test.c:16:11: warning: comparison of constant 42 with
expression of type 'named_t' is always false
[-Wtautological-constant-out-of-range-compare]
if (foo > 42)
~~~ ^ ~~
1 warning generated.
Clang seems to be proposing that the comparison is tautological -- in
this case, that it will always be false. Clearly, however, this is
not true:
$ ./test 84
foo is 84
foo is larger than life!
Only if you pass -Wsign-conversion, clang will tell you about what
breaks its own proposition in this case:
$ /usr/src/llvm/src/Release+Asserts/bin/clang -Wsign-conversion -o test
20130527-clang-enum-test.c
20130527-clang-enum-test.c:14:9: warning: implicit conversion changes
signedness: 'int' to 'named_t' [-Wsign-conversion]
foo = atoi(argv[1]);
~ ^~~~~~~~~~~~~
20130527-clang-enum-test.c:16:11: warning: comparison of constant 42 with
expression of type 'named_t' is always false
[-Wtautological-constant-out-of-range-compare]
if (foo > 42)
~~~ ^ ~~
2 warnings generated.
...but even this can be thwarted:
#include <stdlib.h>
#include <stdio.h>
typedef enum {
alpha=0, bravo, charlie, delta, echo
} named_t;
int main() {
named_t foo=echo;
foo *= 4;
printf("foo is %d\n", foo);
if (foo > 8) printf("foo is larger than 8!\n");
return 0;
}
$ /usr/src/llvm/src/Release+Asserts/bin/clang -Weverything -o test
20130527-clang-enum-test2.c
20130527-clang-enum-test2.c:12:11: warning: comparison of constant 8 with
expression of type 'named_t' is always false
[-Wtautological-constant-out-of-range-compare]
if (foo > 8) printf("foo is larger than 8!\n");
~~~ ^ ~
1 warning generated.
$ ./test
foo is 16
foo is larger than 8!
...leaving an incorrect warning with no other warning to hint at where
the compiler's assumptions were broken.
People often believe the compiler's static analyzer when it says
something is tautological, so we shouldn't tell people a comparison
can't go the other way unless it really cannot.
[Tested with clang/LLVM fresh from git.]</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>