summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorHubert Tong <hubert.reinterpretcast@gmail.com>2015-06-08 21:59:59 +0000
committerHubert Tong <hubert.reinterpretcast@gmail.com>2015-06-08 21:59:59 +0000
commit13234ae40db3d89fcd05a3b59f4e3e25133c4976 (patch)
tree55a60cf1d6c497391efe9846fd158e7f3450dc0e /clang/lib/Sema/SemaExpr.cpp
parent218a9593db8b42e4df8ae22b7f1836927aa972c6 (diff)
downloadbcm5719-llvm-13234ae40db3d89fcd05a3b59f4e3e25133c4976.tar.gz
bcm5719-llvm-13234ae40db3d89fcd05a3b59f4e3e25133c4976.zip
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 llvm-svn: 239356
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index dfb17f4bbc3..b0bc231e7e6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3425,6 +3425,22 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Ty = Context.LongTy;
else if (AllowUnsigned)
Ty = Context.UnsignedLongTy;
+ // Check according to the rules of C90 6.1.3.2p5. C++03 [lex.icon]p2
+ // is compatible.
+ else if (!getLangOpts().C99 && !getLangOpts().CPlusPlus11) {
+ const unsigned LongLongSize =
+ Context.getTargetInfo().getLongLongWidth();
+ Diag(Tok.getLocation(),
+ getLangOpts().CPlusPlus
+ ? Literal.isLong
+ ? diag::warn_old_implicitly_unsigned_long_cxx
+ : /*C++98 UB*/ diag::
+ ext_old_implicitly_unsigned_long_cxx
+ : diag::warn_old_implicitly_unsigned_long)
+ << (LongLongSize > LongSize ? /*will have type 'long long'*/ 0
+ : /*will be ill-formed*/ 1);
+ Ty = Context.UnsignedLongTy;
+ }
Width = LongSize;
}
}
OpenPOWER on IntegriCloud