We previously took a shortcut and said that weak variables never have
constant initializers (because those initializers are never correct to
use outside the variable). We now say that weak variables can have
constant initializers, but are never usable in constant expressions.
References to different declarations of the same entity aren't different
values, so shouldn't have different representations.
Recommit of e6393ee813 with fixed handling
for weak declarations. We now look for attributes on the most recent
declaration when determining whether a declaration is weak. (Second
recommit with further fixes for mishandling of weak declarations. Our
behavior here is fundamentally unsound -- see PR47663 -- but this
approach attempts to not make things worse.)
The change implements evaluation of constant floating point expressions
under non-default rounding modes. The main objective was to support
evaluation of global variable initializers, where constant rounding mode
may be specified by `#pragma STDC FENV_ROUND`.
Differential Revision: https://reviews.llvm.org/D87822
References to different declarations of the same entity aren't different
values, so shouldn't have different representations.
Recommit of e6393ee813 with fixed
handling for weak declarations. We now look for attributes on the most
recent declaration when determining whether a declaration is weak.
On x86, long double has 6 unused trailing bytes. This patch changes the
constant evaluator to treat them as though they were padding bytes, so reading
from them results in an indeterminate value, and nothing is written for them.
Also, fix a similar bug with bool, but instead of treating the unused bits as
padding, enforce that they're zero.
Differential revision: https://reviews.llvm.org/D76323
This enables us to use the __builtin_rotateleft / __builtin_rotateright 8/16/32/64 intrinsics inside constexpr code.
Differential Revision: https://reviews.llvm.org/D86342
This patch moves FixedPointSemantics and APFixedPoint
from Clang to LLVM ADT.
This will make it easier to use the fixed-point
classes in LLVM for constructing an IR builder for
fixed-point and for reusing the APFixedPoint class
for constant evaluation purposes.
RFC: http://lists.llvm.org/pipermail/llvm-dev/2020-August/144025.html
Reviewed By: leonardchan, rjmccall
Differential Revision: https://reviews.llvm.org/D85312
Reapply 49e5f603d4
which had been reverted in c94332919b.
Originally reverted because I hadn't updated it in quite a while when I
got around to committing it, so there were a bunch of missing changes to
new code since I'd written the patch.
Reviewers: aaron.ballman
Differential Revision: https://reviews.llvm.org/D76646
We don't allow runtime-sized flexible array members, nor initialization
of flexible array members, but it seems reasonable to support the most
basic case where the flexible array member is empty.
There is a version that just tests (also called
isIntegerConstantExpression) & whereas this version is specifically used
when the value is of interest (a few call sites were actually refactored
to calling the test-only version) so let's make the API look more like
it.
Reviewers: aaron.ballman
Differential Revision: https://reviews.llvm.org/D76646
in places such as constant folding
Previously some places that should have handled
__builtin_expect_with_probability is missing, so in some case it acts
differently than __builtin_expect.
For example it was not handled in constant folding, thus in the
following program, the "if" condition should be constantly true and
folded, but previously it was not handled and cause warning "control may
reach end of non-void function" (while __builtin_expect does not):
__attribute__((noreturn)) extern void bar();
int foo(int x, int y) {
if (y) {
if (__builtin_expect_with_probability(1, 1, 1))
bar();
}
else
return 0;
}
Now it's fixed.
Differential Revisions: https://reviews.llvm.org/D83362
variable's initializer is not known.
The hope is that a better diagnostic for this case will reduce the rate
at which duplicates of non-bug PR41093 are reported.
Summary:
Assignment and comma operators for fixed-point types were being constevaled as other
binary operators, but they need special treatment.
Reviewers: rjmccall, leonardchan, bjope
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73189
Summary:
Diagnostics for overflow were not being produced for fixed-point
evaluation. This patch refactors a bit of the evaluator and adds
a proper diagnostic for these cases.
Reviewers: rjmccall, leonardchan, bjope
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73188
These operations do member-wise versions of the all of the listed
operations. This patch implements all of the binaryoperators for these
types. Note that the test is required to use codegen as I could not come
up with a good way to validate the values without the array-subscript
operator implemented (which is likely a much more involved change).
Differential Reivision: https://reviews.llvm.org/D79755
Prevent IR-gen from emitting consteval declarations
Summary: with this patch instead of emitting calls to consteval function. the IR-gen will emit a store of the already computed result.
Summary: with this patch instead of emitting calls to consteval function. the IR-gen will emit a store of the already computed result.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D76420
This patch implements matrix index expressions
(matrix[RowIdx][ColumnIdx]).
It does so by introducing a new MatrixSubscriptExpr(Base, RowIdx, ColumnIdx).
MatrixSubscriptExprs are built in 2 steps in ActOnMatrixSubscriptExpr. First,
if the base of a subscript is of matrix type, we create a incomplete
MatrixSubscriptExpr(base, idx, nullptr). Second, if the base is an incomplete
MatrixSubscriptExpr, we create a complete
MatrixSubscriptExpr(base->getBase(), base->getRowIdx(), idx)
Similar to vector elements, it is not possible to take the address of
a MatrixSubscriptExpr.
For CodeGen, a new MatrixElt type is added to LValue, which is very
similar to VectorElt. The only difference is that we may need to cast
the type of the base from an array to a vector type when accessing it.
Reviewers: rjmccall, anemet, Bigcheese, rsmith, martong
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D76791
This operator is intended for casting between
pointers to objects in different address spaces
and follows similar logic as const_cast in C++.
Tags: #clang
Differential Revision: https://reviews.llvm.org/D60193
This patch adds a matrix type to Clang as described in the draft
specification in clang/docs/MatrixSupport.rst. It introduces a new option
-fenable-matrix, which can be used to enable the matrix support.
The patch adds new MatrixType and DependentSizedMatrixType types along
with the plumbing required. Loads of and stores to pointers to matrix
values are lowered to memory operations on 1-D IR arrays. After loading,
the loaded values are cast to a vector. This ensures matrix values use
the alignment of the element type, instead of LLVM's large vector
alignment.
The operators and builtins described in the draft spec will will be added in
follow-up patches.
Reviewers: martong, rsmith, Bigcheese, anemet, dexonsmith, rjmccall, aaron.ballman
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D72281
This reverts commit 61ba1481e2.
I'm reverting this because it breaks the lldb build with
incomplete switch coverage warnings. I would fix it forward,
but am not familiar enough with lldb to determine the correct
fix.
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:3958:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4633:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
^
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp:4889:11: error: enumeration values 'DependentExtInt' and 'ExtInt' not handled in switch [-Werror,-Wswitch]
switch (qual_type->getTypeClass()) {
Introduction/Motivation:
LLVM-IR supports integers of non-power-of-2 bitwidth, in the iN syntax.
Integers of non-power-of-two aren't particularly interesting or useful
on most hardware, so much so that no language in Clang has been
motivated to expose it before.
However, in the case of FPGA hardware normal integer types where the
full bitwidth isn't used, is extremely wasteful and has severe
performance/space concerns. Because of this, Intel has introduced this
functionality in the High Level Synthesis compiler[0]
under the name "Arbitrary Precision Integer" (ap_int for short). This
has been extremely useful and effective for our users, permitting them
to optimize their storage and operation space on an architecture where
both can be extremely expensive.
We are proposing upstreaming a more palatable version of this to the
community, in the form of this proposal and accompanying patch. We are
proposing the syntax _ExtInt(N). We intend to propose this to the WG14
committee[1], and the underscore-capital seems like the active direction
for a WG14 paper's acceptance. An alternative that Richard Smith
suggested on the initial review was __int(N), however we believe that
is much less acceptable by WG14. We considered _Int, however _Int is
used as an identifier in libstdc++ and there is no good way to fall
back to an identifier (since _Int(5) is indistinguishable from an
unnamed initializer of a template type named _Int).
[0]https://www.intel.com/content/www/us/en/software/programmable/quartus-prime/hls-compiler.html)
[1]http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2472.pdf
Differential Revision: https://reviews.llvm.org/D73967
Summary:
Previously, we treated CXXUuidofExpr as quite a special case: it was the
only kind of expression that could be a canonical template argument, it
could be a constant lvalue base object, and so on. In addition, we
represented the UUID value as a string, whose source form we did not
preserve faithfully, and that we partially parsed in multiple different
places.
With this patch, we create an MSGuidDecl object to represent the
implicit object of type 'struct _GUID' created by a UuidAttr. Each
UuidAttr holds a pointer to its 'struct _GUID' and its original
(as-written) UUID string. A non-value-dependent CXXUuidofExpr behaves
like a DeclRefExpr denoting that MSGuidDecl object. We cache an APValue
representation of the GUID on the MSGuidDecl and use it from constant
evaluation where needed.
This allows removing a lot of the special-case logic to handle these
expressions. Unfortunately, many parts of Clang assume there are only
a couple of interesting kinds of ValueDecl, so the total amount of
special-case logic is not really reduced very much.
This fixes a few bugs and issues:
* PR38490: we now support reading from GUID objects returned from
__uuidof during constant evaluation.
* Our Itanium mangling for a non-instantiation-dependent template
argument involving __uuidof no longer depends on which CXXUuidofExpr
template argument we happened to see first.
* We now predeclare ::_GUID, and permit use of __uuidof without
any header inclusion, better matching MSVC's behavior. We do not
predefine ::__s_GUID, though; that seems like a step too far.
* Our IR representation for GUID constants now uses the correct IR type
wherever possible. We will still fall back to using the
{i32, i16, i16, [8 x i8]}
layout if a definition of struct _GUID is not available. This is not
ideal: in principle the two layouts could have different padding.
Reviewers: rnk, jdoerfert
Subscribers: arphaman, cfe-commits, aeubanks
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78171
memchr consistent and comprehensible, and document them.
We previously allowed evaluation of memcmp on arrays of integers of any
size, so long as the call evaluated to 0, and allowed evaluation of
memchr on any array of integral type of size 1 (including enums). The
purpose of constant-evaluating these builtins is only to support
constexpr std::char_traits, so we now consistently allow them on arrays
of (possibly signed or unsigned) char only.
Summary:
Added basic representation and parsing/sema handling of array-shaping
operations. Array shaping expression is an expression of form ([s0]..[sn])base,
where s0, ..., sn must be a positive integer, base - a pointer. This
expression is a kind of cast operation that converts pointer expression
into an array-like kind of expression.
Reviewers: rjmccall, rsmith, jdoerfert
Subscribers: guansong, arphaman, cfe-commits, caomhin, kkwli0
Tags: #clang
Differential Revision: https://reviews.llvm.org/D74144
Normally clang avoids creating expressions when it encounters semantic
errors, even if the parser knows which expression to produce.
This works well for the compiler. However, this is not ideal for
source-level tools that have to deal with broken code, e.g. clangd is
not able to provide navigation features even for names that compiler
knows how to resolve.
The new RecoveryExpr aims to capture the minimal set of information
useful for the tools that need to deal with incorrect code:
source range of the expression being dropped,
subexpressions of the expression.
We aim to make constructing RecoveryExprs as simple as possible to
ensure writing code to avoid dropping expressions is easy.
Producing RecoveryExprs can result in new code paths being taken in the
frontend. In particular, clang can produce some new diagnostics now and
we aim to suppress bogus ones based on Expr::containsErrors.
We deliberately produce RecoveryExprs only in the parser for now to
minimize the code affected by this patch. Producing RecoveryExprs in
Sema potentially allows to preserve more information (e.g. type of an
expression), but also results in more code being affected. E.g.
SFINAE checks will have to take presence of RecoveryExprs into account.
Initial implementation only works in C++ mode, as it relies on compiler
postponing diagnostics on dependent expressions. C and ObjC often do not
do this, so they require more work to make sure we do not produce too
many bogus diagnostics on the new expressions.
See documentation of RecoveryExpr for more details.
original patch from Ilya
This change is based on https://reviews.llvm.org/D61722
Reviewers: sammccall, rsmith
Reviewed By: sammccall, rsmith
Tags: #clang
Differential Revision: https://reviews.llvm.org/D69330
and objects with mutable subobjects.
The standard wording doesn't really cover these cases; accepting all
such cases seems most in line with what we do in other cases and what
other compilers do. (Essentially this means we're assuming that objects
external to the evaluation are always in-lifetime.)
constant initialization.
Removing this zeroing regressed our code generation in a few cases, also
fixed here. We now compute whether a variable has constant destruction
even if it doesn't have a constant initializer, by trying to destroy a
default-initialized value, and skip emitting a trivial default
constructor for a variable even if it has non-trivial (but perhaps
constant) destruction.
whether a call is to a builtin.
We already had a general mechanism to do this but for some reason
weren't using it. In passing, check for the other unary operators that
can intervene in a reasonably-direct function call (we already handled
'&' but missed '*' and '+').
This reverts commit aaae6b1b61,
reinstating af80b8ccc5, with a fix to
clang-tidy.
Summary:
Changes:
- Calls to consteval function are now evaluated in constant context but IR is still generated for them.
- Add diagnostic for taking address of a consteval function in non-constexpr context.
- Add diagnostic for address of consteval function accessible at runtime.
- Add tests
Reviewers: rsmith, aaron.ballman
Reviewed By: rsmith
Subscribers: mgrang, riccibruno, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63960
whether a call is to a builtin.
We already had a general mechanism to do this but for some reason
weren't using it. In passing, check for the other unary operators that
can intervene in a reasonably-direct function call (we already handled
'&' but missed '*' and '+').
Implement support for C++2a requires-expressions.
Re-commit after compilation failure on some platforms due to alignment issues with PointerIntPair.
Differential Revision: https://reviews.llvm.org/D50360
GCC supports the conditional operator on VectorTypes that acts as a
'select' in C++ mode. This patch implements the support. Types are
converted as closely to GCC's behavior as possible, though in a few
places consistency with our existing vector type support was preferred.
Note that this implementation is different from the OpenCL version in a
number of ways, so it unfortunately required a different implementation.
First, the SEMA rules and promotion rules are significantly different.
Secondly, GCC implements COND[i] != 0 ? LHS[i] : RHS[i] (where i is in
the range 0- VectorSize, for each element). In OpenCL, the condition is
COND[i] < 0 ? LHS[i]: RHS[i].
In the process of implementing this, it was also required to make the
expression COND ? LHS : RHS type dependent if COND is type dependent,
since the type is now dependent on the condition. For example:
T ? 1 : 2;
Is not typically type dependent, since the result can be deduced from
the operands. HOWEVER, if T is a VectorType now, it could change this
to a 'select' (basically a swizzle with a non-constant mask) with the 1
and 2 being promoted to vectors themselves.
While this is a change, it is NOT a standards incompatible change. Based
on my (and D. Gregor's, at the time of writing the code) reading of the
standard, the expression is supposed to be type dependent if ANY
sub-expression is type dependent.
Differential Revision: https://reviews.llvm.org/D71463
This change introduces three new builtins (which work on both pointers
and integers) that can be used instead of common bitwise arithmetic:
__builtin_align_up(x, alignment), __builtin_align_down(x, alignment) and
__builtin_is_aligned(x, alignment).
I originally added these builtins to the CHERI fork of LLVM a few years ago
to handle the slightly different C semantics that we use for CHERI [1].
Until recently these builtins (or sequences of other builtins) were
required to generate correct code. I have since made changes to the default
C semantics so that they are no longer strictly necessary (but using them
does generate slightly more efficient code). However, based on our experience
using them in various projects over the past few years, I believe that adding
these builtins to clang would be useful.
These builtins have the following benefit over bit-manipulation and casts
via uintptr_t:
- The named builtins clearly convey the semantics of the operation. While
checking alignment using __builtin_is_aligned(x, 16) versus
((x & 15) == 0) is probably not a huge win in readably, I personally find
__builtin_align_up(x, N) a lot easier to read than (x+(N-1))&~(N-1).
- They preserve the type of the argument (including const qualifiers). When
using casts via uintptr_t, it is easy to cast to the wrong type or strip
qualifiers such as const.
- If the alignment argument is a constant value, clang can check that it is
a power-of-two and within the range of the type. Since the semantics of
these builtins is well defined compared to arbitrary bit-manipulation,
it is possible to add a UBSAN checker that the run-time value is a valid
power-of-two. I intend to add this as a follow-up to this change.
- The builtins avoids int-to-pointer casts both in C and LLVM IR.
In the future (i.e. once most optimizations handle it), we could use the new
llvm.ptrmask intrinsic to avoid the ptrtoint instruction that would normally
be generated.
- They can be used to round up/down to the next aligned value for both
integers and pointers without requiring two separate macros.
- In many projects the alignment operations are already wrapped in macros (e.g.
roundup2 and rounddown2 in FreeBSD), so by replacing the macro implementation
with a builtin call, we get improved diagnostics for many call-sites while
only having to change a few lines.
- Finally, the builtins also emit assume_aligned metadata when used on pointers.
This can improve code generation compared to the uintptr_t casts.
[1] In our CHERI compiler we have compilation mode where all pointers are
implemented as capabilities (essentially unforgeable 128-bit fat pointers).
In our original model, casts from uintptr_t (which is a 128-bit capability)
to an integer value returned the "offset" of the capability (i.e. the
difference between the virtual address and the base of the allocation).
This causes problems for cases such as checking the alignment: for example, the
expression `if ((uintptr_t)ptr & 63) == 0` is generally used to check if the
pointer is aligned to a multiple of 64 bytes. The problem with offsets is that
any pointer to the beginning of an allocation will have an offset of zero, so
this check always succeeds in that case (even if the address is not correctly
aligned). The same issues also exist when aligning up or down. Using the
alignment builtins ensures that the address is used instead of the offset. While
I have since changed the default C semantics to return the address instead of
the offset when casting, this offset compilation mode can still be used by
passing a command-line flag.
Reviewers: rsmith, aaron.ballman, theraven, fhahn, lebedev.ri, nlopes, aqjune
Reviewed By: aaron.ballman, lebedev.ri
Differential Revision: https://reviews.llvm.org/D71499
Add constexpr evaluation for ExtVectorElementExpr nodes by evaluating
the underlying vector expression. Add basic folding for the case that
Evaluate does not return an LValue.
Differential Revision: https://reviews.llvm.org/D71133
The AST for the constexpr.cl test contains address space conversion
nodes to cast through the implicit generic address space. These
caused the evaluator to reject the input as constexpr in C++ for
OpenCL mode, whereas the input was considered constexpr in plain C++
mode as the AST won't have address space cast nodes then.
Fixes PR44177.
Differential Revision: https://reviews.llvm.org/D71015
Array members are not yet handled. In addition, defaulted comparisons
can't yet find comparison operators by unqualified lookup (only by
member lookup and ADL). These issues will be fixed in follow-on changes.
If the lambda used 'this' without without capturing it, an error was
emitted, but the constant evaluator would still attempt to lookup the
capture, and failing to find it, dereference a null pointer.
This only happens in C++17 (as that's when lambdas were made
potentially-constexpr). Therefore, I also updated the
lambda-expressions.cpp test to run in both C++14 and C++17 modes.
Summary:
Removed the ```-fforce-experimental-new-constant-interpreter flag```, leaving
only the ```-fexperimental-new-constant-interpreter``` one. The interpreter
now always emits an error on an unsupported feature.
Allowing the interpreter to bail out would require a mapping from APValue to
interpreter memory, which will not be necessary in the final version. It is
more sensible to always emit an error if the interpreter fails.
Reviewers: jfb, Bigcheese, rsmith, dexonsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70071
Current EvalInfo ctor causes EnableNewConstInterp to be true even though
it is supposed to be false on MSVC 2017. This is because a virtual function
getLangOpts() is called in member initializer lists, whereas on MSVC
member ctors are called before function virtual function pointers are
initialized.
This patch fixes that.
Differential Revision: https://reviews.llvm.org/D70729
non-constant.
We previously failed the entire condition evaluation if an unmodeled
side-effect was encountered in an argument, even if that argument was
unused in the attribute's condition.
Part of C++20 Concepts implementation effort. Added Concept Specialization Expressions that are created when a concept is refe$
D41217 on Phabricator.
(recommit after fixing failing Parser test on windows)
llvm-svn: 374903
Part of C++20 Concepts implementation effort. Added Concept Specialization Expressions that are created when a concept is referenced with arguments, and tests thereof.
llvm-svn: 374882
"non-constant" value.
If the constant evaluator evaluates part of a variable initializer,
including the initializer for some lifetime-extended temporary, but
fails to fully evaluate the initializer, it can leave behind wrong
values for temporaries encountered in that initialization. Don't try to
emit those from CodeGen! Instead, look at the values that constant
evaluation produced if (and only if) it actually succeeds and we're
emitting the lifetime-extending declaration's initializer as a constant.
llvm-svn: 374119
We previously failed to treat an array with an instantiation-dependent
but not value-dependent bound as being an instantiation-dependent type.
We now track the array bound expression as part of a constant array type
if it's an instantiation-dependent expression.
llvm-svn: 373685
The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<> directly and if not assert will fire for us.
llvm-svn: 373612
The static analyzer is warning about potential null dereferences, but in these cases we should be able to use castAs<RecordType> directly and if not assert will fire for us.
llvm-svn: 373584
pointer-to-member call can't determine a callee.
We will have produced a diagnostic already if the callee is known to be
unevaluatable, and diagnosing here rejects valid code during potential
constant expression checking.
llvm-svn: 373553
For now, we restrict this support to use from within the standard
library implementation, since we're required to make parts of the
standard library that use placement new work, but not permitted to
make uses of placement new from user code work.
llvm-svn: 373547
constexpr) destructors from being used in the values of constexpr
variables.
The standard rules here are unclear at best, so rejecting the
problematic cases seems prudent. Prior to this change, we would fail to
run the destructors for these temporaries, even if they had
side-effects, which is certainly not the right behavior.
llvm-svn: 373161
In the presence of mutable state, we need to check whether temporaries
involved in a constant expression have permissible values at the end of
the overall evaluation, rather than at the end of the evaluation of the
initializer of the temporary.
llvm-svn: 373160
has a constexpr destructor.
For constexpr variables, reject if the variable does not have constant
destruction. In all cases, do not emit runtime calls to the destructor
for variables with constant destruction.
llvm-svn: 373159
We need to discard all remaining cleanups if an earlier cleanup failed,
otherwise we may try to rerun the remaining cleanups later, potentially
after the scope containing the object is destroyed. (This can happen
when checking a potential constant expression.)
llvm-svn: 373042
appropriate during constant evaluation.
Note that the evaluator is sometimes invoked on incomplete expressions.
In such cases, if an object is constructed but we never reach the point
where it would be destroyed (and it has non-trivial destruction), we
treat the expression as having an unmodeled side-effect.
llvm-svn: 372538
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 371834
constant-folding mode regardless of the original evaluation mode.
In order for this to be correct, we need to track whether we're checking
for a potential constant expression or checking for undefined behavior
separately from the evaluation mode enum, since we don't want to clobber
those states when entering constant-folding mode.
llvm-svn: 371557
Breaks BUILD_SHARED_LIBS build, introduces cycles in library dependency
graphs. (clangInterp depends on clangAST which depends on clangInterp)
This reverts r370839, which is an yet another recommit of D64146.
llvm-svn: 370874
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 370839
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 370636
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 370584
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 370531
Summary:
This patch introduces the skeleton of the constexpr interpreter,
capable of evaluating a simple constexpr functions consisting of
if statements. The interpreter is described in more detail in the
RFC. Further patches will add more features.
Reviewers: Bigcheese, jfb, rsmith
Subscribers: bruno, uenoku, ldionne, Tyker, thegameg, tschuett, dexonsmith, mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D64146
llvm-svn: 370476
This patch adds the SVE built-in types defined by the Procedure Call
Standard for the Arm Architecture:
https://developer.arm.com/docs/100986/0000
It handles the types in all relevant places that deal with built-in types.
At the moment, some of these places bail out with an error, including:
(1) trying to generate LLVM IR for the types
(2) trying to generate debug info for the types
(3) trying to mangle the types using the Microsoft C++ ABI
(4) trying to @encode the types in Objective C
(1) and (2) are fixed by follow-on patches but (unlike this patch)
they deal mostly with target-specific LLVM details, so seemed like
a logically separate change. There is currently no spec for (3) and
(4), so reporting an error seems like the correct behaviour for now.
The intention is that the types will become sizeless types:
http://lists.llvm.org/pipermail/cfe-dev/2019-June/062523.html
The main purpose of the sizeless type extension is to diagnose
impossible or dangerous uses of the types, such as any that would
require sizeof to have a meaningful defined value.
Until then, the patch sets the alignments of the types to the values
specified in the link above. It also sets the sizes of the types to
zero, which is chosen to be consistently wrong and shouldn't affect
correctly-written code (i.e. code that would compile even with the
sizeless type extension).
The patch adds the common subset of functionality needed to test the
sizeless type extension on the one hand and to provide SVE intrinsic
functions on the other. After this patch, the two pieces of work are
essentially independent.
The patch is based on one by Graham Hunter:
https://reviews.llvm.org/D59245
Differential Revision: https://reviews.llvm.org/D62960
llvm-svn: 368413
Summary:
Prior to r329065, we used [-max, max] as the range of representable
values because LLVM's `fptrunc` did not guarantee defined behavior when
truncating from a larger floating-point type to a smaller one. Now that
has been fixed, we can make clang follow normal IEEE 754 semantics in this
regard and take the larger range [-inf, +inf] as the range of representable
values.
In practice, this affects two parts of the frontend:
* the constant evaluator no longer treats floating-point evaluations
that result in +-inf as being undefined (because they no longer leave
the range of representable values of the type)
* UBSan no longer treats conversions to floating-point type that are
outside the [-max, +max] range as being undefined
In passing, also remove the float-divide-by-zero sanitizer from
-fsanitize=undefined, on the basis that while it's undefined per C++
rules (and we disallow it in constant expressions for that reason), it
is defined by Clang / LLVM / IEEE 754.
Reviewers: rnk, BillyONeal
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63793
llvm-svn: 365272
This commit adds a new builtin, __builtin_bit_cast(T, v), which performs a
bit_cast from a value v to a type T. This expression can be evaluated at
compile time under specific circumstances.
The compile time evaluation currently doesn't support bit-fields, but I'm
planning on fixing this in a follow up (some of the logic for figuring this out
is in CodeGen). I'm also planning follow-ups for supporting some more esoteric
types that the constexpr evaluator supports, as well as extending
__builtin_memcpy constexpr evaluation to use the same infrastructure.
rdar://44987528
Differential revision: https://reviews.llvm.org/D62825
llvm-svn: 364954
Summary:
this patch has multiple small improvements related to the APValue in ConstantExpr.
changes:
- APValue in ConstantExpr are now cleaned up using ASTContext::addDestruction instead of there own system.
- ConstantExprBits Stores the ValueKind of the result beaing stored.
- VerifyIntegerConstantExpression now stores the evaluated value in ConstantExpr.
- the Constant Evaluator uses the stored value of ConstantExpr when available.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D63376
llvm-svn: 364011
Summary:
Since the addition of __builtin_is_constant_evaluated the result of an expression can change based on whether it is evaluated in constant context. a lot of semantic checking performs evaluations with out specifying context. which can lead to wrong diagnostics.
for example:
```
constexpr int i0 = (long long)__builtin_is_constant_evaluated() * (1ll << 33); //#1
constexpr int i1 = (long long)!__builtin_is_constant_evaluated() * (1ll << 33); //#2
```
before the patch, #2 was diagnosed incorrectly and #1 wasn't diagnosed.
after the patch #1 is diagnosed as it should and #2 isn't.
Changes:
- add a flag to Sema to passe in constant context mode.
- in SemaChecking.cpp calls to Expr::Evaluate* are now done in constant context when they should.
- in SemaChecking.cpp diagnostics for UB are not checked for in constant context because an error will be emitted by the constant evaluator.
- in SemaChecking.cpp diagnostics for construct that cannot appear in constant context are not checked for in constant context.
- in SemaChecking.cpp diagnostics on constant expression are always emitted because constant expression are always evaluated.
- semantic checking for initialization of constexpr variables is now done in constant context.
- adapt test that were depending on warning changes.
- add test.
Reviewers: rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62009
llvm-svn: 363488
As reported here https://bugs.llvm.org/show_bug.cgi?id=42000, it was
possible to get the constexpr version of __builtin_*_overflow to give
the wrong answer.
This was because when extending the operands to fit the largest type (so
that the math could be done), the decision on whether to sign/zero
extend the operands was based on the result signedness, not on the
operands signedness.
In the reported case, (unsigned char)255 - (int)100 needed
to have each extended to the int in order to do the math. However, when
extending the first operand to 'int', we incorrectly sign extended it
instead of zero extending. Thus, the result didnt fit back into the
unsigned char.
The fix for this was simply to choose zero/sign extension based on the
sign of the operand itself.
Differential Revision: https://reviews.llvm.org/D62665
llvm-svn: 362157
HandleUnionActiveMemberChange forgot to walk over a nop implicit
conversion node and got stuck in the process.
As a cleanup I changed the declaration of `E` so it can't
be accidentally accessed after the loop.
llvm-svn: 361571
representing no such object, and an "Indeterminate" state representing
an uninitialized object. The latter is not yet used, but soon will be.
llvm-svn: 361328
Without the fix at least clang 3.6 complains with
../tools/clang/lib/AST/ExprConstant.cpp:90:24: error: unused variable 'TI' [-Werror,-Wunused-variable]
if (TypeInfoLValue TI = B.dyn_cast<TypeInfoLValue>())
^
1 error generated.
llvm-svn: 361145
class type in constant evaluation.
This reinstates r360977, reverted in r360987, now that its rerequisite
patch is reinstated and fixed.
llvm-svn: 361067
Summary:
Constant evaluator does not work on value-dependent or type-dependent
expressions.
Also fixed bugs uncovered by these assertions.
Subscribers: cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61522
llvm-svn: 361050
object rather than tracking the originating expression.
This is groundwork for supporting polymorphic typeid expressions. (Note
that this somewhat regresses our support for DR1968, but it turns out
that that never actually worked anyway, at least in non-trivial cases.)
This reinstates r360974, reverted in r360988, with a fix for a
static_assert failure on 32-bit builds: force Type base class to have
8-byte alignment like the rest of Clang's AST nodes.
llvm-svn: 360995
object rather than tracking the originating expression.
This is groundwork for supporting polymorphic typeid expressions. (Note
that this somewhat regresses our support for DR1968, but it turns out
that that never actually worked anyway, at least in non-trivial cases.)
llvm-svn: 360974
Summary:
This patch implements the source location builtins `__builtin_LINE(), `__builtin_FUNCTION()`, `__builtin_FILE()` and `__builtin_COLUMN()`. These builtins are needed to implement [`std::experimental::source_location`](https://rawgit.com/cplusplus/fundamentals-ts/v2/main.html#reflection.src_loc.creation).
With the exception of `__builtin_COLUMN`, GCC also implements these builtins, and Clangs behavior is intended to match as closely as possible.
Reviewers: rsmith, joerg, aaron.ballman, bogner, majnemer, shafik, martong
Reviewed By: rsmith
Subscribers: rnkovacs, loskutov, riccibruno, mgorny, kunitoki, alexr, majnemer, hfinkel, cfe-commits
Differential Revision: https://reviews.llvm.org/D37035
llvm-svn: 360937
evaluation.
This reinstates r360559, reverted in r360580, with a fix to avoid
crashing if evaluation-for-overflow mode encounters a virtual call on an
object of a class with a virtual base class, and to generally not try to
resolve virtual function calls to objects whose (notional) vptrs are not
readable. (The standard rules are unclear here, but this seems like a
reasonable approach.)
llvm-svn: 360635
their lifetime in constant expressions.
This is undefined behavior per [class.cdtor]p2.
We continue to allow this for objects whose values are not visible
within the constant evaluation, because there's no way we can tell
whether the access is defined or not, existing code relies on the
ability to make such calls, and every other compiler allows such
calls.
This reinstates r360499, reverted in r360531.
llvm-svn: 360538
evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
This reinstates r360464 (reverted in r360531) with a workaround for an
MSVC bug that previously caused the Windows bots to fail.
llvm-svn: 360537
Reject attempts to call non-static member functions on objects outside
their lifetime in constant expressions.
This is undefined behavior per [class.cdtor]p2.
We continue to allow this for objects whose values are not visible
within the constant evaluation, because there's no way we can tell
whether the access is defined or not, existing code relies on the
ability to make such calls, and every other compiler allows such
calls.
........
Fix handling of objects under construction during constant expression
evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
........
Fixes windows buildbots
llvm-svn: 360531
their lifetime in constant expressions.
This is undefined behavior per [class.cdtor]p2.
We continue to allow this for objects whose values are not visible
within the constant evaluation, because there's no way we can tell
whether the access is defined or not, existing code relies on the
ability to make such calls, and every other compiler allows such
calls.
llvm-svn: 360499
evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
llvm-svn: 360464
state when it's encountered while evaluating a constexpr function.
We attempt to follow GCC trunk's behavior here, but it is somewhat
inscrutible, so our behavior is only approximately the same for now.
Specifically, we only permit modification of objects whose lifetime
began within the operand of the __builtin_constant_p. GCC appears to
have effectively the same restriction, but also some unknown restriction
based on where and how the local state of the constexpr function is
mentioned within the operand (see added testcases).
llvm-svn: 359958
__builtin_constant_p.
If the operand of __builtin_constant_p is not constant and has
side-effects, then code controlled by a branch on it is unreachable and
we should not emit runtime behavior warnings in such code.
llvm-svn: 359844
us emitting the operand of __builtin_constant_p if it has side-effects.
Original commit message:
Fix interactions between __builtin_constant_p and constexpr to match
current trunk GCC.
GCC permits information from outside the operand of
__builtin_constant_p (but in the same constant evaluation context) to be
used within that operand; clang now does so too. A few other minor
deviations from GCC's behavior showed up in my testing and are also
fixed (matching GCC):
* Clang now supports nullptr_t as the argument type for
__builtin_constant_p
* Clang now returns true from __builtin_constant_p if called with a
null pointer
* Clang now returns true from __builtin_constant_p if called with an
integer cast to pointer type
llvm-svn: 359367
Summary:
This patch implements `__builtin_is_constant_evaluated` as specifier by [P0595R2](https://wg21.link/p0595r2). It is built on the back of Bill Wendling's work for `__builtin_constant_p()`.
More tests to come, but early feedback is appreciated.
I plan to implement warnings for common mis-usages like those belowe in a following patch:
```
void foo(int x) {
if constexpr (std::is_constant_evaluated())) { // condition is always `true`. Should use plain `if` instead.
foo_constexpr(x);
} else {
foo_runtime(x);
}
}
```
Reviewers: rsmith, MaskRay, bruno, void
Reviewed By: rsmith
Subscribers: dexonsmith, zoecarver, fdeazeve, kristina, cfe-commits
Differential Revision: https://reviews.llvm.org/D55500
llvm-svn: 359067
current trunk GCC.
GCC permits information from outside the operand of
__builtin_constant_p (but in the same constant evaluation context) to be
used within that operand; clang now does so too. A few other minor
deviations from GCC's behavior showed up in my testing and are also
fixed (matching GCC):
* Clang now supports nullptr_t as the argument type for
__builtin_constant_p
* Clang now returns true from __builtin_constant_p if called with a
null pointer
* Clang now returns true from __builtin_constant_p if called with an
integer cast to pointer type
llvm-svn: 359059
Summary:
The following code is accepted by Clang 7 and prior but rejected by the upcoming 8 release and in trunk [1]
```
// error {{never produces a constant expression}}
void foo(const char* s) __attribute__((enable_if(__builtin_constant_p(*s) == false, "trap"))) {}
void test() { foo("abc"); }
```
Prior to Clang 8, the call to `__builtin_constant_p` was a constant expression returning false. Currently, it's not a valid constant expression.
The bug is caused because we failed to set `InConstantContext` when attempting to evaluate unevaluated constant expressions.
[1] https://godbolt.org/z/ksAjmq
Reviewers: rsmith, hans, sbenza
Reviewed By: rsmith
Subscribers: kristina, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59038
llvm-svn: 355743
expression inside the parentheses is a valid UTF-8 string literal.
Previously clang emitted an expression like @("abc") as a message send
to stringWithUTF8String. This commit makes clang emit the boxed
expression as a compile-time constant instead.
This commit also has the effect of silencing the nullable-to-nonnull
conversion warning clang started emitting after r317727, which
originally motivated this commit (see https://oleb.net/2018/@keypath).
rdar://problem/42684601
Differential Revision: https://reviews.llvm.org/D58729
llvm-svn: 355662
Apparently GCC allows this, and there's code relying on it (see bug).
The idea is to allow expression that would have been allowed if they
were cast to int. So I based the code on how such a cast would be done
(the CK_PointerToIntegral case in IntExprEvaluator::VisitCastExpr()).
Differential Revision: https://reviews.llvm.org/D58821
llvm-svn: 355491
This patch includes the necessary code for converting between a fixed point type and integer.
This also includes constant expression evaluation for conversions with these types.
Differential Revision: https://reviews.llvm.org/D56900
llvm-svn: 355462
This patch implements fixed point comparisons with other fixed point types and
integers. This also provides constant expression evaluation for them.
Differential Revision: https://reviews.llvm.org/D57219
llvm-svn: 354621
Summary:
This makes it consistent with `memcmp` and `__builtin_bcmp`.
Also see the discussion in https://reviews.llvm.org/D56593.
Reviewers: jyknight
Subscribers: kristina, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D58120
llvm-svn: 354023
This allows substantially simplifying the expression evaluation code,
because we don't have to special-case lvalues which are actually string
literal initialization.
This currently throws away an optimization where we would avoid creating
an array APValue for string literal initialization. If we really want
to optimize this case, we should fix APValue so it can store simple
arrays more efficiently, like llvm::ConstantDataArray. This shouldn't
affect the memory usage for other string literals. (Not sure if this is
a blocker; I don't think string literal init is common enough for this
to be a serious issue, but I could be wrong.)
The change to test/CodeGenObjC/encode-test.m is a weird side-effect of
these changes: we currently don't constant-evaluate arrays in C, so the
strlen call shouldn't be folded, but lvalue string init managed to get
around that check. I this this is fine.
Fixes https://bugs.llvm.org/show_bug.cgi?id=40430 .
llvm-svn: 353569
This builtin has the same UI as __builtin_object_size, but has the
potential to be evaluated dynamically. It is meant to be used as a
drop-in replacement for libraries that use __builtin_object_size when
a dynamic checking mode is enabled. For instance,
__builtin_object_size fails to provide any extra checking in the
following function:
void f(size_t alloc) {
char* p = malloc(alloc);
strcpy(p, "foobar"); // expands to __builtin___strcpy_chk(p, "foobar", __builtin_object_size(p, 0))
}
This is an overflow if alloc < 7, but because LLVM can't fold the
object size intrinsic statically, it folds __builtin_object_size to
-1. With __builtin_dynamic_object_size, alloc is passed through to
__builtin___strcpy_chk.
rdar://32212419
Differential revision: https://reviews.llvm.org/D56760
llvm-svn: 352665
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 patch includes logic for constant expression evaluation of fixed point additions.
Differential Revision: https://reviews.llvm.org/D55868
llvm-svn: 351593
This adds APFixedPoint to the union of values that can be represented with an APValue.
Differential Revision: https://reviews.llvm.org/D56746
llvm-svn: 351368
Summary:
https://reviews.llvm.org/D54862 removed the usages of `ASTContext&` from
within the `CXXMethodDecl::getThisType` method. Remove the parameter
altogether, as well as all usages of it. This does not result in any
functional change because the parameter was unused since
https://reviews.llvm.org/D54862.
Test Plan: check-clang
Reviewers: akyrtzi, mikael
Reviewed By: mikael
Subscribers: mehdi_amini, dexonsmith, cfe-commits
Differential Revision: https://reviews.llvm.org/D56509
llvm-svn: 350914
Summary:
This patch adds `__builtin_launder`, which is required to implement `std::launder`. Additionally GCC provides `__builtin_launder`, so thing brings Clang in-line with GCC.
I'm not exactly sure what magic `__builtin_launder` requires, but based on previous discussions this patch applies a `@llvm.invariant.group.barrier`. As noted in previous discussions, this may not be enough to correctly handle vtables.
Reviewers: rnk, majnemer, rsmith
Reviewed By: rsmith
Subscribers: kristina, Romain-Geissler-1A, erichkeane, amharc, jroelofs, cfe-commits, Prazek
Differential Revision: https://reviews.llvm.org/D40218
llvm-svn: 349195
Summary:
`memchr` and `memcmp` operate upon the character units of the object
representation; that is, the `size_t` parameter expresses the number of
character units. The constant folding implementation is updated in this
patch to account for multibyte element types in the arrays passed to
`memchr`/`memcmp` and, in the case of `memcmp`, to account for the
possibility that the arrays may have differing element types (even when
they are byte-sized).
Actual inspection of the object representation is not implemented.
Comparisons are done only between elements with the same object size;
that is, `memchr` will fail when inspecting at least one character unit
of a multibyte element. The integer types are assumed to have two's
complement representation with 0 for `false`, 1 for `true`, and no
padding bits.
`memcmp` on multibyte elements will only be able to fold in cases where
enough elements are equal for the answer to be 0.
Various tests are added to guard against incorrect folding for cases
that miscompile on some system or other prior to this patch. At the same
time, the unsigned 32-bit `wchar_t` testing in
`test/SemaCXX/constexpr-string.cpp` is restored.
Reviewers: rsmith, aaron.ballman, hfinkel
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D55510
llvm-svn: 348938
Implement support for try-catch blocks in constexpr functions, as
proposed in http://wg21.link/P1002 and voted in San Diego for c++20.
The idea is that we can still never throw inside constexpr, so the catch
block is never entered. A try-catch block like this:
try { f(); } catch (...) { }
is then morally equivalent to just
{ f(); }
Same idea should apply for function/constructor try blocks.
rdar://problem/45530773
Differential Revision: https://reviews.llvm.org/D55097
llvm-svn: 348789
It seems the two failing tests can be simply fixed after r348037
Fix 3 cases in Analysis/builtin-functions.cpp
Delete the bad CodeGen/builtin-constant-p.c for now
llvm-svn: 348053
Kept the "indirect_builtin_constant_p" test case in test/SemaCXX/constant-expression-cxx1y.cpp
while we are investigating why the following snippet fails:
extern char extern_var;
struct { int a; } a = {__builtin_constant_p(extern_var)};
llvm-svn: 348039