1453 Commits

Author SHA1 Message Date
DaPorkchop_
b45236f133
[clang] Implement constexpr bit_cast for vectors (#66894)
This makes __builtin_bit_cast support converting to and from vector
types in a constexpr context.
2023-10-30 11:15:36 -07:00
Takuya Shimizu
b88a9f9670
[clang][ExprConst] Fix crash on uninitialized array subobject (#67817)
https://reviews.llvm.org/D146358 was assuming that all subobjects have
their own name (`SubobjectDecl`), but it was not true for array
elements.

Fixes https://github.com/llvm/llvm-project/issues/67317
2023-10-27 14:11:27 +09:00
Timm Bäder
f8b7506e2d [clang][NFC] Move a variable into the closest scope
AllocType is not used anywhere else.
2023-10-26 11:40:43 +02:00
Shafik Yaghmour
b8e06933a2
[Clang] Ensure zero-init is not overridden when initializing a base class in a constant expression context (#70150)
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
2023-10-25 10:18:40 -07:00
Timm Bäder
aaaece65a8 [clang][ExprConst] Handle 0 type size in builtin_memcpy etc.
Differential Revision: https://reviews.llvm.org/D157252
2023-10-24 06:48:09 +02:00
Lawrence Benson
de65b6bec6
[Clang] Add __builtin_vectorelements to get number of elements in vector (#69010)
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).
2023-10-19 10:45:08 +02:00
Timm Bäder
b4343aba9f [clang][ExprConst] Short-circuit ConstantExpr evaluation
ConstantExprs already have a value attached we can just return here.

Differential Revision: https://reviews.llvm.org/D155548
2023-10-10 13:27:03 +02:00
cor3ntin
49666ec038
[Clang] Fix constant evaluating a captured variable in a lambda (#68090)
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
2023-10-05 10:17:50 +02:00
Timm Baeder
5ef904b5da
[clang][ExprConst] Don't try to evaluate value-dependent DeclRefExprs (#67778)
The Expression here migth be value dependent, which makes us run into an
assertion later on. Just bail out early.

Fixes #67690
2023-10-05 08:42:34 +02:00
Corentin Jabot
af4751738d [C++] Implement "Deducing this" (P0847R7)
This patch implements P0847R7 (partially),
CWG2561 and CWG2653.

Reviewed By: aaron.ballman, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D140828
2023-10-02 14:33:02 +02:00
isuckatcs
c496aa34c0
[clang] Fix a crash from nested ArrayInitLoopExpr (#67722)
This patch makes sure that everything is cleaned up properly
when ExprConstant evaluates an ArrayInitLoopExpr.

Fixes #57135
2023-09-29 19:12:49 +02:00
Aaron Ballman
b7663760a5 Remove unsed parameter; NFC 2023-09-29 07:58:19 -04:00
Sam McCall
880fa7faa9 Revert "[clang][SemaCXX] Diagnose tautological uses of consteval if and is_constant_evaluated"
This reverts commit 491b2810fb7fe5f080fa9c4f5945ed0a6909dc92.

This change broke valid code and generated incorrect diagnostics, see
https://reviews.llvm.org/D155064
2023-09-27 18:58:01 +02:00
Takuya Shimizu
491b2810fb [clang][SemaCXX] Diagnose tautological uses of consteval if and is_constant_evaluated
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
2023-09-27 09:26:06 +09:00
Antonio Frighetto
660876a401 [clang] Bail out when handling union access with virtual inheritance
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
2023-09-14 08:48:59 +02:00
Timm Baeder
fedc982731
[clang][Diagnostics] Add source range to uninitialized diagnostics (#65896)
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;
      |           ^~~
```
2023-09-11 07:03:18 +02:00
Sergei Barannikov
18a628ec4e [AST] Use correct APSInt width when evaluating string literals
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
2023-09-05 19:14:09 +03:00
Richard Dzenis
e6d305e64f Add support of Windows Trace Logging macros
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
2023-09-04 16:54:42 +02:00
Ilya Biryukov
d703dcdfb0 [AST] Fix crash in evaluation of OpaqueExpr in Clangd
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
2023-08-28 17:10:44 +02:00
Kazu Hirata
7866c011f8 [AST] Modernize EvalResult (NFC) 2023-08-27 09:24:24 -07:00
Shafik Yaghmour
33b6b67462 [clang] Fix crash in __builtin_strncmp and other related builtin functions
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
2023-08-25 13:54:50 -07:00
Takuya Shimizu
615d812696 [clang][ExprConstant] Improve error message of compound assignment against uninitialized object
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
2023-08-25 16:08:07 +09:00
Corentin Jabot
3f98cdc815 [Clang] Always constant-evaluate operands of comparisons to nullptr
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
2023-08-24 16:11:10 +02:00
Takuya Shimizu
985a72b6b3 [clang][Diagnostics] Provide source range to integer-overflow warnings
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
2023-08-19 22:05:12 +09:00
Jianjian GUAN
28741a23c9 [clang][SVE] Rename isVLSTBuiltinType, NFC
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
2023-08-17 14:18:32 +08:00
Timm Bäder
871ee94141 [clang][ExprConst] Use call source range for 'in call to' diags
Differential Revision: https://reviews.llvm.org/D156604
2023-08-16 15:22:29 +02:00
Alejandro Aguirre
00158ae236 [clang] Enable constexpr on LZCNT/POPCNT MS extension intrinsics
As discussed on #46593 - this enables us to use __lzcnt / __popcnt intrinsics inside constexpr code.

Differential Revision: https://reviews.llvm.org/D157420
2023-08-14 11:33:33 +01:00
Timm Bäder
f6ee4e3f55 [clang][ExprConst] Add RHS source range to div by zero diags
Differential Revision: https://reviews.llvm.org/D157074
2023-08-09 15:48:50 +02:00
Timm Bäder
925ec544cf Revert "[clang][ExprConst] Add RHS source range to div by zero diags"
This reverts commit 74c141a467caf9ebb4835458bc4ffbedb172a63a.

Looks like this breaks a whole bunch of unexpected tests:
https://lab.llvm.org/buildbot/#/builders/109/builds/70813
2023-08-08 18:16:35 +02:00
Timm Bäder
74c141a467 [clang][ExprConst] Add RHS source range to div by zero diags
Differential Revision: https://reviews.llvm.org/D157074
2023-08-08 17:59:13 +02:00
Takuya Shimizu
24c91d4432 [clang][ExprConstant] Fix crash on uninitialized base class subobject
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
2023-08-08 15:53:17 +09:00
Nick Desaulniers
610ec954e1 [clang] allow const structs/unions/arrays to be constant expressions for C
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
2023-08-02 15:32:37 -07:00
Takuya Shimizu
e90f4fc6ac [clang][ExprConstant] Print template arguments when describing stack frame
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
2023-07-31 17:05:56 +09:00
Corentin Jabot
45ab2b48bd [Clang] Improve the handling of large arrays evaluation.
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
2023-07-28 14:38:22 +02:00
Timm Bäder
81fb216245 [clang][Diagnostics] Provide source range to invalid casts in const expr
Differential Revision: https://reviews.llvm.org/D153241
2023-07-28 12:28:45 +02:00
Timm Bäder
7a3ad8ed77 [clang] Provide source range to 'invalid subexpr in const expr' diags
Differential Revision: https://reviews.llvm.org/D150566
2023-07-26 09:12:11 +02:00
Nick Desaulniers
b54294e2c9 [clang][ConstantEmitter] have tryEmitPrivate[ForVarInit] try ConstExprEmitter fast-path first
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
2023-07-24 13:50:45 -07:00
Corentin Jabot
47ccfd7a89 [Clang] Implement P2741R3 - user-generated static_assert messages
Reviewed By: #clang-language-wg, aaron.ballman

Differential Revision: https://reviews.llvm.org/D154290
2023-07-20 08:33:19 +02:00
Sindhu Chittireddy
e9877eca40 [NFC] Initialize class member pointers to nullptr.
Fix clang-format issues in surrounding code.
Differential revision: https://reviews.llvm.org/D153892
2023-07-12 11:04:38 -07:00
Timm Bäder
a83079f754 [clang][ConstExpr][NFC] Make Frame::describe() const 2023-07-09 15:49:32 +02:00
yronglin
36f67434f7 [AST] Stop evaluate constant expression if the condition expression which in switch statement contains errors
This fix issue: https://github.com/llvm/llvm-project/issues/63453

```
constexpr int foo(unsigned char c) {
    switch (f) {
    case 0:
        return 7;
    default:
        break;
    }
    return 0;
}

static_assert(foo('d'));

```

Reviewed By: aaron.ballman, erichkeane, hokein

Differential Revision: https://reviews.llvm.org/D153296
2023-07-07 19:56:47 +08:00
Timm Bäder
3ec12740d0 [clang][NFC] Move two declarations closer to their point of use 2023-07-05 08:54:24 +02:00
Aaron Ballman
7b69eabdc1 [C11] Correct global atomic pointer initialization from an integer constant
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
2023-07-02 14:41:21 -04:00
Takuya Shimizu
f6be96aa4e [clang][ExprConstant] Fix display of syntactically-invalid note for member function calls
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
2023-06-28 00:19:46 +09:00
Corentin Jabot
f27afedc6c [Clang] Implement P2738R1 - constexpr cast from void*
Reviewed By: #clang-language-wg, erichkeane

Differential Revision: https://reviews.llvm.org/D153702
2023-06-26 16:45:07 +02:00
Elliot Goodrich
b0abd4893f [llvm] Add missing StringExtras.h includes
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.
2023-06-25 15:42:22 +01:00
Manna, Soumi
5e12f5ab2d [CLANG] Fix uninitialized scalar field issues
Reviewed By: erichkeane, steakhal, tahonermann, shafik

Differential Revision: https://reviews.llvm.org/D150744
2023-06-22 12:09:14 -07:00
Serge Pavlov
7dd387d297 [clang] Add __builtin_isfpclass
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
2023-06-18 22:53:32 +07:00
Dimitry Andric
69d42eef4b [Clang] Show type in enum out of range diagnostic
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
2023-06-14 20:34:19 +02:00
Nick Desaulniers
9daab7fb02 [ExprConstant] fix ICE from Evaluate on _Atomic structs
Fixes two crashes reported by @efriedma and @ahatanak, as per
@ahatanak's analysis.

Link: https://reviews.llvm.org/D151587#4397446
Link: https://reviews.llvm.org/D151587#4399684

Reviewed By: ahatanak, aaron.ballman

Differential Revision: https://reviews.llvm.org/D152303
2023-06-08 13:20:24 -07:00