diff options
author | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-06-08 21:59:59 +0000 |
---|---|---|
committer | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-06-08 21:59:59 +0000 |
commit | b15375b3f601242d233233ccf394b1af9834ce2d (patch) | |
tree | 165dadbe2429302305793d49e4a9ff0e06259689 /include/clang/Basic/DiagnosticCommonKinds.td | |
parent | e3d3ccf99349e3087f311f2b610bdadf6851272f (diff) |
Consider unsigned long for non-u/U decimal literals (C90/C++03)
Summary:
This modifies Clang to reflect that under pre-C99 ISO C, decimal
constants may have type `unsigned long` even if they do not contain `u`
or `U` in their suffix (C90 subclause 6.1.3.2 paragraph 5). The same is
done for C++ without C++11 which--because of undefined behaviour--allows
for behaviour compatible with ISO C90 in the case of an unsuffixed
decimal literal and is otherwise identical to C90 in its treatment of
integer literals (C++03 subclause 2.13.1 [lex.icon] paragraph 2).
Messages are added to the `c99-compat` and `c++11-compat` groups to warn
on such literals, since they behave differently under the newer
standards.
Fixes PR 16678.
Test Plan:
A new test file is added to exercise both pre-C99/C++11 and C99/C++11-up
on decimal literals with no suffix or suffixes `l`/`L` for both 32-bit
and 64-bit `long`.
In the file, 2^31 (being `INT_MAX+1`) is tested for the expected type
using `__typeof__` and multiple declarations of the same entity. 2^63
is similarly tested when it is within the range of `unsigned long`.
Preprocessor arithmetic tests are added to ensure consistency given
that Clang (like GCC) uses greater than 32 bits for preprocessor
arithmetic even when `long` and `unsigned long` is 32 bits and a
pre-C99/C++11 mode is in effect.
Tests added:
test/Sema/PR16678.c
Reviewers: fraggamuffin, rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D9794
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239356 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/DiagnosticCommonKinds.td')
-rw-r--r-- | include/clang/Basic/DiagnosticCommonKinds.td | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index afdd9269d0..deb23f3149 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -115,7 +115,23 @@ def err_integer_literal_too_large : Error< def ext_integer_literal_too_large_for_signed : ExtWarn< "integer literal is too large to be represented in a signed integer type, " "interpreting as unsigned">, - InGroup<DiagGroup<"implicitly-unsigned-literal">>; + InGroup<ImplicitlyUnsignedLiteral>; +def warn_old_implicitly_unsigned_long : Warning< + "integer literal is too large to be represented in type 'long', " + "interpreting as 'unsigned long' per C89; this literal will " + "%select{have type 'long long'|be ill-formed}0 in C99 onwards">, + InGroup<C99Compat>; +def warn_old_implicitly_unsigned_long_cxx : Warning< + "integer literal is too large to be represented in type 'long', " + "interpreting as 'unsigned long' per C++98; this literal will " + "%select{have type 'long long'|be ill-formed}0 in C++11 onwards">, + InGroup<CXX11Compat>; +def ext_old_implicitly_unsigned_long_cxx : ExtWarn< + "integer literal is too large to be represented in type 'long' and is " + "subject to undefined behavior under C++98, interpreting as 'unsigned long'; " + "this literal will %select{have type 'long long'|be ill-formed}0 " + "in C++11 onwards">, + InGroup<CXX11Compat>; // SEH def err_seh_expected_handler : Error< |