[LLVMbugs] [Bug 20158] New: std::numeric_limits<signed T>::is_modulo set even without -fwrapv

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Sat Jun 28 23:15:30 PDT 2014


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

            Bug ID: 20158
           Summary: std::numeric_limits<signed T>::is_modulo set even
                    without -fwrapv
           Product: libc++
           Version: 3.4
          Hardware: Macintosh
                OS: MacOS X
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: myriachan at gmail.com
                CC: llvmbugs at cs.uiuc.edu, mclow.lists at gmail.com
    Classification: Unclassified

std::numeric_limits<signed T>::is_modulo is true for integral types T when it
should not be, due to clang considering signed integer overflow to be undefined
and making optimizations on the basis of this assumption.

The following code demonstrates this flaw (Yosemite beta, Xcode 6 beta).

#include <stdio.h>
#include <limits>

__attribute__((__noinline__))
bool WillIncrementOverflow(signed int x)
{
    return x + 1 < x;
}

extern "C" int main()
{
    static_assert(true, "use C++11 mode");
    printf("%d %d\n",
        WillIncrementOverflow((std::numeric_limits<signed int>::max)()),
        std::numeric_limits<signed int>::is_modulo);
    return 0;
}

Compile with (yes, optimizations required):
clang++ -arch x86_64 -O3 test.cpp -o test

Outputs:
0 1

If you disable optimizations or add -fwrapv:
1 1

By the language of the C++11 standard, this is in violation.  is_modulo on
signed integer types essentially indicates that the implementation considers
signed integer overflow and underflow to be well-defined, and that it wraps
essentially like you'd expect.

C++03 had a different definition for is_modulo: is_modulo indicated that a type
*may* wrap.  In C++11, is_modulo indicates that it *will* wrap, and in a
very-specific, well-defined manner.

As the above program demonstrates, clang assumes that signed integer overflow
is undefined, and so it is incorrect to set is_modulo to true on signed integer
types.  It should be false unless -fwrapv is used.  However, with the
One-Definition Rule, that is likely to cause problems if a single module has
some translation units with -fwrapv and some without.

GCC's libstdc++ solution was to always set is_modulo to false:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=22200  Visual C++ seems to
fully-define signed integer overflow/underflow, so its setting of is_modulo to
true appears to be correct.

Melissa

-- 
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/20140629/7b9cba06/attachment.html>


More information about the llvm-bugs mailing list