Our rules to determine if the throw expression are within the variable
scope were giving a false negative result in case the throw expression
would appear within a decltype in a nested function declaration.
Per P2266R3, the relevant rule is: [expr.prim.id.unqual]/2
```
if the id-expression (possibly parenthesized) is the operand of a throw-expression, and names an implicitly movable entity that belongs to a scope that does not contain the compound-statement of the innermost lambda-expression, try-block , or function-try-block (if any) whose compound-statement or ctor-initializer encloses the throw-expression.
```
This fixes PR54341.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D127075
This patch adds support for the conditional (ternary) operator on SVE
scalable vector types in C++, matching the behaviour for NEON vector
types. Like the conditional operator for NEON types, this is disabled in
C mode.
Differential Revision: https://reviews.llvm.org/D124091
This reverts commit b0bc93da92.
Changes: `s/_WIN32/_WIN64/g` in clang/test/SemaCXX/attr-trivial-abi.cpp.
The calling convention is specific to 64-bit windows. It's even in the name: `CCK_MicrosoftWin64`.
After this, the test passes with both `-triple i686-pc-win32` and `-triple x86_64-pc-win32`. Phew!
Reviewed By: gribozavr2
Differential Revision: https://reviews.llvm.org/D123059
This is extended to all `std::` functions that take a reference to a
value and return a reference (or pointer) to that same value: `move`,
`forward`, `move_if_noexcept`, `as_const`, `addressof`, and the
libstdc++-specific function `__addressof`.
We still require these functions to be declared before they can be used,
but don't instantiate their definitions unless their addresses are
taken. Instead, code generation, constant evaluation, and static
analysis are given direct knowledge of their effect.
This change aims to reduce various costs associated with these functions
-- per-instantiation memory costs, compile time and memory costs due to
creating out-of-line copies and inlining them, code size at -O0, and so
on -- so that they are not substantially more expensive than a cast.
Most of these improvements are very small, but I measured a 3% decrease
in -O0 object file size for a simple C++ source file using the standard
library after this change.
We now automatically infer the `const` and `nothrow` attributes on these
now-builtin functions, in particular meaning that we get a warning for
an unused call to one of these functions.
In C++20 onwards, we disallow taking the addresses of these functions,
per the C++20 "addressable function" rule. In earlier language modes, a
compatibility warning is produced but the address can still be taken.
The same infrastructure is extended to the existing MSVC builtin
`__GetExceptionInfo`, which is now only recognized in namespace `std`
like it always should have been.
This is a re-commit of
fc30901096,
a571f82a50,
64c045e25b, and
de6ddaeef3,
and reverts aa643f455a.
This change also includes a workaround for users using libc++ 3.1 and
earlier (!!), as apparently happens on AIX, where std::move sometimes
returns by value.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123345
Revert "Fixup D123950 to address revert of D123345"
This reverts commit aa643f455a.
This reverts commit 69dd89fdcb.
This reverts commit 04000c2f92.
The current states breaks libstdc++ usage (https://reviews.llvm.org/D119136#3455423).
The fixup has been reverted as it caused other valid code to be disallowed.
I think we should start from the clean state by reverting all relevant commits.
This is extended to all `std::` functions that take a reference to a
value and return a reference (or pointer) to that same value: `move`,
`forward`, `move_if_noexcept`, `as_const`, `addressof`, and the
libstdc++-specific function `__addressof`.
We still require these functions to be declared before they can be used,
but don't instantiate their definitions unless their addresses are
taken. Instead, code generation, constant evaluation, and static
analysis are given direct knowledge of their effect.
This change aims to reduce various costs associated with these functions
-- per-instantiation memory costs, compile time and memory costs due to
creating out-of-line copies and inlining them, code size at -O0, and so
on -- so that they are not substantially more expensive than a cast.
Most of these improvements are very small, but I measured a 3% decrease
in -O0 object file size for a simple C++ source file using the standard
library after this change.
We now automatically infer the `const` and `nothrow` attributes on these
now-builtin functions, in particular meaning that we get a warning for
an unused call to one of these functions.
In C++20 onwards, we disallow taking the addresses of these functions,
per the C++20 "addressable function" rule. In earlier language modes, a
compatibility warning is produced but the address can still be taken.
The same infrastructure is extended to the existing MSVC builtin
`__GetExceptionInfo`, which is now only recognized in namespace `std`
like it always should have been.
This is a re-commit of
fc30901096,
a571f82a50, and
64c045e25b
which were reverted in
e75d8b7037
due to a crasher bug where CodeGen would emit a builtin glvalue as an
rvalue if it constant-folds.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123345
We still require these functions to be declared before they can be used,
but don't instantiate their definitions unless their addresses are
taken. Instead, code generation, constant evaluation, and static
analysis are given direct knowledge of their effect.
This change aims to reduce various costs associated with these functions
-- per-instantiation memory costs, compile time and memory costs due to
creating out-of-line copies and inlining them, code size at -O0, and so
on -- so that they are not substantially more expensive than a cast.
Most of these improvements are very small, but I measured a 3% decrease
in -O0 object file size for a simple C++ source file using the standard
library after this change.
We now automatically infer the `const` and `nothrow` attributes on these
now-builtin functions, in particular meaning that we get a warning for
an unused call to one of these functions.
In C++20 onwards, we disallow taking the addresses of these functions,
per the C++20 "addressable function" rule. In earlier language modes, a
compatibility warning is produced but the address can still be taken.
The same infrastructure is extended to the existing MSVC builtin
`__GetExceptionInfo`, which is now only recognized in namespace `std`
like it always should have been.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123345
Implement P2036R3.
Captured variables by copy (explicitely or not), are deduced
correctly at the point we know whether the lambda is mutable,
and ill-formed before that.
Up until now, the entire lambda declaration up to the start of the body would be parsed in the parent scope, such that capture would not be available to look up.
The scoping is changed to have an outer lambda scope, followed by the lambda prototype and body.
The lambda scope is necessary because there may be a template scope between the start of the lambda (to which we want to attach the captured variable) and the prototype scope.
We also need to introduce a declaration context to attach the captured variable to (and several parts of clang assume captures are handled from the call operator context), before we know the type of the call operator.
The order of operations is as follow:
* Parse the init capture in the lambda's parent scope
* Introduce a lambda scope
* Create the lambda class and call operator
* Add the init captures to the call operator context and the lambda scope. But the variables are not capured yet (because we don't know their type).
Instead, explicit captures are stored in a temporary map that conserves the order of capture (for the purpose of having a stable order in the ast dumps).
* A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures.
* The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context, we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known).
* The lambda qualifiers are parsed, at this point We can switch (for the second time) inside the lambda context, unset the flag indicating that we have not parsed the lambda qualifiers,
record the lambda is mutable and capture the explicit variables.
* We can parse the rest of the lambda type, transform the lambda and call operator's types and also transform the call operator to a template function decl where necessary.
At this point, both captures and parameters can be injected in the body's scope. When trying to capture an implicit variable, if we are before the qualifiers of a lambda, we need to remember that the variables are still in the parent's context (rather than in the call operator's).
Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu
Differential Revision: https://reviews.llvm.org/D119136
Implement P2036R3.
Captured variables by copy (explicitely or not), are deduced
correctly at the point we know whether the lambda is mutable,
and ill-formed before that.
Up until now, the entire lambda declaration up to the start
of the body would be parsed in the parent scope, such that
captures would not be available to look up.
The scoping is changed to have an outer lambda scope,
followed by the lambda prototype and body.
The lambda scope is necessary because there may be a template scope
between the start of the lambda (to which we want to attach
the captured variable) and the prototype scope.
We also need to introduce a declaration context to attach the captured
variable to (and several parts of clang assume captures are handled from
the call operator context), before we know the type of the call operator.
The order of operations is as follow:
* Parse the init capture in the lambda's parent scope
* Introduce a lambda scope
* Create the lambda class and call operator
* Add the init captures to the call operator context and the lambda scope.
But the variables are not capured yet (because we don't know their type).
Instead, explicit captures are stored in a temporary map that
conserves the order of capture (for the purpose of having a stable order in the ast dumps).
* A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures.
* The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context,
we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known).
* The lambda qualifiers are parsed, at this point,
we can switch (for the second time) inside the lambda context,
unset the flag indicating that we have not parsed the lambda qualifiers,
record the lambda is mutable and capture the explicit variables.
* We can parse the rest of the lambda type, transform the lambda and call operator's types and also
transform the call operator to a template function decl where necessary.
At this point, both captures and parameters can be injected in the body's scope.
When trying to capture an implicit variable, if we are before the qualifiers of a lambda,
we need to remember that the variables are still in the parent's context (rather than in the call operator's).
This is a recommit of adff142dc2 after a fix in d8d793f29b
Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu
Differential Revision: https://reviews.llvm.org/D119136
This reverts commit adff142dc2.
This broke clang bootstrap: it made existing C++ code in LLVM invalid:
llvm/include/llvm/CodeGen/LiveInterval.h:630:53: error: captured variable 'Idx' cannot appear here
[=](std::remove_reference_t<decltype(*Idx)> V,
^
Implement P2036R3.
Captured variables by copy (explicitely or not), are deduced
correctly at the point we know whether the lambda is mutable,
and ill-formed before that.
Up until now, the entire lambda declaration up to the start of the body would be parsed in the parent scope, such that capture would not be available to look up.
The scoping is changed to have an outer lambda scope, followed by the lambda prototype and body.
The lambda scope is necessary because there may be a template scope between the start of the lambda (to which we want to attach the captured variable) and the prototype scope.
We also need to introduce a declaration context to attach the captured variable to (and several parts of clang assume captures are handled from the call operator context), before we know the type of the call operator.
The order of operations is as follow:
* Parse the init capture in the lambda's parent scope
* Introduce a lambda scope
* Create the lambda class and call operator
* Add the init captures to the call operator context and the lambda scope. But the variables are not capured yet (because we don't know their type).
Instead, explicit captures are stored in a temporary map that conserves the order of capture (for the purpose of having a stable order in the ast dumps).
* A flag is set on LambdaScopeInfo to indicate that we have not yet injected the captures.
* The parameters are parsed (in the parent context, as lambda mangling recurses in the parent context, we couldn't mangle a lambda that is attached to the context of a lambda whose type is not yet known).
* The lambda qualifiers are parsed, at this point We can switch (for the second time) inside the lambda context, unset the flag indicating that we have not parsed the lambda qualifiers,
record the lambda is mutable and capture the explicit variables.
* We can parse the rest of the lambda type, transform the lambda and call operator's types and also transform the call operator to a template function decl where necessary.
At this point, both captures and parameters can be injected in the body's scope. When trying to capture an implicit variable, if we are before the qualifiers of a lambda, we need to remember that the variables are still in the parent's context (rather than in the call operator's).
Reviewed By: aaron.ballman, #clang-language-wg, ChuanqiXu
Differential Revision: https://reviews.llvm.org/D119136
Clang fails to diagnose:
```
void test() {
int j = 0;
for (int i = 0; i < 1000; i++)
j++;
return;
}
```
Reason: Missing support for UnaryOperator.
We should not warn with volatile variables... so add check for it.
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D122271
This reverts commit 56d46b36fc.
The LIT test SemaCXX/attr-trivial-abi.cpp is failing with 32bit build on
Windows. All the lines with the ifdef WIN32 are asserting but they are
not expected to. It looks like the LIT test was not tested on a 32bit
build of the compiler.
For the following code,
void test() {
volatile int j = 0;
for (int i = 0; i < 1000; i++)
j += 1;
return;
}
If compiled with
clang -g -Wall -Werror -S -emit-llvm test.c
we will see the following error:
test.c:2:6: error: variable 'j' set but not used [-Werror,-Wunused-but-set-variable]
volatile int j = 0;
^
This is not quite right since 'j' is indeed used due to '+=' operator.
gcc doesn't emit error either in this case.
Also if we change 'j += 1' to 'j++', the warning will disappear
with latest clang.
Note that clang will issue the warning if the volatile declaration
involves only simple assignment (var = ...).
To fix the issue, in function MaybeDecrementCount(), if the
operator is a compound assignment (i.e., +=, -=, etc.) and the
variable is volatile, the count for RefsMinusAssignments will be
decremented, similar to 'j++' case.
Differential Revision: https://reviews.llvm.org/D121715
This is the `ext_vector_type` alternative to D81083.
This patch extends Clang to allow 'bool' as a valid vector element type
(attribute ext_vector_type) in C/C++.
This is intended as the canonical type for SIMD masks and facilitates
clean vector intrinsic declarations. Vectors of i1 are supported on IR
level and below down to many SIMD ISAs, such as AVX512, ARM SVE (fixed
vector length) and the VE target (NEC SX-Aurora TSUBASA).
The RFC on cfe-dev: https://lists.llvm.org/pipermail/cfe-dev/2020-May/065434.html
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D88905
As far as I can tell, MSVC allows the relevant conversions for all
pointer types. Found compiling a Windows SDK header.
I've verified that the updated errors in MicrosoftExtensions.cpp match
the ones that MSVC actually emits, except for the one with a FIXME. (Not
sure why this wasn't done for the patch that added the tests.)
To make up for the missing error, add a warning that triggers on
conversions that drop the __unaligned qualfier.
Differential Revision: https://reviews.llvm.org/D120936
This reverts commit 852afed5e0.
Changes since D114732:
On PS4, we reverse the expectation that classes whose constructor is deleted are not trivially relocatable. Because, at the moment, only classes which are passed in registers are trivially relocatable, and PS4 allows passing in registers if the copy constructor is deleted, the original assertions were broken on PS4.
(This is kinda similar to DR1734.)
Reviewed By: gribozavr2
Differential Revision: https://reviews.llvm.org/D119017
This change enables library code to skip paired move-construction and destruction for `trivial_abi` types, as if they were trivially-movable and trivially-destructible. This offers an extension to the performance fix offered by `trivial_abi`: rather than only offering trivial-type-like performance for pass-by-value, it also offers it for library code that moves values but not as arguments.
For example, if we use `memcpy` for trivially relocatable types inside of vector reallocation, and mark `unique_ptr` as `trivial_abi` (via `_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI` / `_LIBCPP_ABI_UNSTABLE` / etc.), this would speed up `vector<unique_ptr>::push_back` by 40% on my benchmarks. (Though note that in this case, the compiler could have done this anyway, but happens not to due to the inlining horizon.)
If accepted, I intend to follow up with exactly such changes to library code, including and especially `std::vector`, making them use a trivial relocation operation on trivially relocatable types.
**D50119 and P1144:**
This change is very similar to D50119, which was rejected from Clang. (That change was an implementation of P1144, which is not yet part of the C++ standard.)
The intent of this change, rather than trying to pick a winning proposal for trivial relocation operations, is to extend the behavior of `trivial_abi` in a way that could be made compatible with any such proposal. If P1144 or any similar proposal were accepted, then `trivial_abi`, `__is_trivially_relocatable`, and everything else in this change would be redefined in terms of that.
**Safety:**
It's worth pointing out, specifically, that `trivial_abi` already implies trivial relocatability in a narrow sense: a `trivial_abi` type, when passed by value, has its constructor run in one location, and its destructor run in another, after the type has been trivially relocated (through registers).
Trivial relocatability optimizations could change the number of paired constructor/destructor calls, but this seems unlikely to matter for `trivial_abi` types.
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D114732
This reverts commit 80e2c58749.
The original patch causes a lot of warnings on gcc like:
llvm-project/clang/include/clang/Basic/Diagnostic.h:1329:3: warning:
base class ‘class clang::StreamingDiagnostic’ should be explicitly
initialized in the copy constructor [-Wextra]
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith, #libc, ldionne
Differential Revision: https://reviews.llvm.org/D110216
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D110216
This implements the following changes:
* AutoType retains sugared deduced-as-type.
* Template argument deduction machinery analyses the sugared type all the way
down. It would previously lose the sugar on first recursion.
* Undeduced AutoType will be properly canonicalized, including the constraint
template arguments.
* Remove the decltype node created from the decltype(auto) deduction.
As a result, we start seeing sugared types in a lot more test cases,
including some which showed very unfriendly `type-parameter-*-*` types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D110216
Fixes a compiler assert on passing a compile time integer to atomic builtins.
Assert introduced in D61522
Function changed from ->bool to ->Optional in D76646
Simplifies call sites to getIntegerConstantExpr to elide the now-redundant
isValueDependent checks.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D112159
This appears to be a think-o where the developer was trying to check for a null
pointer but was actually checking (redundantly) whether the optional held a
valid value or not. We now properly check the pointer for null.
This fixes PR51547.
This implements the new implicit conversion sequence to an incomplete
(unbounded) array type. It is mostly Richard Smith's work, updated to
trunk, testcases added and a few bugs fixed found in such testing.
It is not a complete implementation of p0388.
Differential Revision: https://reviews.llvm.org/D102645
Also do not warn on `#define _foo` or `#undef _foo`.
Only global scope names starting with _[a-z] are reserved, not the use
of such an identifier in any other context.
(This relands 59337263ab and makes sure comma operator
diagnostics are suppressed in a SFINAE context.)
While at it, add the diagnosis message "left operand of comma operator has no effect" (used by GCC) for comma operator.
This also makes Clang diagnose in the constant evaluation context which aligns with GCC/MSVC behavior. (https://godbolt.org/z/7zxb8Tx96)
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D103938
While at it, add the diagnosis message "left operand of comma operator has no effect" (used by GCC) for comma operator.
This also makes Clang diagnose in the constant evaluation context which aligns with GCC/MSVC behavior. (https://godbolt.org/z/7zxb8Tx96)
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D103938
See PR51862.
The consumers of the Elidable flag in CXXConstructExpr assume that
an elidable construction just goes through a single copy/move construction,
so that the source object is immediately passed as an argument and is the same
type as the parameter itself.
With the implementation of P2266 and after some adjustments to the
implementation of P1825, we started (correctly, as per standard)
allowing more cases where the copy initialization goes through
user defined conversions.
With this patch we stop using this flag in NRVO contexts, to preserve code
that relies on that assumption.
This causes no known functional changes, we just stop firing some asserts
in a cople of included test cases.
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D109800
While at it, add the diagnosis message "left operand of comma operator has no effect" (used by GCC) for comma operator.
This also makes Clang diagnose in the constant evaluation context which aligns with GCC/MSVC behavior. (https://godbolt.org/z/7zxb8Tx96)
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D103938
This patch fixes initializing temporaries, which are currently initialized
without an address space, meaning that no constructor can ever be applicable.
Now they will be constructed in the private addrspace.
Fixes the second issue in PR43296.
Reviewed By: Anastasia
Differential Revision: https://reviews.llvm.org/D107553
This renames the primary methods for creating a zero value to `getZero`
instead of `getNullValue` and renames predicates like `isAllOnesValue`
to simply `isAllOnes`. This achieves two things:
1) This starts standardizing predicates across the LLVM codebase,
following (in this case) ConstantInt. The word "Value" doesn't
convey anything of merit, and is missing in some of the other things.
2) Calling an integer "null" doesn't make any sense. The original sin
here is mine and I've regretted it for years. This moves us to calling
it "zero" instead, which is correct!
APInt is widely used and I don't think anyone is keen to take massive source
breakage on anything so core, at least not all in one go. As such, this
doesn't actually delete any entrypoints, it "soft deprecates" them with a
comment.
Included in this patch are changes to a bunch of the codebase, but there are
more. We should normalize SelectionDAG and other APIs as well, which would
make the API change more mechanical.
Differential Revision: https://reviews.llvm.org/D109483
- `this` used in lambda expression parameter declarations needs no capture.
- Set up CXXThisOverride for default template arguments of a lambda.
A similar fix to this is c3d2ebb60f.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D102531
The declaration for the global new function in C++ is generated in the compiler front-end. When examining exception propagation, we found that this is the largest root throw site propagator requiring unwind code to be generated for callers up the stack. Allowing this to be handled immediately with termination stops upward propagation and leads to significantly less landing pads generated. This in turns leads to a performance and .text size win.
With `-fnew-infallible` this annotates the declaration with `throw()` and `__attribute__((returns_nonnull))`. `throw()` allows the compiler to assume exceptions do not propagate out of new and eliminate it as a root throw site. Note that the definition of global new is user-replaceable so users should ensure that the one used follows these semantics.
Measuring internally, we're seeing at 0.5% CPU win in one of our large internal FB workload. Measuring on clang self-build (cd0a1226b5) we get:
thinlto/
"dwarfehprepare.NumCleanupLandingPadsRemaining": 153494,
"dwarfehprepare.NumNoUnwind": 26309,
thinlto_newinfallible/
"dwarfehprepare.NumCleanupLandingPadsRemaining": 143660,
"dwarfehprepare.NumNoUnwind": 28744,
a 1-143660/153494 = 6.4% reduction in landing pads and a 28744/26309 = 9.3% increase in the number of nounwind functions.
Testing:
ninja check-all
new test case to make sure these attributes are added correctly to global new.
Reviewed By: urnathan
Differential Revision: https://reviews.llvm.org/D105225
@kpn pointed out that the global variable initialization functions didn't
have the "strictfp" metadata set correctly, and @rjmccall said that there
was buggy code in SetFPModel and StartFunction, this patch is to solve
those problems. When Sema creates a FunctionDecl, it sets the
FunctionDeclBits.UsesFPIntrin to "true" if the lexical FP settings
(i.e. a combination of command line options and #pragma float_control
settings) correspond to ConstrainedFP mode. That bit is used when CodeGen
starts codegen for a llvm function, and it translates into the
"strictfp" function attribute. See bugs.llvm.org/show_bug.cgi?id=44571
Reviewed By: Aaron Ballman
Differential Revision: https://reviews.llvm.org/D102343
This cleanup patch refactors a bunch of functional duplicates of
getDecltypeForParenthesizedExpr into a common implementation.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: aaronpuchert
Differential Revision: https://reviews.llvm.org/D100713
Support Narrowing conversions to bool in if constexpr condition
under C++23 language mode.
Only if constexpr is implemented as the behavior of static_assert
is already conforming. Still need to work on explicit(bool) to
complete support.
When building the member call to a user conversion function during an
implicit cast, the expression was not being checked for immediate
invocation, so we were never adding the ConstantExpr node to AST.
This would cause the call to the user conversion operator to be emitted
even if it was constantexpr evaluated, and this would even trip an
assert when said user conversion was declared consteval:
`Assertion failed: !cast<FunctionDecl>(GD.getDecl())->isConsteval() && "consteval function should never be emitted", file clang\lib\CodeGen\CodeGenModule.cpp, line 3530`
Fixes PR48855.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D105446
According to https://eel.is/c++draft/over.literal
> double operator""_Bq(long double); // OK: does not use the reserved identifier _Bq ([lex.name])
> double operator"" _Bq(long double); // ill-formed, no diagnostic required: uses the reserved identifier _Bq ([lex.name])
Obey that rule by keeping track of the operator literal name status wrt. leading whitespace.
Fix: https://bugs.llvm.org/show_bug.cgi?id=50644
Differential Revision: https://reviews.llvm.org/D104299
This expands NRVO propagation for more cases:
Parse analysis improvement:
* Lambdas and Blocks with dependent return type can have their variables
marked as NRVO Candidates.
Variable instantiation improvements:
* Fixes crash when instantiating NRVO variables in Blocks.
* Functions, Lambdas, and Blocks which have auto return type have their
variables' NRVO status propagated. For Blocks with non-auto return type,
as a limitation, this propagation does not consider the actual return
type.
This also implements exclusion of VarDecls which are references to
dependent types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: Quuxplusone
Differential Revision: https://reviews.llvm.org/D99696
This change caused build errors related to move-only __block variables,
see discussion on https://reviews.llvm.org/D99696
> This expands NRVO propagation for more cases:
>
> Parse analysis improvement:
> * Lambdas and Blocks with dependent return type can have their variables
> marked as NRVO Candidates.
>
> Variable instantiation improvements:
> * Fixes crash when instantiating NRVO variables in Blocks.
> * Functions, Lambdas, and Blocks which have auto return type have their
> variables' NRVO status propagated. For Blocks with non-auto return type,
> as a limitation, this propagation does not consider the actual return
> type.
>
> This also implements exclusion of VarDecls which are references to
> dependent types.
>
> Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
>
> Reviewed By: Quuxplusone
>
> Differential Revision: https://reviews.llvm.org/D99696
This also reverts the follow-on change which was hard to tease apart
form the one above:
> "[clang] Implement P2266 Simpler implicit move"
>
> This Implements [[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2266r1.html|P2266 Simpler implicit move]].
>
> Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
>
> Reviewed By: Quuxplusone
>
> Differential Revision: https://reviews.llvm.org/D99005
This reverts commits 1e50c3d785 and
bf20631782.
At least LibreOffice has, for mainly historic reasons that would be hard to
change now, a class Any with an overloaded operator >>= that semantically does
not assign to the LHS but rather extracts into the (by-reference) RHS. Which
thus caused false positive -Wunused-but-set-parameter and
-Wunused-but-set-variable after those have been introduced recently.
This change is more conservative about the assumed semantics of overloaded
operators, excluding compound assignment operators but keeping plain operator =
ones. At least for LibreOffice, that strikes a good balance of not producing
false positives but still finding lots of true ones.
(The change to the BinaryOperator case in MaybeDecrementCount is necessary
because e.g. the template f4 test code in warn-unused-but-set-variables-cpp.cpp
turns the += into a BinaryOperator.)
Differential Revision: https://reviews.llvm.org/D103949
This expands NRVO propagation for more cases:
Parse analysis improvement:
* Lambdas and Blocks with dependent return type can have their variables
marked as NRVO Candidates.
Variable instantiation improvements:
* Fixes crash when instantiating NRVO variables in Blocks.
* Functions, Lambdas, and Blocks which have auto return type have their
variables' NRVO status propagated. For Blocks with non-auto return type,
as a limitation, this propagation does not consider the actual return
type.
This also implements exclusion of VarDecls which are references to
dependent types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: Quuxplusone
Differential Revision: https://reviews.llvm.org/D99696
<string> is currently the highest impact header in a clang+llvm build:
https://commondatastorage.googleapis.com/chromium-browser-clang/llvm-include-analysis.html
One of the most common places this is being included is the APInt.h header, which needs it for an old toString() implementation that returns std::string - an inefficient method compared to the SmallString versions that it actually wraps.
This patch replaces these APInt/APSInt methods with a pair of llvm::toString() helpers inside StringExtras.h, adjusts users accordingly and removes the <string> from APInt.h - I was hoping that more of these users could be converted to use the SmallString methods, but it appears that most end up creating a std::string anyhow. I avoided trying to use the raw_ostream << operators as well as I didn't want to lose having the integer radix explicit in the code.
Differential Revision: https://reviews.llvm.org/D103888
This expands NRVO propagation for more cases:
Parse analysis improvement:
* Lambdas and Blocks with dependent return type can have their variables
marked as NRVO Candidates.
Variable instantiation improvements:
* Fixes crash when instantiating NRVO variables in Blocks.
* Functions, Lambdas, and Blocks which have auto return type have their
variables' NRVO status propagated. For Blocks with non-auto return type,
as a limitation, this propagation does not consider the actual return
type.
This also implements exclusion of VarDecls which are references to
dependent types.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: Quuxplusone
Differential Revision: https://reviews.llvm.org/D99696
This renames the expression value categories from rvalue to prvalue,
keeping nomenclature consistent with C++11 onwards.
C++ has the most complicated taxonomy here, and every other language
only uses a subset of it, so it's less confusing to use the C++ names
consistently, and mentally remap to the C names when working on that
context (prvalue -> rvalue, no xvalues, etc).
Renames:
* VK_RValue -> VK_PRValue
* Expr::isRValue -> Expr::isPRValue
* SK_QualificationConversionRValue -> SK_QualificationConversionPRValue
* JSON AST Dumper Expression nodes value category: "rvalue" -> "prvalue"
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D103720
This addresses pr50497. The argument of a typeid expression is
unevaluated, *except* when it's a polymorphic type. We handle this by
parsing as unevaluated and then transforming to evaluated if we
discover it should have been an evaluated context.
We do the same in TreeTransform<Derived>::TransformCXXTypeidExpr,
entering unevaluated context before transforming and rebuilding the
typeid. But that's incorrect and can lead us to converting to
evaluated context twice -- and hitting an assert.
During normal template instantiation we're always cloning the
expression, but during generic lambda processing we do not necessarily
AlwaysRebuild, and end up with TransformDeclRefExpr unconditionally
calling MarkDeclRefReferenced around line 10226. That triggers the
assert.
// Mark it referenced in the new context regardless.
// FIXME: this is a bit instantiation-specific.
SemaRef.MarkDeclRefReferenced(E);
This patch makes 2 changes.
a) TreeTransform<Derived>::TransformCXXTypeidExpr only enters
unevaluated context if the typeid's operand is not a polymorphic
glvalue. If it is, it keeps the same evaluation context.
b) Sema::BuildCXXTypeId is altered to only transform to evaluated, if
the current context is unevaluated.
Differential Revision: https://reviews.llvm.org/D103258
Because half is limited to the `cl_khr_fp16` extension being enabled,
`DefaultLvalueConversion` can fail when it's not enabled.
The original assumption that it will never fail is therefore wrong now.
Fixes: PR47976
Reviewed By: Anastasia
Differential Revision: https://reviews.llvm.org/D103175
For a type-constraint in a lambda signature, this makes the lambda
contain an unexpanded pack; for requirements in a requires-expressions
it makes the requires-expression contain an unexpanded pack; otherwise
it's invalid.
See PR45088.
Compound requirement type constraints were using decltype(E) instead of
decltype((E)), as per `[expr.prim.req]p1.3.3`.
Since neither instantiation nor type dependence should matter for
the constraints, this uses an approach where a `decltype` type is not built,
and just the canonical type of the expression after template instantiation
is used on the requirement.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D98160
Updates __is_unsigned to have the same behavior as the standard
specifies. This is in line with 511dbd8, which applied the same change
to __is_signed.
Refs D67897.
Differential Revision: https://reviews.llvm.org/D98104
This patch implements the conditional select operator for
ext_vector_types in C++. It does so by using the same semantics as for
C.
D71463 added support for the conditional select operator for VectorType
in C++. Unfortunately the semantics between ext_vector_type in C are
different to VectorType in C++. Select for ext_vector_type is based on
the MSB of the condition vector, whereas for VectorType it is `!= 0`.
This unfortunately means that the behavior is inconsistent between
ExtVectorType and VectorType, but I think using the C semantics for
ExtVectorType in C++ as well should be less surprising for users.
Reviewed By: erichkeane, aaron.ballman
Differential Revision: https://reviews.llvm.org/D98055
See https://bugs.llvm.org/show_bug.cgi?id=42154.
GCC's __attribute__((align)) can reduce the alignment of a type when applied to
a typedef. However, functions which take a pointer or reference to the
original type are compiled assuming the original alignment. Therefore when any
such function is passed an object of the new, less-aligned type, an alignment
fault can occur. In particular, this applies to the constructor, which is
defined for the original type and called for the less-aligned object.
This change adds a warning whenever an pointer or reference to an object is
passed to a function that was defined for a more-aligned type.
The calls to ASTContext::getTypeAlignInChars seem change the order in which
record layouts are evaluated, which caused changes to the output of
-fdump-record-layouts. As such some tests needed to be updated:
* Use CHECK-LABEL rather than counting the number of "Dumping AST Record
Layout" headers.
* Check for end of line in labels, so that struct B1 doesn't match struct B
etc.
* Add --strict-whitespace, since the whitespace shows meaningful structure.
* The order in which record layouts are printed has changed in some cases.
* clang-format for regions changed
Differential Revision: https://reviews.llvm.org/D97187
Fix duplicate diagnostic for an over-aligned allocation with no matching
function, and add custom diagnostic for the case where the
non-allocating placement new was intended but <new> was not included.
Defaulted destructor was treated inconsistently, compared to other
compiler-generated functions.
When Sema::IdentifyCUDATarget() got called on just-created dtor which didn't
have implicit __host__ __device__ attributes applied yet, it would treat it as a
host function. That happened to (sometimes) hide the error when dtor referred
to a host-only functions.
Even when we had identified defaulted dtor as a HD function, we still treated it
inconsistently during selection of usual deallocators, where we did not allow
referring to wrong-side functions, while it is allowed for other HD functions.
This change brings handling of defaulted dtors in line with other HD functions.
Differential Revision: https://reviews.llvm.org/D94732
exception thrown during construction in a new-expression.
Instead, when performing deallocation function lookup for a
new-expression, ignore all destroying operator delete candidates, and
fall back to global operator delete if there is no member operator
delete other than a destroying operator delete.
Use of destroying operator delete only makes sense when there is an
object to destroy, which there isn't in this case. The language wording
doesn't cover this case; this oversight has been reported to WG21, with
the approach in this patch as the proposed fix.
The use of the new types introduced for PowerPC MMA instructions needs to be restricted.
We add a PowerPC function checking that the given type is valid in a context in which we don't allow MMA types.
This function is called from various places in Sema where we want to prevent the use of these types.
Differential Revision: https://reviews.llvm.org/D82035
folding to not constant folding.
Constant folding of ICEs is done as a GCC compatibility measure, but new
code was picking it up, presumably by accident, due to the bad default.
While here, also switch the flag from a bool to an enum to make it more
obvious what it means at call sites. This highlighted a couple of places
where our behavior is different between C++11 and C++14 due to switching
from checking for an ICE to checking for a converted constant
expression (where there is no 'fold' codepath).
Previously we failed to convert 'p' from array/function to pointer type,
and to represent the load of 'p' in the AST. The latter causes problems
for constant evaluation.