This completes the implementation of P1091R3 and P1381R1.
This patch allow the capture of structured bindings
both for C++20+ and C++17, with extension/compat warning.
In addition, capturing an anonymous union member,
a bitfield, or a structured binding thereof now has a
better diagnostic.
We only support structured bindings - as opposed to other kinds
of structured statements/blocks. We still emit an error for those.
In addition, support for structured bindings capture is entirely disabled in
OpenMP mode as this needs more investigation - a specific diagnostic indicate the feature is not yet supported there.
Note that the rest of P1091R3 (static/thread_local structured bindings) was already implemented.
at the request of @shafik, i can confirm the correct behavior of lldb wit this change.
Fixes https://github.com/llvm/llvm-project/issues/54300
Fixes https://github.com/llvm/llvm-project/issues/54300
Fixes https://github.com/llvm/llvm-project/issues/52720
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D122768
This completes the implementation of P1091R3 and P1381R1.
This patch allow the capture of structured bindings
both for C++20+ and C++17, with extension/compat warning.
In addition, capturing an anonymous union member,
a bitfield, or a structured binding thereof now has a
better diagnostic.
We only support structured bindings - as opposed to other kinds
of structured statements/blocks. We still emit an error for those.
In addition, support for structured bindings capture is entirely disabled in
OpenMP mode as this needs more investigation - a specific diagnostic indicate the feature is not yet supported there.
Note that the rest of P1091R3 (static/thread_local structured bindings) was already implemented.
at the request of @shafik, i can confirm the correct behavior of lldb wit this change.
Fixes https://github.com/llvm/llvm-project/issues/54300
Fixes https://github.com/llvm/llvm-project/issues/54300
Fixes https://github.com/llvm/llvm-project/issues/52720
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D122768
We didn't check that a destructor's name matches the directly enclosing class if the class was dependent.
I enabled the check we already had for non-dependent types, which seems to work. Added appropriate tests.
Fixes GitHub issue #56772
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D130936
I went over the output of the following mess of a command:
(ulimit -m 2000000; ulimit -v 2000000; git ls-files -z |
parallel --xargs -0 cat | aspell list --mode=none --ignore-case |
grep -E '^[A-Za-z][a-z]*$' | sort | uniq -c | sort -n |
grep -vE '.{25}' | aspell pipe -W3 | grep : | cut -d' ' -f2 | less)
and proceeded to spend a few days looking at it to find probable typos
and fixed a few hundred of them in all of the llvm project (note, the
ones I found are not anywhere near all of them, but it seems like a
good start).
Differential Revision: https://reviews.llvm.org/D130827
According to [basic.def.odr]p14, the same redeclarations in different TU
but not attached to a named module are allowed. But we didn't take care
of concept decl for this condition. This patch tries to fix this
problem.
Reviewed By: ilya-biryukov
Differention Revision: https://reviews.llvm.org/D130614
Without this patch, clang will not wrap in an ElaboratedType node types written
without a keyword and nested name qualifier, which goes against the intent that
we should produce an AST which retains enough details to recover how things are
written.
The lack of this sugar is incompatible with the intent of the type printer
default policy, which is to print types as written, but to fall back and print
them fully qualified when they are desugared.
An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still
requires pointer alignment due to pre-existing bug in the TypeLoc buffer
handling.
---
Troubleshooting list to deal with any breakage seen with this patch:
1) The most likely effect one would see by this patch is a change in how
a type is printed. The type printer will, by design and default,
print types as written. There are customization options there, but
not that many, and they mainly apply to how to print a type that we
somehow failed to track how it was written. This patch fixes a
problem where we failed to distinguish between a type
that was written without any elaborated-type qualifiers,
such as a 'struct'/'class' tags and name spacifiers such as 'std::',
and one that has been stripped of any 'metadata' that identifies such,
the so called canonical types.
Example:
```
namespace foo {
struct A {};
A a;
};
```
If one were to print the type of `foo::a`, prior to this patch, this
would result in `foo::A`. This is how the type printer would have,
by default, printed the canonical type of A as well.
As soon as you add any name qualifiers to A, the type printer would
suddenly start accurately printing the type as written. This patch
will make it print it accurately even when written without
qualifiers, so we will just print `A` for the initial example, as
the user did not really write that `foo::` namespace qualifier.
2) This patch could expose a bug in some AST matcher. Matching types
is harder to get right when there is sugar involved. For example,
if you want to match a type against being a pointer to some type A,
then you have to account for getting a type that is sugar for a
pointer to A, or being a pointer to sugar to A, or both! Usually
you would get the second part wrong, and this would work for a
very simple test where you don't use any name qualifiers, but
you would discover is broken when you do. The usual fix is to
either use the matcher which strips sugar, which is annoying
to use as for example if you match an N level pointer, you have
to put N+1 such matchers in there, beginning to end and between
all those levels. But in a lot of cases, if the property you want
to match is present in the canonical type, it's easier and faster
to just match on that... This goes with what is said in 1), if
you want to match against the name of a type, and you want
the name string to be something stable, perhaps matching on
the name of the canonical type is the better choice.
3) This patch could expose a bug in how you get the source range of some
TypeLoc. For some reason, a lot of code is using getLocalSourceRange(),
which only looks at the given TypeLoc node. This patch introduces a new,
and more common TypeLoc node which contains no source locations on itself.
This is not an inovation here, and some other, more rare TypeLoc nodes could
also have this property, but if you use getLocalSourceRange on them, it's not
going to return any valid locations, because it doesn't have any. The right fix
here is to always use getSourceRange() or getBeginLoc/getEndLoc which will dive
into the inner TypeLoc to get the source range if it doesn't find it on the
top level one. You can use getLocalSourceRange if you are really into
micro-optimizations and you have some outside knowledge that the TypeLocs you are
dealing with will always include some source location.
4) Exposed a bug somewhere in the use of the normal clang type class API, where you
have some type, you want to see if that type is some particular kind, you try a
`dyn_cast` such as `dyn_cast<TypedefType>` and that fails because now you have an
ElaboratedType which has a TypeDefType inside of it, which is what you wanted to match.
Again, like 2), this would usually have been tested poorly with some simple tests with
no qualifications, and would have been broken had there been any other kind of type sugar,
be it an ElaboratedType or a TemplateSpecializationType or a SubstTemplateParmType.
The usual fix here is to use `getAs` instead of `dyn_cast`, which will look deeper
into the type. Or use `getAsAdjusted` when dealing with TypeLocs.
For some reason the API is inconsistent there and on TypeLocs getAs behaves like a dyn_cast.
5) It could be a bug in this patch perhaps.
Let me know if you need any help!
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D112374
Before the patch we calculated the NRVO candidate looking at the
variable's whole enclosing scope. The research in [P2025] shows that
looking at the variable's potential scope is better and covers more
cases where NRVO would be safe and desirable.
Many thanks to @Izaron for the original implementation.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D119792
Currently in Sema::ActOnEnumBody(...) when calculating NumPositiveBits we miss
the case where there is only a single enumerator with value zero and the case of
an empty enum. In both cases we end up with zero positive bits when in fact we
need one bit to store the value zero.
This PR updates the calculation to account for these cases.
Differential Revision: https://reviews.llvm.org/D130301
EnumDecl's promotion type is set either to the parsed type or calculated type
after completing its definition. When it's bool type and has no definition,
its promotion type is bool which is not allowed by clang.
Fixes#56560.
Differential Revision: https://reviews.llvm.org/D130210
re-land fixes an unwanted interaction with module-map modules, seen in
Greendragon testing.
This provides updates to
[class.mfct]:
Pre C++20 [class.mfct]p2:
A member function may be defined (8.4) in its class definition, in
which case it is an inline member function (7.1.2)
Post C++20 [class.mfct]p1:
If a member function is attached to the global module and is defined
in its class definition, it is inline.
and
[class.friend]:
Pre-C++20 [class.friend]p5
A function can be defined in a friend declaration of a
class . . . . Such a function is implicitly inline.
Post C++20 [class.friend]p7
Such a function is implicitly an inline function if it is attached
to the global module.
We add the output of implicit-inline to the TextNodeDumper, and amend
a couple of existing tests to account for this, plus add tests for the
cases covered above.
Differential Revision: https://reviews.llvm.org/D129045
This reverts commit 7c51f02eff because it
stills breaks the LLDB tests. This was re-landed without addressing the
issue or even agreement on how to address the issue. More details and
discussion in https://reviews.llvm.org/D112374.
Without this patch, clang will not wrap in an ElaboratedType node types written
without a keyword and nested name qualifier, which goes against the intent that
we should produce an AST which retains enough details to recover how things are
written.
The lack of this sugar is incompatible with the intent of the type printer
default policy, which is to print types as written, but to fall back and print
them fully qualified when they are desugared.
An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still
requires pointer alignment due to pre-existing bug in the TypeLoc buffer
handling.
---
Troubleshooting list to deal with any breakage seen with this patch:
1) The most likely effect one would see by this patch is a change in how
a type is printed. The type printer will, by design and default,
print types as written. There are customization options there, but
not that many, and they mainly apply to how to print a type that we
somehow failed to track how it was written. This patch fixes a
problem where we failed to distinguish between a type
that was written without any elaborated-type qualifiers,
such as a 'struct'/'class' tags and name spacifiers such as 'std::',
and one that has been stripped of any 'metadata' that identifies such,
the so called canonical types.
Example:
```
namespace foo {
struct A {};
A a;
};
```
If one were to print the type of `foo::a`, prior to this patch, this
would result in `foo::A`. This is how the type printer would have,
by default, printed the canonical type of A as well.
As soon as you add any name qualifiers to A, the type printer would
suddenly start accurately printing the type as written. This patch
will make it print it accurately even when written without
qualifiers, so we will just print `A` for the initial example, as
the user did not really write that `foo::` namespace qualifier.
2) This patch could expose a bug in some AST matcher. Matching types
is harder to get right when there is sugar involved. For example,
if you want to match a type against being a pointer to some type A,
then you have to account for getting a type that is sugar for a
pointer to A, or being a pointer to sugar to A, or both! Usually
you would get the second part wrong, and this would work for a
very simple test where you don't use any name qualifiers, but
you would discover is broken when you do. The usual fix is to
either use the matcher which strips sugar, which is annoying
to use as for example if you match an N level pointer, you have
to put N+1 such matchers in there, beginning to end and between
all those levels. But in a lot of cases, if the property you want
to match is present in the canonical type, it's easier and faster
to just match on that... This goes with what is said in 1), if
you want to match against the name of a type, and you want
the name string to be something stable, perhaps matching on
the name of the canonical type is the better choice.
3) This patch could exposed a bug in how you get the source range of some
TypeLoc. For some reason, a lot of code is using getLocalSourceRange(),
which only looks at the given TypeLoc node. This patch introduces a new,
and more common TypeLoc node which contains no source locations on itself.
This is not an inovation here, and some other, more rare TypeLoc nodes could
also have this property, but if you use getLocalSourceRange on them, it's not
going to return any valid locations, because it doesn't have any. The right fix
here is to always use getSourceRange() or getBeginLoc/getEndLoc which will dive
into the inner TypeLoc to get the source range if it doesn't find it on the
top level one. You can use getLocalSourceRange if you are really into
micro-optimizations and you have some outside knowledge that the TypeLocs you are
dealing with will always include some source location.
4) Exposed a bug somewhere in the use of the normal clang type class API, where you
have some type, you want to see if that type is some particular kind, you try a
`dyn_cast` such as `dyn_cast<TypedefType>` and that fails because now you have an
ElaboratedType which has a TypeDefType inside of it, which is what you wanted to match.
Again, like 2), this would usually have been tested poorly with some simple tests with
no qualifications, and would have been broken had there been any other kind of type sugar,
be it an ElaboratedType or a TemplateSpecializationType or a SubstTemplateParmType.
The usual fix here is to use `getAs` instead of `dyn_cast`, which will look deeper
into the type. Or use `getAsAdjusted` when dealing with TypeLocs.
For some reason the API is inconsistent there and on TypeLocs getAs behaves like a dyn_cast.
5) It could be a bug in this patch perhaps.
Let me know if you need any help!
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D112374
This reverts commit bdc6974f92 because it
breaks all the LLDB tests that import the std module.
import-std-module/array.TestArrayFromStdModule.py
import-std-module/deque-basic.TestDequeFromStdModule.py
import-std-module/deque-dbg-info-content.TestDbgInfoContentDequeFromStdModule.py
import-std-module/forward_list.TestForwardListFromStdModule.py
import-std-module/forward_list-dbg-info-content.TestDbgInfoContentForwardListFromStdModule.py
import-std-module/list.TestListFromStdModule.py
import-std-module/list-dbg-info-content.TestDbgInfoContentListFromStdModule.py
import-std-module/queue.TestQueueFromStdModule.py
import-std-module/stack.TestStackFromStdModule.py
import-std-module/vector.TestVectorFromStdModule.py
import-std-module/vector-bool.TestVectorBoolFromStdModule.py
import-std-module/vector-dbg-info-content.TestDbgInfoContentVectorFromStdModule.py
import-std-module/vector-of-vectors.TestVectorOfVectorsFromStdModule.py
https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/45301/
Without this patch, clang will not wrap in an ElaboratedType node types written
without a keyword and nested name qualifier, which goes against the intent that
we should produce an AST which retains enough details to recover how things are
written.
The lack of this sugar is incompatible with the intent of the type printer
default policy, which is to print types as written, but to fall back and print
them fully qualified when they are desugared.
An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still
requires pointer alignment due to pre-existing bug in the TypeLoc buffer
handling.
Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>
Differential Revision: https://reviews.llvm.org/D112374
This provides updates to
[class.mfct]:
Pre C++20 [class.mfct]p2:
A member function may be defined (8.4) in its class definition, in
which case it is an inline member function (7.1.2)
Post C++20 [class.mfct]p1:
If a member function is attached to the global module and is defined
in its class definition, it is inline.
and
[class.friend]:
Pre-C++20 [class.friend]p5
A function can be defined in a friend declaration of a
class . . . . Such a function is implicitly inline.
Post C++20 [class.friend]p7
Such a function is implicitly an inline function if it is attached
to the global module.
We add the output of implicit-inline to the TextNodeDumper, and amend
a couple of existing tests to account for this, plus add tests for the
cases covered above.
Differential Revision: https://reviews.llvm.org/D129045
The existing provision is not sufficient, it did not allow for the cases
where an implementation partition includes the primary module interface,
or for the case that an exported interface partition is contains a decl
that is then implemented in a regular implementation unit.
It is somewhat unfortunate that we have to compare top level module names
to achieve this, since built modules are not necessarily available.
TODO: It might be useful to cache a hash of the primary module name if
this test proves to be a significant load.
Differential Revision: https://reviews.llvm.org/D127624
This patch adds a new extension to the `omp begin / end declare variant`
support that causes it to apply to function declarations as well. This
is explicitly not done in the standard, but can be useful in some
situations so we should provide it as an extension. This will allow us
to uniquely bind and overload existing definitions with a simple
declaration using variants.
Reviewed By: jdoerfert
Differential Revision: https://reviews.llvm.org/D124624
Before D126061, Clang would warn about this code
```
struct X {
[[deprecated]] struct Y {};
};
```
with the warning
attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration
D126061 inadvertently caused this warning to no longer be emitted. This patch
restores the previous behavior.
The reason for the bug is that after D126061, C++11 attributes applied to a
member declaration are no longer placed in `DS.getAttributes()` but are instead
tracked in a separate list (`DeclAttrs`). In the case of a free-standing
decl-specifier-seq, we would simply ignore the contents of this list. Instead,
we now pass the list on to `Sema::ParsedFreeStandingDeclSpec()` so that it can
issue the appropriate warning.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D128499
MSVC's pragma optimize turns optimizations on or off based on the list
passed. At the moment, we only support an empty optimization list.
i.e. `#pragma optimize("", on | off)`
From MSVC's docs:
| Parameter | Type of optimization |
|-----------|--------------------------------------------------|
| g | Enable global optimizations. Deprecated |
| s or t | Specify short or fast sequences of machine code |
| y | Generate frame pointers on the program stack |
https://docs.microsoft.com/en-us/cpp/preprocessor/optimize?view=msvc-170
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D125723
This patch implements a necessary part of P0848, the overload resolution for destructors.
It is now possible to overload destructors based on constraints, and the eligible destructor
will be selected at the end of the class.
The approach this patch takes is to perform the overload resolution in Sema::ActOnFields
and to mark the selected destructor using a new property in FunctionDeclBitfields.
CXXRecordDecl::getDestructor is then modified to use this property to return the correct
destructor.
This closes https://github.com/llvm/llvm-project/issues/45614.
Reviewed By: #clang-language-wg, erichkeane
Differential Revision: https://reviews.llvm.org/D126194
For backwards compatiblity, we emit only a warning instead of an error if the
attribute is one of the existing type attributes that we have historically
allowed to "slide" to the `DeclSpec` just as if it had been specified in GNU
syntax. (We will call these "legacy type attributes" below.)
The high-level changes that achieve this are:
- We introduce a new field `Declarator::DeclarationAttrs` (with appropriate
accessors) to store C++11 attributes occurring in the attribute-specifier-seq
at the beginning of a simple-declaration (and other similar declarations).
Previously, these attributes were placed on the `DeclSpec`, which made it
impossible to reconstruct later on whether the attributes had in fact been
placed on the decl-specifier-seq or ahead of the declaration.
- In the parser, we propgate declaration attributes and decl-specifier-seq
attributes separately until we can place them in
`Declarator::DeclarationAttrs` or `DeclSpec::Attrs`, respectively.
- In `ProcessDeclAttributes()`, in addition to processing declarator attributes,
we now also process the attributes from `Declarator::DeclarationAttrs` (except
if they are legacy type attributes).
- In `ConvertDeclSpecToType()`, in addition to processing `DeclSpec` attributes,
we also process any legacy type attributes that occur in
`Declarator::DeclarationAttrs` (and emit a warning).
- We make `ProcessDeclAttribute` emit an error if it sees any non-declaration
attributes in C++11 syntax, except in the following cases:
- If it is being called for attributes on a `DeclSpec` or `DeclaratorChunk`
- If the attribute is a legacy type attribute (in which case we only emit
a warning)
The standard justifies treating attributes at the beginning of a
simple-declaration and attributes after a declarator-id the same. Here are some
relevant parts of the standard:
- The attribute-specifier-seq at the beginning of a simple-declaration
"appertains to each of the entities declared by the declarators of the
init-declarator-list" (https://eel.is/c++draft/dcl.dcl#dcl.pre-3)
- "In the declaration for an entity, attributes appertaining to that entity can
appear at the start of the declaration and after the declarator-id for that
declaration." (https://eel.is/c++draft/dcl.dcl#dcl.pre-note-2)
- "The optional attribute-specifier-seq following a declarator-id appertains to
the entity that is declared."
(https://eel.is/c++draft/dcl.dcl#dcl.meaning.general-1)
The standard contains similar wording to that for a simple-declaration in other
similar types of declarations, for example:
- "The optional attribute-specifier-seq in a parameter-declaration appertains to
the parameter." (https://eel.is/c++draft/dcl.fct#3)
- "The optional attribute-specifier-seq in an exception-declaration appertains
to the parameter of the catch clause" (https://eel.is/c++draft/except.pre#1)
The new behavior is tested both on the newly added type attribute
`annotate_type`, for which we emit errors, and for the legacy type attribute
`address_space` (chosen somewhat randomly from the various legacy type
attributes), for which we emit warnings.
Depends On D111548
Reviewed By: aaron.ballman, rsmith
Differential Revision: https://reviews.llvm.org/D126061
Post-commit feedback on https://reviews.llvm.org/D122895 pointed out
that the diagnostic wording for some code was using "declaration" in a
confusing way, such as:
int foo(); // warning: a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x
int foo(int arg) { // warning: a function declaration without a prototype is deprecated in all versions of C and is not supported in C2x
return 5;
}
And that we had other minor issues with the diagnostics being somewhat
confusing.
This patch addresses the confusion by reworking the implementation to
be a bit more simple and a bit less chatty. Specifically, it changes
the warning and note diagnostics to be able to specify "declaration" or
"definition" as appropriate, and it changes the function merging logic
so that the function without a prototype is always what gets warned on,
and the function with a prototype is sometimes what gets noted.
Additionally, when diagnosing a K&R C definition that is preceded by a
function without a prototype, we don't note the prior declaration, we
warn on it because it will also be changing behavior in C2x.
Differential Revision: https://reviews.llvm.org/D125814
This would allow more AST nodes being preserved for broken code, and
have a more consistent valid bit for ref-type var decl (currently, a
ref-type var decl with a broken initializer is valid).
Per https://reviews.llvm.org/D76831#1973053, the initializer of a variable
should play no part in its "invalid" bit.
Reviewed By: sammccall
Differential Revision: https://reviews.llvm.org/D122935
Clang has recently started diagnosing prototype redeclaration errors like [rG385e7df33046](https://reviews.llvm.org/rG385e7df33046d7292612ee1e3ac00a59d8bc0441)
This flagged legitimate issues in a codebase but was confusing to resolve because it actually conflicted with a function declaration from a system header and not from the one emitted with "note: ".
This patch updates the error handling to use the canonical declaration's source location instead to avoid misleading errors like the one described.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D126258
Most clients only used these methods because they wanted to be able to
extend or truncate to the same bit width (which is a no-op). Now that
the standard zext, sext and trunc allow this, there is no reason to use
the OrSelf versions.
The OrSelf versions additionally have the strange behaviour of allowing
extending to a *smaller* width, or truncating to a *larger* width, which
are also treated as no-ops. A small amount of client code relied on this
(ConstantRange::castOp and MicrosoftCXXNameMangler::mangleNumber) and
needed rewriting.
Differential Revision: https://reviews.llvm.org/D125557
The standard says:
The optional requires-clause ([temp.pre]) in an init-declarator or
member-declarator shall be present only if the declarator declares a
templated function ([dcl.fct]).
This implements that limitation, and updates the tests to the best of my
ability to capture the intent of the original checks.
Differential Revision: https://reviews.llvm.org/D125711
C89 allowed a type specifier to be elided with the resulting type being
int, aka implicit int behavior. This feature was subsequently removed
in C99 without a deprecation period, so implementations continued to
support the feature. Now, as with implicit function declarations, is a
good time to reevaluate the need for this support.
This patch allows -Wimplicit-int to issue warnings in C89 mode (off by
default), defaults the warning to an error in C99 through C17, and
disables support for the feature entirely in C2x. It also removes a
warning about missing declaration specifiers that really was just an
implicit int warning in disguise and other minor related cleanups.
Before C++20, MSVC treated any friend function declaration as a function declaration, so the following code would compile despite funGlob being declared after its first call:
```
class Glob {
public:
friend void funGlob();
void test() {
funGlob();
}
};
void funGlob() {}
```
This proposed patch mimics the MSVC behavior when in MSVC compatibility mode
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D124613
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.
Strutures of function pointers are a good surface area for attacks. We
should therefore randomize them unless explicitly told not to.
Reviewed By: aaron.ballman, MaskRay
Differential Revision: https://reviews.llvm.org/D123544
A record may have more than just FieldDecls in it. If so, then we're
likely to drop them if we only randomize the FieldDecls.
We need to be careful about anonymous structs/unions. Their fields are
made available in the RecordDecl as IndirectFieldDecls, which are listed
after the anonymous struct/union. The ordering doesn't appear to be
super important, however we place them unrandomized at the end of the
RecordDecl just in case. There's also the possiblity of
StaticAssertDecls. We also want those at the end.
All other non-FieldDecls we place at the top, just in case we get
something like:
struct foo {
enum e { BORK };
enum e a;
};
Link: https://github.com/KSPP/linux/issues/185
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D123958
Shader attribute is for shader library identify entry functions.
Here's an example,
[shader("pixel")]
float ps_main() : SV_Target {
return 1;
}
When compile this shader to library target like -E lib_6_3, compiler needs to know ps_main is an entry function for pixel shader. Shader attribute is to offer the information.
A new attribute HLSLShader is added to support shader attribute. It has an EnumArgument which included all possible shader stages.
Reviewed By: aaron.ballman, MaskRay
Differential Revision: https://reviews.llvm.org/D123907
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.
WG14 has elected to remove support for K&R C functions in C2x. The
feature was introduced into C89 already deprecated, so after this long
of a deprecation period, the committee has made an empty parameter list
mean the same thing in C as it means in C++: the function accepts no
arguments exactly as if the function were written with (void) as the
parameter list.
This patch implements WG14 N2841 No function declarators without
prototypes (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2841.htm)
and WG14 N2432 Remove support for function definitions with identifier
lists (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2432.pdf).
It also adds The -fno-knr-functions command line option to opt into
this behavior in other language modes.
Differential Revision: https://reviews.llvm.org/D123955
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
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
std::addressof, plus the libstdc++-specific std::__addressof.
This brings us to parity with the corresponding GCC behavior.
Remove STDBUILTIN macro that ended up not being used.
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
Given the declaration:
typedef void func_t(unsigned);
__attribute__((noreturn)) func_t func;
we would incorrectly determine that `func` had no prototype because the
`noreturn` attribute would convert the underlying type directly into a
FunctionProtoType, but the declarator for `func` itself was not one for
a function with a prototype. This adds an additional check for when the
declarator is a type representation for a function with a prototype.
When emitting a "conflicting types" warning for a function declaration,
it's more clear to diagnose the previous declaration specifically as
being a builtin if it one.
This is the template version of https://reviews.llvm.org/D114251.
This patch introduces a new template name kind (UsingTemplateName). The
UsingTemplateName stores the found using-shadow decl (and underlying
template can be retrieved from the using-shadow decl). With the new
template name, we can be able to find the using decl that a template
typeloc (e.g. TemplateSpecializationTypeLoc) found its underlying template,
which is useful for tooling use cases (include cleaner etc).
This patch merely focuses on adding the node to the AST.
Next steps:
- support using-decl in qualified template name;
- update the clangd and other tools to use this new node;
- add ast matchers for matching different kinds of template names;
Differential Revision: https://reviews.llvm.org/D123127
We did not implement C99 6.7.5.3p15 fully in that we missed the rule
for compatible function types where a prior declaration has a prototype
and a subsequent definition (not just declaration) has an empty
identifier list or an identifier list with a mismatch in parameter
arity. This addresses that situation by issuing an error on code like:
void f(int);
void f() {} // type conflicts with previous declaration
(Note: we already diagnose the other type conflict situations
appropriately, this was the only situation we hadn't covered that I
could find.)
It breaks arm build, there is no free bit for the extra
UsingShadowDecl in TemplateName::StorageType.
Reverting it to build the buildbot back until we comeup with a fix.
This reverts commit 5a5be4044f.
This is the template version of https://reviews.llvm.org/D114251.
This patch introduces a new template name kind (UsingTemplateName). The
UsingTemplateName stores the found using-shadow decl (and underlying
template can be retrieved from the using-shadow decl). With the new
template name, we can be able to find the using decl that a template
typeloc (e.g. TemplateSpecializationTypeLoc) found its underlying template,
which is useful for tooling use cases (include cleaner etc).
This patch merely focuses on adding the node to the AST.
Next steps:
- support using-decl in qualified template name;
- update the clangd and other tools to use this new node;
- add ast matchers for matching different kinds of template names;
Differential Revision: https://reviews.llvm.org/D123127
According to CWG 1394 and C++20 [dcl.fct.def.general]p2,
Clang should not diagnose incomplete types if function body is "= delete;".
For example:
```
struct Incomplete;
Incomplete f(Incomplete) = delete; // well-formed
```
Also close https://github.com/llvm/llvm-project/issues/52802
Differential Revision: https://reviews.llvm.org/D122981
The Randstruct feature is a compile-time hardening technique that
randomizes the field layout for designated structures of a code base.
Admittedly, this is mostly useful for closed-source releases of code,
since the randomization seed would need to be available for public and
open source applications.
Why implement it? This patch set enhances Clang’s feature parity with
that of GCC which already has the Randstruct feature. It's used by the
Linux kernel in certain structures to help thwart attacks that depend on
structure layouts in memory.
This patch set is a from-scratch reimplementation of the Randstruct
feature that was originally ported to GCC. The patches for the GCC
implementation can be found here:
https://www.openwall.com/lists/kernel-hardening/2017/04/06/14
Link: https://lists.llvm.org/pipermail/cfe-dev/2019-March/061607.html
Co-authored-by: Cole Nixon <nixontcole@gmail.com>
Co-authored-by: Connor Kuehl <cipkuehl@gmail.com>
Co-authored-by: James Foster <jafosterja@gmail.com>
Co-authored-by: Jeff Takahashi <jeffrey.takahashi@gmail.com>
Co-authored-by: Jordan Cantrell <jordan.cantrell@mail.com>
Co-authored-by: Nikk Forbus <nicholas.forbus@gmail.com>
Co-authored-by: Tim Pugh <nwtpugh@gmail.com>
Co-authored-by: Bill Wendling <isanbard@gmail.com>
Signed-off-by: Bill Wendling <isanbard@gmail.com>
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D121556
This reverts commit 3f0587d0c6.
Not all tests pass after a few rounds of fixes.
I spot one failure that std::shuffle (potentially different results with
different STL implementations) was misused and replaced it with llvm::shuffle,
but there appears to be another failure in a Windows build.
The latest failure is reported on https://reviews.llvm.org/D121556#3440383
Functions without prototypes in C (also known as K&R C functions) were
introduced into C89 as a deprecated feature and C2x is now reclaiming
that syntax space with different semantics. However, Clang's
-Wstrict-prototypes diagnostic is off-by-default (even in pedantic
mode) and does not suffice to warn users about issues in their code.
This patch changes the behavior of -Wstrict-prototypes to only diagnose
declarations and definitions which are not going to change behavior in
C2x mode, and enables the diagnostic in -pedantic mode. The diagnostic
is now specifically about the fact that the feature is deprecated.
It also adds -Wdeprecated-non-prototype, which is grouped under
-Wstrict-prototypes and diagnoses declarations or definitions which
will change behavior in C2x mode. This diagnostic is enabled by default
because the risk is higher for the user to continue to use the
deprecated feature.
Differential Revision: https://reviews.llvm.org/D122895
The Randstruct feature is a compile-time hardening technique that
randomizes the field layout for designated structures of a code base.
Admittedly, this is mostly useful for closed-source releases of code,
since the randomization seed would need to be available for public and
open source applications.
Why implement it? This patch set enhances Clang’s feature parity with
that of GCC which already has the Randstruct feature. It's used by the
Linux kernel in certain structures to help thwart attacks that depend on
structure layouts in memory.
This patch set is a from-scratch reimplementation of the Randstruct
feature that was originally ported to GCC. The patches for the GCC
implementation can be found here:
https://www.openwall.com/lists/kernel-hardening/2017/04/06/14
Link: https://lists.llvm.org/pipermail/cfe-dev/2019-March/061607.html
Co-authored-by: Cole Nixon <nixontcole@gmail.com>
Co-authored-by: Connor Kuehl <cipkuehl@gmail.com>
Co-authored-by: James Foster <jafosterja@gmail.com>
Co-authored-by: Jeff Takahashi <jeffrey.takahashi@gmail.com>
Co-authored-by: Jordan Cantrell <jordan.cantrell@mail.com>
Co-authored-by: Nikk Forbus <nicholas.forbus@gmail.com>
Co-authored-by: Tim Pugh <nwtpugh@gmail.com>
Co-authored-by: Bill Wendling <isanbard@gmail.com>
Signed-off-by: Bill Wendling <isanbard@gmail.com>
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D121556
This adjusts the handling for:
export module M;
export namespace {};
export namespace N {};
export using namespace N;
In the first case, we were allowing empty anonymous namespaces
as part of an extension allowing empty top-level entities, but that seems
inappropriate in this case, since the linkage would be internal for the
anonymous namespace. We now report an error for this.
The second case was producing a warning diagnostic that this was
accepted as an extension - however the C++20 standard does allow this
as well-formed.
In the third case we keep the current practice that this is accepted with a
warning (as an extension). The C++20 standard says it's an error.
We also ensure that using decls are only applied to items with external linkage.
This adjusts error messages for exports involving redeclarations in modules to
be more specific about the reason that the decl has been rejected.
Differential Revision: https://reviews.llvm.org/D122119
Without the fix ivars with anonymous types can trigger errors like
> error: 'TestClass::structIvar' from module 'Target' is not present in definition of 'TestClass' provided earlier
> [...]
> note: declaration of 'structIvar' does not match
It happens because types of ivars from different modules are considered
to be different. And it is caused by not merging anonymous `TagDecl`
from different modules.
To fix that I've changed `serialization::needsAnonymousDeclarationNumber`
to handle anonymous `TagDecl` inside `ObjCInterfaceDecl`. But that's not
sufficient as C code inside `ObjCInterfaceDecl` doesn't use interface
decl as a decl context but switches to its parent (TranslationUnit in
most cases). I'm changing that to make `ObjCContainerDecl` the lexical
decl context but keeping the semantic decl context intact.
Test "check-dup-decls-inside-objc.m" doesn't reflect a change in
functionality but captures the existing behavior to prevent regressions.
rdar://85563013
Differential Revision: https://reviews.llvm.org/D118525
This adds diagnostics for conflicting attributes on the same
declarataion, conflicting attributes on a forward and final
declaration, and defines a more narrowly scoped HLSLEntry attribute
target.
Big shout out to @aaron.ballman for the great feedback and review on
this!
HLSL uses Microsoft-style attributes `[attr]`, which clang mostly
ignores. For HLSL we need to handle known Microsoft attributes, and to
maintain C/C++ as-is we ignore unknown attributes.
To utilize this new code path, this change adds the HLSL `numthreads`
attribute.
Reviewed By: rnk
Differential Revision: https://reviews.llvm.org/D122627
Some functions can end up non-externally visible despite not being
declared "static" or in an unnamed namespace in C++ - such as by having
parameters that are of non-external types.
Such functions aren't mistakenly intended to be defining some function
that needs a declaration. They could be maybe more legible (except for
the operator new example) with an explicit static, but that's a
stylistic thing outside what should be addressed by a warning.
This reapplies 275c56226d - once we figure
out what to do about the change in behavior for -Wnon-c-typedef-for-linkage
(this reverts the revert commit 85ee1d3ca1)
Differential Revision: https://reviews.llvm.org/D121328
Update `WeakUndeclaredIdentifiers` to hold a collection of weak
aliases per identifier instead of only one.
This also allows the "used" state to be removed from `WeakInfo`
because it is really only there as an alternative to removing
processed map entries, and we can represent that using an empty set
now. The serialization code is updated for the removal of the field.
Additionally, a PCH test is added for the new functionality.
The records are grouped by the "target" identifier, which was already
being used as a key for lookup purposes. We also store only one record
per alias name; combined, this means that diagnostics are grouped by
the "target" and limited to one per alias (which should be acceptable).
Fixes PR28611.
Fixesllvm/llvm-project#28985.
Reviewed By: aaron.ballman, cebowleratibm
Differential Revision: https://reviews.llvm.org/D121927
Co-authored-by: Rachel Craik <rcraik@ca.ibm.com>
Co-authored-by: Jamie Schmeiser <schmeise@ca.ibm.com>
Move the SourceRange from the old ParsedAttributesWithRange into
ParsedAttributesView, so we have source range information available
everywhere we use attributes.
This also removes ParsedAttributesWithRange (replaced by simply using
ParsedAttributes) and ParsedAttributesVieWithRange (replaced by using
ParsedAttributesView).
Differential Revision: https://reviews.llvm.org/D121201
Previously, an attempt to declare an overload of a multiversion function
in C was not properly diagnosed. In some cases, diagnostics were simply
missing. In other cases the following assertion failure occured...
```
Assertion `(Previous.empty() || llvm::any_of(Previous, [](const NamedDecl *ND) { return ND->hasAttr(); })) && "Non-redecls shouldn't happen without overloadable present"' failed.
```
... or the following diagnostic was spuriously issued.
```
error: at most one overload for a given name may lack the 'overloadable' attribute
```
The diagnostics issued in some cases could be improved. When the function
type of a redeclaration does not match the prior declaration, it would be
preferable to diagnose the type mismatch before diagnosing mismatched
attributes. Diagnostics are also missing for some cases.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D121959
Checking of multiversion function declarations performed by various functions
in clang/lib/Sema/SemaDecl.cpp previously forced the valus of a passed in
'MergeTypeWithPrevious' reference argument in several scenarios. This was
unnecessary and possibly incorrect in the one case that the value
was forced to 'true' (though seemingly unobservably so).
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D121958
This change removes redundant code in the definition of
CheckTargetCausesMultiVersioning() in SemaDecl.cpp. The removed code checked
for multiversion function support. The code immediately following the removed
code is a call to CheckMultiVersionAdditionalRules(); that function performs
the same check on entry. In both cases, the consequences of missing multiversion
function support results in the same diagnostic message being issued and the
applicable function declaration being marked as invalid.
Reviewed By: erichkeane, aaron.ballman
Differential Revision: https://reviews.llvm.org/D121957
This change removes dead code in the definition of CheckMultiVersionFunction()
in clang/lib/Sema/SemaDecl.cpp. The removed code was made dead by commit
fc53eb69c26cdd7efa6b629c187d04326f0448ca: "Reapply 'Implement target_clones multiversioning'".
See the added code just above the code being deleted; it contains the same
return statement with the previous condition now distributed across an if
statement and a switch statement.
Reviewed By: erichkeane, aaron.ballman
Differential Revision: https://reviews.llvm.org/D121955
Regresses:
typedef struct {
static void f() {
}
} a_t;
Causing this to error instead of warn, because the linkage is computed
earlier/too early perhaps. I'll send out a review to see if there's some
other path forward or if this is an acceptable regression, etc.
This reverts commit 275c56226d.
The `objc_precise_lifetime` attribute is applied to Objective-C pointers to ensure the optimizer does not prematurely release an object under Automatic Reference Counting (ARC). It is a common enough pattern to assign values to these variables but not reference them otherwise, and annotating them with `__unused` is not really correct as they are being used to ensure an object's lifetime.
Differential Revision: https://reviews.llvm.org/D120372
This implements the parsing and recognition of module partition CMIs
and removes the FIXMEs in the parser.
Module partitions are recognised in the base computation of visibility,
however additional amendments to visibility follow in subsequent patches.
Differential Revision: https://reviews.llvm.org/D118586
The above change assumed that malloc (and friends) would always
allocate memory to getNewAlign(), even for allocations which have a
smaller size. This is not actually required by spec (a 1-byte
allocation may validly have 1-byte alignment).
Some real-world malloc implementations do not provide this guarantee,
and thus this optimization is breaking programs.
Fixes#53540
This reverts commit c2297544c0.
Differential Revision: https://reviews.llvm.org/D118804
Some functions can end up non-externally visible despite not being
declared "static" or in an unnamed namespace in C++ - such as by having
parameters that are of non-external types.
Such functions aren't mistakenly intended to be defining some function
that needs a declaration. They could be maybe more legible (except for
the `operator new` example) with an explicit static, but that's a
stylistic thing outside what should be addressed by a warning.
Do not warn on reserved identifiers resulting from expansion of system macros.
Also properly test -Wreserved-identifier wrt. system headers.
Should fix#49592
Differential Revision: https://reviews.llvm.org/D118532
This commit checks if a function is marked with the naked attribute
and, if it is, will silence the emission of any unused-parameter
warning.
Inside a naked function only the usage of basic ASM instructions is
expected. In this context the parameters can actually be used by
fetching them according to the underlying ABI. Since parameters might
be used through ASM instructions, the linter and the compiler will have
a hard time understanding if one of those is unused or not, therefore
no unused-parameter warning should ever be triggered whenever a
function is marked naked.
Since only the decls inhabit in a namespace scope could be exported, it
is not meaningful to check it in CheckRedeclarationExported, which
implements [module.interface]/p6.
Reviewed By: urnathan
Differential Revision: https://reviews.llvm.org/D118120
Special classes such as accessor, sampler, and stream need additional
implementation when they are passed from host to device.
This patch is adding a new attribute “sycl_special_class” used to mark
SYCL classes/struct that need the additional compiler handling.
There is a comment contains a FIXME for the Module TS. And now the
Module TS is merged so we should update the comment. I've checked the
implementation.
This fixes bug 47716.
According to [module.interface]p2, it is meaningless to export an entity
which is not in namespace scope.
The reason why the compiler crashes is that the compiler missed
ExportDecl when the compiler traverse the subclass of DeclContext. So
here is the crash.
Also, the patch implements [module.interface]p6 in
Sema::CheckRedeclaration* functions.
Reviewed By: aaron.ballman, urnathan
Differential Revision: https://reviews.llvm.org/D112903
Often we run into situations where we want to ignore
warnings from system headers, but Clang will still
give warnings about the contents of a macro defined
in a system header used in user-code.
Introduce a ShowInSystemMacro option to be able to
specify which warnings we do want to keep raising
warnings for. The current behavior is kept in this patch
(i.e. warnings from system macros are enabled by default).
The decision as to whether this should be an opt-in or opt-out
feature can be made in a separate patch.
To put the feature to test, replace duplicated code for
Wshadow and Wold-style-cast with the SuppressInSystemMacro tag.
Also disable the warning for C++20 designators, fixing #52944.
Differential Revision: https://reviews.llvm.org/D116833