summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
Commit message (Collapse)AuthorAgeFilesLines
* PR45350: Handle unsized array CXXConstructExprs in constant evaluationRichard Smith2020-05-181-1/+22
| | | | | | of array new expressions with runtime bound. (cherry picked from commit 9a7eda1bece887ca9af085d79fe6e4fb8826dcda)
* [Concepts] Requires ExpressionsSaar Raz2020-01-241-0/+5
| | | | | | | | | | 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 (cherry picked from commit a0f50d731639350c7a79f140f026c27a18215531)
* Implement VectorType conditional operator GNU extension.Erich Keane2020-01-131-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Add builtins for aligning and checking alignment of pointers and integersAlex Richardson2020-01-091-11/+163
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* [OpenCL] Add ExtVectorElementExpr constant evaluation (PR42387)Sven van Haastregt2019-12-171-0/+25
| | | | | | | | 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
* [c++20] P1959R0: Remove support for std::*_equality.Richard Smith2019-12-161-42/+62
|
* If constant evaluation fails due to an unspecified pointer comparison,Richard Smith2019-12-161-2/+4
| | | | | produce a note saying that rather than the default "evaluation failed" note.
* PR44268: Fix crash if __builtin_object_size is applied to a heapRichard Smith2019-12-131-1/+1
| | | | allocation.
* [OpenCL] Handle address space conversions for constexpr (PR44177)Sven van Haastregt2019-12-091-0/+7
| | | | | | | | | | | | 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
* [c++20] Synthesis of defaulted comparison functions.Richard Smith2019-12-081-0/+30
| | | | | | 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.
* Remove Expr.h include from ASTContext.h, NFCReid Kleckner2019-12-061-2/+3
| | | | | | | ASTContext.h is popular, prune its includes. Expr.h brings in Attr.h, which is also expensive. Move BlockVarCopyInit to Expr.h to accomplish this.
* Fix crash-on-invalid-code in lambda constant evaluation.James Y Knight2019-12-041-0/+5
| | | | | | | | | | 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.
* [ConstExprPreter] Removed the flag forcing the use of the interpreterNandor Licker2019-11-271-73/+45
| | | | | | | | | | | | | | | | | | | 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
* Workaround for EvalInfo ctor for MSVC 2017Yaxun (Sam) Liu2019-11-261-3/+3
| | | | | | | | | | | | 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
* [NFC] Refactor representation of materialized temporariesTyker2019-11-191-7/+7
| | | | | | | | | | | | | | | Summary: this patch refactor representation of materialized temporaries to prevent an issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718 Reviewers: rsmith, martong, shafik Reviewed By: rsmith Subscribers: thakis, sammccall, ilya-biryukov, rnkovacs, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69360
* Revert "[NFC] Refactor representation of materialized temporaries"Nico Weber2019-11-171-7/+7
| | | | | | This reverts commit 08ea1ee2db5f9d6460fef1d79d0d1d1a5eb78982. It broke ./ClangdTests/FindExplicitReferencesTest.All on the bots, see comments on https://reviews.llvm.org/D69360
* [NFC] Refactor representation of materialized temporariesTyker2019-11-161-7/+7
| | | | | | | | | | | | | | | Summary: this patch refactor representation of materialized temporaries to prevent an issue raised by rsmith in https://reviews.llvm.org/D63640#inline-612718 Reviewers: rsmith, martong, shafik Reviewed By: rsmith Subscribers: rnkovacs, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69360
* [Diagnostics] Warn for std::is_constant_evaluated in constexpr modeDávid Bolvanský2019-10-311-1/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: constexpr int fn1() { if constexpr (std::is_constant_evaluated()) // condition is always true! return 0; else return 1; } constexpr int fn2() { if (std::is_constant_evaluated()) return 0; else return 1; } Solves PR42977 Reviewers: rsmith, aaron.ballman Reviewed By: rsmith Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69518
* Fix __attribute__((enable_if)) to treat arguments with side-effects asRichard Smith2019-10-301-11/+28
| | | | | | | | 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.
* PR43762: when implicitly changing the active union member for anRichard Smith2019-10-271-3/+10
| | | | | assignment during constant evaluation, only start the lifetime of trivially-default-constructible union members.
* [c++20] Add CXXRewrittenBinaryOperator to represent a comparisonRichard Smith2019-10-191-0/+7
| | | | | | | | operator that is rewritten as a call to multiple other operators. No functionality change yet: nothing creates these expressions. llvm-svn: 375305
* PR43674: fix incorrect constant evaluation of 'switch' where no caseRichard Smith2019-10-151-1/+1
| | | | | | label corresponds to the condition. llvm-svn: 374954
* [Concepts] Concept Specialization ExpressionsSaar Raz2019-10-151-0/+8
| | | | | | | | | | 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
* Revert 374882 "[Concepts] Concept Specialization Expressions"Nico Weber2019-10-151-8/+0
| | | | | | | | | | This reverts commit ec87b003823d63f3342cf648f55a134c1522e612. The test fails on Windows, see e.g. http://lab.llvm.org:8011/builders/clang-x64-windows-msvc/builds/11533/steps/stage%201%20check/logs/stdio Also revert follow-up r374893. llvm-svn: 374899
* [Concepts] Concept Specialization ExpressionsSaar Raz2019-10-151-0/+8
| | | | | | 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
* PR43629: Fix crash evaluating constexpr placement new on a subobject ofRichard Smith2019-10-101-1/+1
| | | | | | an out-of-lifetime object. llvm-svn: 374465
* [clang] prevent crash for nonnull attribut in constant context (Bug 43601)Gauthier Harnisch2019-10-101-6/+6
| | | | | | | | | | | | | | | | | | Summary: bug : https://bugs.llvm.org/show_bug.cgi?id=43601 Reviewers: rnk Reviewed By: rnk Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D68716 llvm-svn: 374285
* Factor out some duplication. NFC.Richard Smith2019-10-081-5/+3
| | | | llvm-svn: 374130
* Fix crash or wrong code bug if a lifetime-extended temporary contains aRichard Smith2019-10-081-2/+4
| | | | | | | | | | | | | | "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
* [c++20] Check for a class-specific operator delete when deleting anRichard Smith2019-10-071-0/+19
| | | | | | object of class type with a virtual destructor. llvm-svn: 373875
* Properly handle instantiation-dependent array bounds.Richard Smith2019-10-041-3/+3
| | | | | | | | | 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
* ExprConstant - silence static analyzer getAs<> null dereference warnings. NFCI.Simon Pilgrim2019-10-031-11/+10
| | | | | | 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
* Silence static analyzer getAs<RecordType> null dereference warnings. NFCI.Simon Pilgrim2019-10-031-1/+1
| | | | | | 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
* PR43519: don't inject a diagnostic when constant-evaulation of aRichard Smith2019-10-031-2/+5
| | | | | | | | | | 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 P0784R7: support placement new-expressions in constant evaluation.Richard Smith2019-10-031-19/+88
| | | | | | | | | 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
* For P0784R7: allow direct calls to operator new / operator delete fromRichard Smith2019-10-031-79/+276
| | | | | | std::allocator::{allocate,deallocate} in constant evaluation. llvm-svn: 373546
* Rename TypeNodes.def to TypeNodes.inc for consistency across allJohn McCall2019-10-021-2/+2
| | | | | | | | our autogenerated files. NFC. As requested by Nico Weber. llvm-svn: 373425
* Fix crash on constant-evaluation of pseudo-destruction of a pointer.Richard Smith2019-10-021-1/+1
| | | | | | | We got confused and thought we might be pseudo-destroying the pointee instead. llvm-svn: 373418
* During constant evaluation, handle CXXBindTemporaryExprs forRichard Smith2019-10-011-7/+6
| | | | | | array-of-class types, not just for class types. llvm-svn: 373279
* [c++20] Fix crash when constant-evaluating an assignment with aRichard Smith2019-10-011-1/+3
| | | | | | reference member access on its left-hand side. llvm-svn: 373276
* For now, disallow lifetime-extended temporaries with non-trivial (butRichard Smith2019-09-291-1/+9
| | | | | | | | | | | | 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
* Fix checking for permitted results of constant expressions.Richard Smith2019-09-291-25/+54
| | | | | | | | | 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
* For P0784R7: compute whether a variable has constant destruction if itRichard Smith2019-09-291-32/+104
| | | | | | | | | | 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
* For P0784R7: add support for explicit destructor calls andRichard Smith2019-09-271-30/+98
| | | | | | pseudo-destructor calls in constant evaluation. llvm-svn: 373122
* Fix use-after-free found in Clang's testsuite.Richard Smith2019-09-271-3/+6
| | | | | | | | | 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
* For P0784R7: add support for new (std::nothrow).Richard Smith2019-09-271-11/+33
| | | | llvm-svn: 373037
* For P0784R7: Add support for dynamic allocation with new / delete duringRichard Smith2019-09-271-51/+438
| | | | | | constant evaluation. llvm-svn: 373036
* For P0784R7: add support for constexpr destructors, and call them asRichard Smith2019-09-231-101/+448
| | | | | | | | | | | 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
* Remove outdated FIXME.Richard Smith2019-09-201-4/+0
| | | | llvm-svn: 372438
* Fix assertion failure when constant evaluation of a switch jumps over anRichard Smith2019-09-201-0/+27
| | | | | | uninitialized variable in an init-statement of a 'for' or 'if'. llvm-svn: 372437
OpenPOWER on IntegriCloud