During constant evaluation when value-initializing a class if the base
class was default-initialized it would undue the previously
zero-initialized class members. This fixes the way we handle default
initialization to avoid initializing over an already initialized member
to an indeterminate value.
Fixes: https://github.com/llvm/llvm-project/issues/69890
Adds a new `__builtin_vectorelements()` function which returns the
number of elements for a given vector either at compile-time for
fixed-sized vectors, e.g., created via `__attribute__((vector_size(N)))`
or at runtime via a call to `@llvm.vscale.i32()` for scalable vectors,
e.g., SVE or RISCV V.
The new builtin follows a similar path as `sizeof()`, as it essentially
does the same thing but for the number of elements in vector instead of
the number of bytes. This allows us to re-use a lot of the existing
logic to handle types etc.
A small side addition is `Type::isSizelessVectorType()`, which we need
to distinguish between sizeless vectors (SVE, RISCV V) and sizeless
types (WASM).
This is the [corresponding
discussion](https://discourse.llvm.org/t/new-builtin-function-to-get-number-of-lanes-in-simd-vectors/73911).
with an explicit parameter.
We tried to read a pointer to a non-existent `This` APValue when
constant-evaluating an explicit object lambda call operator (the `this`
pointer is never set in explicit object member functions)
Fixes#68070
This reverts commit 491b2810fb7fe5f080fa9c4f5945ed0a6909dc92.
This change broke valid code and generated incorrect diagnostics, see
https://reviews.llvm.org/D155064
This patch makes clang diagnose extensive cases of consteval if and is_constant_evaluated usage that are tautologically true or false.
This introduces a new IsRuntimeEvaluated boolean flag to Sema::ExpressionEvaluationContextRecord that means the immediate appearance of if consteval or is_constant_evaluated are tautologically false(e.g. inside if !consteval {} block or non-constexpr-qualified function definition body)
This patch also pushes new expression evaluation context when parsing the condition of if constexpr and initializer of constexpr variables so that Sema can be aware that the use of consteval if and is_consteval are tautologically true in if constexpr condition and constexpr variable initializers.
BEFORE this patch, the warning for is_constant_evaluated was emitted from constant evaluator. This patch moves the warning logic to Sema in order to diagnose tautological use of is_constant_evaluated in the same way as consteval if.
This patch separates initializer evaluation context from InitializerScopeRAII.
This fixes a bug that was happening when user takes address of function address in initializers of non-local variables.
Fixes https://github.com/llvm/llvm-project/issues/43760
Fixes https://github.com/llvm/llvm-project/issues/51567
Reviewed By: cor3ntin, ldionne
Differential Revision: https://reviews.llvm.org/D155064
An assertion issue that arose when handling union member access with
virtual base class has been addressed. As pointed out by @zygoloid,
there is no need for further derived-to-base analysis in this instance,
so we can bail out upon encountering a virtual base class. Minor
refinement on the function name as we might not be handling a union.
Reported-By: ormris
Fixes: https://github.com/llvm/llvm-project/issues/65982
Before:
```
array.cpp:319:10: note: read of uninitialized object is not allowed in a constant expression
319 | return aaa;
| ^
```
After:
```
array.cpp:319:10: note: read of uninitialized object is not allowed in a constant expression
319 | return aaa;
| ^~~
```
The width of the APSInt values should be the width of an element.
getCharByteWidth returns the size of an element in _host_ bytes, which
makes the width N times greater, where N is the ratio between target's
CHAR_BIT and host's CHAR_BIT.
This is NFC for in-tree targets because all of them have CHAR_BIT == 8.
Reviewed By: cor3ntin, aaron.ballman
Differential Revision: https://reviews.llvm.org/D154773
Consider the following code:
#include <windows.h>
#include <TraceLoggingActivity.h>
#include <TraceLoggingProvider.h>
#include <winmeta.h>
TRACELOGGING_DEFINE_PROVIDER(
g_hMyComponentProvider,
"SimpleTraceLoggingProvider",
// {0205c616-cf97-5c11-9756-56a2cee02ca7}
(0x0205c616,0xcf97,0x5c11,0x97,0x56,0x56,0xa2,0xce,0xe0,0x2c,0xa7));
void test()
{
TraceLoggingFunction(g_hMyComponentProvider);
}
int main()
{
TraceLoggingRegister(g_hMyComponentProvider);
test();
TraceLoggingUnregister(g_hMyComponentProvider);
}
It compiles with MSVC, but clang-cl reports an error:
C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared/TraceLoggingActivity.h(377,30): note: expanded from macro '_tlgThisFunctionName'
#define _tlgThisFunctionName __FUNCTION__
^
.\tl.cpp(14,5): error: cannot initialize an array element of type 'char' with an lvalue of type 'const char[5]'
TraceLoggingFunction(g_hMyComponentProvider);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The second commit is not needed to support above code, however, during isolated tests in ms_predefined_expr.cpp
I found that MSVC accepts code with constexpr, whereas clang-cl does not.
I see that in most places PredefinedExpr is supported in constant evaluation, so I didn't wrap my code with ``if(MicrosoftExt)``.
Reviewed By: cor3ntin
Differential Revision: https://reviews.llvm.org/D158591
The code mistakenly returns the value as evaluated whenever the
temporary is allocated, but not yet evaluated.
I could only reproduce in Clangd and could not come up with an example
that would crash the compiler. Clangd runs more evaluations for hover
than the language would allow.
Reviewed By: kadircet
Differential Revision: https://reviews.llvm.org/D158985
The implementation of __builtin_strncmp and other related builtins function use
getExtValue() to evaluate the size argument. This can cause a crash when the
value does not fit into an int64_t value, which is can be expected since the
type of the argument is size_t.
The fix is to switch to using getZExtValue().
This fixes: https://github.com/llvm/llvm-project/issues/64876
Differential Revision: https://reviews.llvm.org/D158557
BEFORE this patch, compound assignment operator against uninitialized object such as uninit += 1 was diagnosed as subexpression not valid
This patch clarifies the reason for the error by saying that uninit is an uninitialized object.
Fixes https://github.com/llvm/llvm-project/issues/51536
Reviewed By: shafik, tbaeder
Differential Revision: https://reviews.llvm.org/D157855
even if we know what the result is going to be.
There may be side effects we ought not to ignore,
Fixes#64923
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D158601
BEFORE:
```
overflow.cpp:1:21: warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
1 | int x = __INT_MAX__ + 1 + 3;
| ^
overflow.cpp:2:9: warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
2 | int a = -(1 << 31) + 1;
| ^
```
AFTER:
```
overflow.cpp:1:21: warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
1 | int x = __INT_MAX__ + 1 + 3;
| ~~~~~~~~~~~~^~~
overflow.cpp:2:9: warning: overflow in expression; result is -2147483648 with type 'int' [-Winteger-overflow]
2 | int a = -(1 << 31) + 1;
| ^~~~~~~~~~
```
Reviewed By: tbaeder
Differential Revision: https://reviews.llvm.org/D157383
Since we also have VLST for rvv now, it is not clear to keep using `isVLSTBuiltinType`, so I added prefix SVE to it.
Reviewed By: paulwalker-arm
Differential Revision: https://reviews.llvm.org/D158045
As discussed on #46593 - this enables us to use __lzcnt / __popcnt intrinsics inside constexpr code.
Differential Revision: https://reviews.llvm.org/D157420
This patch fixes the reported regression caused by D146358 through adding notes about an uninitialized base class when we diagnose uninitialized constructor.
This also changes the wording from the old one in order to make it clear that the uninitialized subobject is a base class and its constructor is not called.
Wording changes:
BEFORE: `subobject of type 'Base' is not initialized`
AFTER: `constructor of base class 'Base' is not called`
Fixes https://github.com/llvm/llvm-project/issues/63496
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D153969
For code like:
struct foo { ... };
struct bar { struct foo foo; };
const struct foo my_foo = { ... };
struct bar my_bar = { .foo = my_foo };
Eli Friedman points out the relevant part of the C standard seems to
have some flexibility in what is considered a constant expression:
6.6 paragraph 10:
An implementation may accept other forms of constant expressions.
GCC 8 added support for these, so clang not supporting them has been a
constant thorn in the side of source code portability within the Linux
kernel.
Fixes: https://github.com/llvm/llvm-project/issues/44502
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D76096
This patch adds additional printing of template argument list when the described function is a template specialization.
This can be useful when handling complex template functions in constexpr evaluator.
Reviewed By: cjdb, dblaikie
Differential Revision: https://reviews.llvm.org/D154366
This is a temporary fix (for clang 17) that caps the size of
any array we try to constant evaluate:
There are 2 limits:
* We cap to UINT_MAX the size of ant constant evaluated array,
because the constant evaluator does not support size_t.
* We cap to `-fconstexpr-steps` elements the size of each individual
array and dynamic array allocations.
This works out because the number of constexpr steps already limits
how many array elements can be initialized, which makes this new
limit conservatively generous.
This ensure that the compiler does not crash when attempting to
constant-fold valid programs.
If the limit is reached by a given array, constant evaluation will fail,
and the program will be ill-formed, until a bigger limit is given.
Or, constant folding will fail and the array will be evaluated at runtime.
Fixes#63562
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D155955
As suggested by @efriedma in:
https://reviews.llvm.org/D76096#4370369
This should speed up evaluating whether an expression is constant or
not, but due to the complexity of these two different implementations,
we may start getting different answers for edge cases for which we do
not yet have test cases in-tree (or perhaps even performance regressions
for some cases). As such, contributors have carte blanche to revert if
necessary.
For additional historical context about ExprConstant vs CGExprConstant,
here's snippets from a private conversation on discord:
ndesaulniers:
why do we have clang/lib/AST/ExprConstant.cpp and
clang/lib/CodeGen/CGExprConstant.cpp? Does clang constant fold during
ast walking/creation AND during LLVM codegen?
efriedma:
originally, clang needed to handle two things: integer constant
expressions (the "5" in "int x[5];"), and constant global initializers
(the "5" in "int x = 5;"). pre-C++11, the two could be handled mostly
separately; so we had the code for integer constants in AST/, and the
code for globals in CodeGen/. C++11 constexpr sort of destroyed that
separation, though. so now we do both kinds of constant evaluation on
the AST, then CGExprConstant translates the result of that evaluation
to LLVM IR. but we kept around some bits of the old cgexprconstant to
avoid performance/memory usage regressions on large arrays.
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D151587
This is a follow-up to 2e275e24355cb224981f9beb2b026a3169fc7232 and
1395cde24b3641e284bb1daae7d56c189a2635e3 which corrects a missed case:
initializing an _Atomic(T *) from a null pointer constant in the form
of the integer literal 0.
Fixes https://github.com/llvm/llvm-project/issues/63550
Differential Revision: https://reviews.llvm.org/D154284
This patch makes the display of member function calls more true to the user-written code by making use of the syntactical structure of the function calls.
This patch also changes the display of conventional value-based printing from arrow operator to dot operator.
This avoids the syntactical invalidness in notes previously caused by the display of & operator
(lack of parentheses and reference of rvalue)
Fixes https://github.com/llvm/llvm-project/issues/57081
Reviewed By: cjdb
Differential Revision: https://reviews.llvm.org/D151720
In preparation for removing the `#include "llvm/ADT/StringExtras.h"`
from the header to source file of `llvm/Support/Error.h`, first add in
all the missing includes that were previously included transitively
through this header.
A new builtin function __builtin_isfpclass is added. It is called as:
__builtin_isfpclass(<floating point value>, <test>)
and returns an integer value, which is non-zero if the floating point
argument falls into one of the classes specified by the second argument,
and zero otherwise. The set of classes is an integer value, where each
value class is represented by a bit. There are ten data classes, as
defined by the IEEE-754 standard, they are represented by bits:
0x0001 (__FPCLASS_SNAN) - Signaling NaN
0x0002 (__FPCLASS_QNAN) - Quiet NaN
0x0004 (__FPCLASS_NEGINF) - Negative infinity
0x0008 (__FPCLASS_NEGNORMAL) - Negative normal
0x0010 (__FPCLASS_NEGSUBNORMAL) - Negative subnormal
0x0020 (__FPCLASS_NEGZERO) - Negative zero
0x0040 (__FPCLASS_POSZERO) - Positive zero
0x0080 (__FPCLASS_POSSUBNORMAL) - Positive subnormal
0x0100 (__FPCLASS_POSNORMAL) - Positive normal
0x0200 (__FPCLASS_POSINF) - Positive infinity
They have corresponding builtin macros to facilitate using the builtin
function:
if (__builtin_isfpclass(x, __FPCLASS_NEGZERO | __FPCLASS_POSZERO) {
// x is any zero.
}
The data class encoding is identical to that used in llvm.is.fpclass
function.
Differential Revision: https://reviews.llvm.org/D152351
When the diagnostic for an out of range enum value is printed, it
currently does not show the actual enum type in question, for example:
v8/src/base/bit-field.h:43:29: error: integer value 7 is outside the valid range of values [0, 3] for this enumeration type [-Wenum-constexpr-conversion]
static constexpr T kMax = static_cast<T>(kNumValues - 1);
^
This can make it cumbersome to find the cause for the problem. Add the
enum type to the diagnostic message, to make it easier.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D152788