This patch is the last prerequisite to switch the default behaviour to -fno-lax-vector-conversions in the future.
The first path ;D124093; fixed the altivec implicit castings.
Reviewed By: amyk
Differential Revision: https://reviews.llvm.org/D126540
This patch allows the same implicit conversions for vector-scalar
operations in SVE that are allowed for NEON.
Depends on D126377
Reviewed By: c-rhodes
Differential Revision: https://reviews.llvm.org/D126380
This patch corrects some diagnostics for the SVE sizeless vector
operators, including correctly diagnosing when the vectors are
different sizes.
Differential Revision: https://reviews.llvm.org/D126377
We should not mark a function as "referenced" if we call it within a
ConstantExpr, because the expression will be folded to a value in LLVM
IR. To prevent emitting consteval function declarations, we should not "jump
over" a ConstantExpr when it is a top-level ParmVarDecl's subexpression.
Fixes https://github.com/llvm/llvm-project/issues/48230
Reviewed By: erichkeane, aaron.ballman, ChuanqiXu
Differenitial Revision: https://reviews.llvm.org/D119646
This ensures that a deduced type like __auto_type matches the correct
association instead of matching all associations.
This addresses a regression from e4a42c5b64Fixes#55702
New diagnostics were added for unreachable generic selection expression
associations in ca75ac5f04, but it did
not account for a difference in behavior between C and C++ regarding
lvalue to rvalue conversions. So we would issue diagnostics about a
selection being unreachable and then reach it. This corrects the
diagnostic behavior in that case.
Differential Revision: https://reviews.llvm.org/D125882
The controlling expression of a _Generic selection expression undergoes
lvalue conversion, array conversion, and function conversion before
picking the association. This means that array types, function types,
and qualified types are all unreachable code if they're used as an
association. I've been caught by this twice in the past few months and
I figure that if a WG14 member can't seem to remember this rule, users
are also likely to struggle with it. So this adds an on-by-default
unreachable code diagnostic for generic selection expression
associations.
Note, we don't have to worry about function types as those are already
a constraint violation which generates an error.
Differential Revision: https://reviews.llvm.org/D125259
If the operand to `sizeof` is an expression of VLA type, the operand is
still evaluated, so we should not issue a diagnostic about ignoring the
side effects in this case, as they're not actually ignored.
Fixes#48010
We were failing to check if the controlling expression is dependent or
not when testing whether it has side effects. This would trigger an
assertion. Instead, if the controlling expression is dependent, we
suppress the check and diagnostic.
This fixes Issue 50227.
In C++ and C2x, we would avoid calling ImplicitlyDefineFunction at all,
but in OpenCL mode we would still call the function and have it produce
an error diagnostic. Instead, we now have a helper function to
determine when implicit function definitions are allowed and we use
that to determine whether to call ImplicitlyDefineFunction so that the
behavior is more consistent across language modes.
This changes the diagnostic behavior from telling the users that an
implicit function declaration is not allowed in OpenCL to reporting use
of an unknown identifier and going through typo correction, as done in
C++ and C2x.
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.
The previous code unneccessarily duplicated the creation of a diagnostic
where the only difference was the `AssignmentAction` being passed.
rdar://88664722
Differential Revision: https://reviews.llvm.org/D124054
C89 had a questionable feature where the compiler would implicitly
declare a function that the user called but was never previously
declared. The resulting function would be globally declared as
extern int func(); -- a function without a prototype which accepts zero
or more arguments.
C99 removed support for this questionable feature due to severe
security concerns. However, there was no deprecation period; C89 had
the feature, C99 didn't. So Clang (and GCC) both supported the
functionality as an extension in C99 and later modes.
C2x no longer supports that function signature as it now requires all
functions to have a prototype, and given the known security issues with
the feature, continuing to support it as an extension is not tenable.
This patch changes the diagnostic behavior for the
-Wimplicit-function-declaration warning group depending on the language
mode in effect. We continue to warn by default in C89 mode (due to the
feature being dangerous to use). However, because this feature will not
be supported in C2x mode, we've diagnosed it as being invalid for so
long, the security concerns with the feature, and the trivial
workaround for users (declare the function), we now default the
extension warning to an error in C99-C17 mode. This still gives users
an easy workaround if they are extensively using the extension in those
modes (they can disable the warning or use -Wno-error to downgrade the
error), but the new diagnostic makes it more clear that this feature is
not supported and should be avoided. In C2x mode, we no longer allow an
implicit function to be defined and treat the situation the same as any
other lookup failure.
Differential Revision: https://reviews.llvm.org/D122983
Partially implement the proposed resolution to CWG2569.
D119136 broke some libstdc++ code, as P2036R3, implemented as a DR to
C++11 made ill-formed some previously valid and innocuous code.
We resolve this issue to allow decltype(x) - but not decltype((x)
to appear in the parameter list of a lambda that capture x by copy.
Unlike CWG2569, we do not extend that special treatment to
sizeof/noexcept yet, as the resolution has not been approved yet
and keeping the review small allows a quicker fix of impacted code.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123909
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
This catches places where a function without a prototype is
accidentally used, potentially passing an incorrect number of
arguments, and is a follow-up to the work done in
https://reviews.llvm.org/D122895 and described in the RFC
(https://discourse.llvm.org/t/rfc-enabling-wstrict-prototypes-by-default-in-c).
The diagnostic is grouped under the new -Wdeprecated-non-prototypes
warning group and is enabled by default.
The diagnostic is disabled if the function being called was implicitly
declared (the user already gets an on-by-default warning about the
creation of the implicit function declaration, so no need to warn them
twice on the same line). Additionally, the diagnostic is disabled if
the declaration of the function without a prototype was in a location
where the user explicitly disabled deprecation warnings for functions
without prototypes (this allows the provider of the API a way to
disable the diagnostic at call sites because the lack of prototype is
intentional).
HLSL does not support pointers or references. This change generates
errors in sema for generating pointer, and reference types as well as
common operators (address-of, dereference, arrow), which are used with
pointers and are unsupported in HLSL.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123167
This patch enables shift operators on SVE vector types, as well as
supporting vector-scalar shift operations.
Shifts by a scalar that is wider than the contained type in the
vector are permitted but as in the C standard if the value is larger
than the width of the type the behavior is undefined.
Differential Revision: https://reviews.llvm.org/D123303
Undefined behaviour is just passed on to extract_element when the
index is out of bounds. Subscript on svbool_t is not allowed as
this doesn't really have meaningful semantics.
Differential Revision: https://reviews.llvm.org/D122732
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
For -fgpu-rdc, a host function may call an external kernel
which is defined in an archive of bitcode. Since this external
kernel is only referenced in host function, the device
bitcode does not contain reference to this external
kernel, then the linker will not try to resolve this external
kernel in the archive.
To fix this issue, host-used external kernels and device
variables are tracked. A global array containing pointers
to these external kernels and variables is emitted which
serves as an artificial references to the external kernels
and variables used by host.
Reviewed by: Artem Belevich
Differential Revision: https://reviews.llvm.org/D123441
Comparison operators on SVE types return a signed integer vector
of the same width as the incoming SVE type. This matches the existing
behaviour for NEON types.
Differential Revision: https://reviews.llvm.org/D122404
This builtin returns the address of a global instance of the
`std::source_location::__impl` type, which must be defined (with an
appropriate shape) before calling the builtin.
It will be used to implement std::source_location in libc++ in a
future change. The builtin is compatible with GCC's implementation,
and libstdc++'s usage. An intentional divergence is that GCC declares
the builtin's return type to be `const void*` (for
ease-of-implementation reasons), while Clang uses the actual type,
`const std::source_location::__impl*`.
In order to support this new functionality, I've also added a new
'UnnamedGlobalConstantDecl'. This artificial Decl is modeled after
MSGuidDecl, and is used to represent a generic concept of an lvalue
constant with global scope, deduplicated by its value. It's possible
that MSGuidDecl itself, or some of the other similar sorts of things
in Clang might be able to be refactored onto this more-generic
concept, but there's enough special-case weirdness in MSGuidDecl that
I gave up attempting to share code there, at least for now.
Finally, for compatibility with libstdc++'s <source_location> header,
I've added a second exception to the "cannot cast from void* to T* in
constant evaluation" rule. This seems a bit distasteful, but feels
like the best available option.
Reviewers: aaron.ballman, erichkeane
Differential Revision: https://reviews.llvm.org/D120159
In C, assignment expressions result in an rvalue whose type is the type
of the lhs of the assignment after it undergoes lvalue to rvalue
conversion. lvalue to rvalue conversion in C strips all qualifiers
including _Atomic.
We used getUnqualifiedType() which does not strip the _Atomic qualifier
when we should have used getAtomicUnqualifiedType(). This corrects the
usage and adds some comments to getUnqualifiedType() to make it more
clear that it does not strip _Atomic and that's on purpose (see C11
6.2.5p27).
This addresses Issue 48742.
Currently, Clang handles some qualifiers correctly for __auto_type, but
it does not handle the restrict or _Atomic qualifiers in the same way
that GCC does. This patch handles those qualifiers so that they attach
to the deduced type the same as const and volatile already do.
This fixes https://github.com/llvm/llvm-project/issues/53652
This patch extends the support for C/C++ operators for SVE
types to allow one of the arguments to be a scalar, in which
case a vector splat is performed.
Differential Revision: https://reviews.llvm.org/D121829
@mgehre-amd pointed out the following post-commit review feedback on
the changes in 8cba72177dcd8de5d37177dbaf2347e5c1f0f1e8:
As an example, the paper says 3wb /* Yields an _BitInt(3); two value
bits, one sign bit */.
So I would expect that 0xFwb gives _BitInt(5); four value bits, one
sign bit, but with this implementation I get _BitInt(2).
This is because ResultVal as 4 bits, and getMinSignedBits() inteprets
it as negative and thus says that 1 bit is enough to represent -1.
This corrects the behavior for calculating the bit-width and adds some
test coverage.
If we are equality comparing an FP literal with a value cast from a type
where the literal can't be represented, that's known true or false and
probably a programmer error.
Fixes issue #54222.
https://github.com/llvm/llvm-project/issues/54222
Note - I added the optimizer change with:
9397bdc67e
...and as discussed in the post-commit comments, that transform might be
too dangerous without this warning in place, so it was reverted to allow
this change first.
Differential Revision: https://reviews.llvm.org/D121306
Current ASTContext.getAttributedType() takes attribute kind,
ModifiedType and EquivType as the hash to decide whether an AST node
has been generated or note. But this is not enough for btf_type_tag
as the attribute might have the same ModifiedType and EquivType, but
still have different string associated with attribute.
For example, for a data structure like below,
struct map_value {
int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *a;
int __attribute__((btf_type_tag("tag2"))) __attribute__((btf_type_tag("tag4"))) *b;
};
The current ASTContext.getAttributedType() will produce
an AST similar to below:
struct map_value {
int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *a;
int __attribute__((btf_type_tag("tag1"))) __attribute__((btf_type_tag("tag3"))) *b;
};
and this is incorrect.
It is very difficult to use the current AttributedType as it is hard to
get the tag information. To fix the problem, this patch introduced
BTFTagAttributedType which is similar to AttributedType
in many ways but with an additional BTFTypeTagAttr. The tag itself can
be retrieved with BTFTypeTagAttr.
With the new BTFTagAttributed type, the debuginfo code can be greatly
simplified compared to previous TypeLoc based approach.
Differential Revision: https://reviews.llvm.org/D120296
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
WG14 adopted N2775 (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2775.pdf)
at our Feb 2022 meeting. This paper adds a literal suffix for
bit-precise types that automatically sizes the bit-precise type to be
the smallest possible legal _BitInt type that can represent the literal
value. The suffix chosen is wb (for a signed bit-precise type) which
can be combined with the u suffix (for an unsigned bit-precise type).
The preprocessor continues to operate as-if all integer types were
intmax_t/uintmax_t, including bit-precise integer types. It is a
constraint violation if the bit-precise literal is too large to fit
within that type in the context of the preprocessor (when still using
a pp-number preprocessing token), but it is not a constraint violation
in other circumstances. This allows you to make bit-precise integer
literals that are wider than what the preprocessor currently supports
in order to initialize variables, etc.
This patch implements support for the +, -, *, / and % operators on sizeless SVE
types. Support for these operators on svbool_t is excluded.
Differential Revision: https://reviews.llvm.org/D120323