Summary:
When constructing an APSInt from a string, the constructor doesn't correctly
truncate the bit width of the result if the passed in string was "0" (or any
alternative way to express 0 like "-0" or "000"). Instead of 1 (which is the
smallest allowed bit width) it returns an APSInt with a bit width of 5.
The reason is that the constructor checks that it never truncates the result to
the invalid bit width of 0, so when it calculates that storing a "0" doesn't
require any bits it just keeps the original overestimated bit width (which
happens to be 5).
This patch just sets the bit width of the result to 1 if the required bit width
is 0.
Reviewers: arphaman, dexonsmith
Reviewed By: dexonsmith
Subscribers: hiraditya, dexonsmith, JDevlieghere, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D81329
Without this patch, APSInt inherits APInt::isNegative, which merely
checks the sign bit without regard to whether the type is actually
signed. isNonNegative and isStrictlyPositive call isNegative and so
are also affected.
This patch adjusts APSInt to override isNegative, isNonNegative, and
isStrictlyPositive with implementations that consider whether the type
is signed.
A large set of Clang OpenMP tests are affected. Without this patch,
these tests assume that `true` is not a valid argument for clauses
like `collapse`. Indeed, `true` fails APInt::isStrictlyPositive but
not APSInt::isStrictlyPositive. This patch adjusts those tests to
assume `true` should be accepted.
This patch also adds tests revealing various other similar fixes due
to APSInt::isNegative calls in Clang's ExprConstant.cpp and
SemaExpr.cpp: `++` and `--` overflow in `constexpr`, evaluated object
size based on `alloc_size`, `<<` and `>>` shift count validation, and
OpenMP array section validation.
Reviewed By: lebedev.ri, ABataev, hfinkel
Differential Revision: https://reviews.llvm.org/D59712
llvm-svn: 359012
to reflect the new license.
We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.
llvm-svn: 351636
This commit moves the APSInt initialization code that's used by
the LLLexer class into a new APSInt constructor that constructs
APSInts from strings.
This change is useful for MIR Serialization, as it would allow
the MILexer class to use the same APSInt initialization as
LLexer when parsing immediate machine operands.
llvm-svn: 240436
Add some API to `APSInt` to make it easier to compare with `int64_t`.
- `APSInt::compareValues(APSInt, APSInt)` returns 1, -1 or 0 for
greater, lesser, or equal, doing the right thing for mismatched
"has-sign" and bitwidths. This is just like `isSameValue()` (and is
now the implementation of it).
- `APSInt::get(int64_t)` gets a signed `APSInt`.
- `operator<(int64_t)`, etc., are implemented trivially via `get()`
and `compareValues()`.
- Also added `APSInt::getUnsigned(uint64_t)` to make it easier to test
`compareValues()`.
llvm-svn: 228239
The interaction between defaulted operators and move elision isn't
totally obvious, add a unit test so it doesn't break unintentionally.
llvm-svn: 202662