[LLVMbugs] [Bug 16154] New: Clang incorrectly throws -Wtautological-constant-out-of-range-compare with enums

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon May 27 11:39:59 PDT 2013


http://llvm.org/bugs/show_bug.cgi?id=16154

            Bug ID: 16154
           Summary: Clang incorrectly throws
                    -Wtautological-constant-out-of-range-compare with
                    enums
           Product: clang
           Version: trunk
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: Frontend
          Assignee: unassignedclangbugs at nondot.org
          Reporter: tc+llvm at traviscross.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

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.]

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20130527/20903787/attachment.html>


More information about the llvm-bugs mailing list