aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDecl.cpp
AgeCommit message (Collapse)AuthorFilesLines
2025-04-15Allow some attributes on declarations after definitions (#135791)Aaron Ballman1-0/+15
The deprecated, maybe_unused, and nodiscard standard attributes may all be applied to a redeclaration after a definition has already appeared. We were previously dropping the attribute in that case, now we retain the attribute after the redeclaration. Note: someday we may want to tablegen this as part of information from Attr.td. We may also want to relax the restriction here so that the syntax used does not matter. This is an intentionally conservative fix. Fixes #135481
2025-04-10[RFC] Initial implementation of P2719 (#113510)Oliver Hunt1-7/+3
This is a basic implementation of P2719: "Type-aware allocation and deallocation functions" described at http://wg21.link/P2719 The proposal includes some more details but the basic change in functionality is the addition of support for an additional implicit parameter in operators `new` and `delete` to act as a type tag. Tag is of type `std::type_identity<T>` where T is the concrete type being allocated. So for example, a custom type specific allocator for `int` say can be provided by the declaration of void *operator new(std::type_identity<int>, size_t, std::align_val_t); void operator delete(std::type_identity<int>, void*, size_t, std::align_val_t); However this becomes more powerful by specifying templated declarations, for example template <typename T> void *operator new(std::type_identity<T>, size_t, std::align_val_t); template <typename T> void operator delete(std::type_identity<T>, void*, size_t, std::align_val_t);); Where the operators being resolved will be the concrete type being operated over (NB. A completely unconstrained global definition as above is not recommended as it triggers many problems similar to a general override of the global operators). These type aware operators can be declared as either free functions or in class, and can be specified with or without the other implicit parameters, with overload resolution performed according to the existing standard parameter prioritisation, only with type parameterised operators having higher precedence than non-type aware operators. The only exception is destroying_delete which for reasons discussed in the paper we do not support type-aware variants by default.
2025-04-10[HLSL][SPIR-V] Add hlsl_private address space for SPIR-V (#133464)Nathan Gauër1-0/+4
This is an alternative to https://github.com/llvm/llvm-project/pull/122103 In SPIR-V, private global variables have the Private storage class. This PR adds a new address space which allows frontend to emit variable with this storage class when targeting this backend. This is covered in this proposal: llvm/wg-hlsl@4c9e11a This PR will cause addrspacecast to show up in several cases, like class member functions or assignment. Those will have to be handled in the backend later on, particularly to fixup pointer storage classes in some functions. Before this change, global variable were emitted with the 'Function' storage class, which was wrong.
2025-04-08[Clang] add ext warning for missing return in 'main' for C89 mode (#134617)Oleksandr T.1-1/+6
Fixes #21650 --- Clang currently inserts an implicit `return 0;` in `main()` when compiling in `C89` mode, even though the `C89` standard doesn't require this behavior. This patch changes that behavior by emitting a warning instead of silently inserting the implicit return under `-pedantic`.
2025-04-07Correctly diagnose incomplete arrays with static storage in C (#134374)Aaron Ballman1-2/+4
A file scope declaration without an initializer which is neither extern nor thread_local is a tentative definition. If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type. Clang was previously failing to diagnose this in -pedantic mode. Fixes #50661 --------- Co-authored-by: Mariya Podchishchaeva <mariya.podchishchaeva@intel.com>
2025-04-03[clang] NFC: introduce UnsignedOrNone as a replacement for ↵Matheus Izvekov1-1/+1
std::optional<unsigned> (#134142) This introduces a new class 'UnsignedOrNone', which models a lite version of `std::optional<unsigned>`, but has the same size as 'unsigned'. This replaces most uses of `std::optional<unsigned>`, and similar schemes utilizing 'int' and '-1' as sentinel. Besides the smaller size advantage, this is simpler to serialize, as its internal representation is a single unsigned int as well.
2025-04-03[clang] support pack expansions for trailing requires clauses (#133190)Matheus Izvekov1-12/+9
2025-04-02Reapply "[Clang] [NFC] Introduce a helper for emitting compatibility ↵Sirraide1-8/+3
diagnostics (#132348)" (#134043) This reapplies #132348 with a fix to the python bindings tests, reverting https://github.com/llvm/llvm-project/commit/076397ff3217cf45fd08024dd7bcd2bc8fb229ab.
2025-04-02Revert "[Clang] [NFC] Introduce a helper for emitting compatibility ↵Sirraide1-3/+8
diagnostics" (#134036) Reverts llvm/llvm-project#132348 Some tests are failing and I still need to figure out what is going on here.
2025-04-02[Clang] [NFC] Introduce a helper for emitting compatibility diagnostics ↵Sirraide1-8/+3
(#132348) This is a follow-up to #132129. Currently, only `Parser` and `SemaBase` get a `DiagCompat()` helper; I’m planning to keep refactoring compatibility warnings and add more helpers to other classes as needed. I also refactored a single parser compat warning just to make sure everything works properly when diagnostics across multiple components (i.e. Sema and Parser in this case) are involved.
2025-04-01[clang] Concepts: support pack expansions for type constraints (#132626)Matheus Izvekov1-2/+3
This reverts an earlier attempt (adb0d8ddceb143749c519d14b8b31b481071da77 and 50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions, which was limited to type arguments and which subverted the purpose of SubstTemplateTypeParmType. This propagates the ArgumentPackSubstitutionIndex along with the AssociatedConstraint, so that the pack expansion works, without needing any new transforms or otherwise any changes to the template instantiation process. This keeps the tests from the reverted commits, and adds a few more showing the new solution also works for NTTPs. Fixes https://github.com/llvm/llvm-project/issues/131798
2025-04-01[clang] improved preservation of template keyword (#133610)Matheus Izvekov1-12/+12
2025-03-28[clang][flang][Triple][llvm] Add isOffload function to LangOpts and isGPU ↵Nick Sarnie1-7/+4
function to Triple (#126956) I'm adding support for SPIR-V, so let's consolidate these checks. --------- Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
2025-03-21[OpenACC] Finish implementing 'routine' AST/Sema.erichkeane1-0/+10
This is the last item of the OpenACC 3.3 spec. It includes the implicit-name version of 'routine', plus significant refactorings to make the two work together. The implicit name version is represented as an attribute on the function call. This patch also implements the clauses for the implicit-name version, as well as the A.3.4 warning.
2025-03-21[Clang] [NFC] Introduce helpers for defining compatibilty warnings (#132129)Sirraide1-6/+6
This introduces some tablegen helpers for defining compatibility warnings. The main aim of this is to both simplify adding new compatibility warnings as well as to unify the naming of compatibility warnings. I’ve refactored ~half of the compatiblity warnings (that follow the usual scheme) in `DiagnosticSemaKinds.td` for illustration purposes and also to simplify/unify the wording of some of them (I also corrected a typo in one of them as a drive-by fix). I haven’t (yet) migrated *all* warnings even in that one file, and there are some more specialised ones for which the scheme I’ve established here doesn’t work (e.g. because they’re warning+error instead of warning+extwarn; however, warning+extension *is* supported), but the point of this isn’t to implement *all* compatibility-related warnings this way, only to make the common case a bit easier to handle. This currently also only handles C++ compatibility warnings, but it should be fairly straight-forward to extend the tablegen code so it can also be used for C compatibility warnings (if this gets merged, I’m planning to do that in a follow-up pr). The vast majority of compatibility warnings are emitted by writing ```c++ Diag(Loc, getLangOpts().CPlusPlusYZ ? diag::ext_... : diag::warn_...) ``` in accordance with which I’ve chosen the following naming scheme: ```c++ Diag(Loc, getLangOpts().CPlusPlusYZ ? diag::compat_cxxyz_foo : diag::compat_pre_cxxyz_foo) ``` That is, for a warning about a C++20 feature—i.e. C++≤17 compatibility—we get: ```c++ Diag(Loc, getLangOpts().CPlusPlus20 ? diag::compat_cxx20_foo : diag::compat_pre_cxx20_foo) ``` While there is an argument to be made against writing ‘`compat_cxx20`’ here since is technically a case of ‘C++17 compatibility’ and not ‘C++20 compatibility’, I at least find this easier to reason about, because I can just write the same number 3 times instead of having to use `ext_cxx20_foo` but `warn_cxx17_foo`. Instead, I like to read this as a warning about the ‘compatibility *of* a C++20 feature’ rather than ‘*with* C++17’. I also experimented with moving all compatibility warnings to a separate file, but 1. I don’t think it’s worth the effort, and 2. I think it hurts compile times a bit because at least in my testing I felt that I had to recompile more code than if we just keep e.g. Sema-specific compat warnings in the Sema diagnostics file. Instead, I’ve opted to put them all in the same place within any one file; currently this is a the very top but I don’t really have strong opinions about this.
2025-03-19[Clang] emit -Wunused-variable warning for unused structured bindings ↵Oleksandr T.1-4/+5
without the [[maybe_unused]] attribute (#127061) Fixes #125810 --- This patch resolves an issue in Clang where the `-Wunused-variable` warning was suppressed for structured bindings with elements marked `[[maybe_unused]]`, causing the entire declaration to be treated as used and preventing the warning from being emitted.
2025-03-13[C++20] [Modules] Don't add decls from other units to undefinedButUsed setChuanqi Xu1-6/+5
It is still better to elide the declaration if possible. To overcome the false positive undefinedButUsed diagnostic, it seems better to not add declaration from other units to the set actually.
2025-03-10Reland: [clang] Fix missing diagnostic of declaration use when accessing ↵Matheus Izvekov1-18/+29
TypeDecls through typename access (#130673)
2025-03-10[clang] fix matching of nested template template parameters (#130447)Matheus Izvekov1-1/+1
When checking the template template parameters of template template parameters, the PartialOrdering context was not correctly propagated. This also has a few drive-by fixes, such as checking the template parameter lists of template template parameters, which was previously missing and would have been it's own bug, but we need to fix it in order to prevent crashes in error recovery in a simple way. Fixes #130362
2025-03-10Revert "[clang] Fix missing diagnostic of declaration use when accessing ↵Hans Wennborg1-29/+18
TypeDecls through typename access (#129681)" This caused incorrect -Wunguarded-availability warnings. See comment on the pull request. > We were missing a call to DiagnoseUseOfDecl when performing typename > access. > > This refactors the code so that TypeDecl lookups funnel through a helper > which performs all the necessary checks, removing some related > duplication on the way. > > Fixes #58547 > > Differential Revision: https://reviews.llvm.org/D136533 This reverts commit 4c4fd6b03149348cf11af245ad2603d24144a9d5.
2025-03-10[clang] NNS: don't print trailing scope resolution operator in diagnostics ↵Matheus Izvekov1-4/+4
(#130529) This clears up the printing of a NestedNameSpecifier so a trailing '::' is not printed, unless it refers into the global scope. This fixes a bunch of diagnostics where the trailing :: was awkward. This also prints the NNS quoted consistenty. There is a drive-by improvement to error recovery, where now we print the actual type instead of `<dependent type>`. This will clear up further uses of NNS printing in further patches.
2025-03-07[clang] Fix ASTWriter crash after merging named enums (#114240)Michael Jabbour1-13/+17
Clang already removes parsed enumerators when merging typedefs to anonymous enums. This is why the following example decl used to be handled correctly while merging, and ASTWriter behaves as expected: ```c typedef enum { Val } AnonEnum; ``` However, the mentioned mechanism didn't handle named enums. This leads to stale declarations in `IdResolver`, causing an assertion violation in ASTWriter ``Assertion `DeclIDs.contains(D) && "Declaration not emitted!"' failed`` when a module is being serialized with the following example merged enums: ```c typedef enum Enum1 { Val_A } Enum1; enum Enum2 { Val_B }; ``` The PR applies the same mechanism in the named enums case. Additionally, I dropped the call to `getLexicalDeclContext()->removeDecl` as it was causing a wrong odr-violation diagnostic with anonymous enums. Might be easier to to review commit by commit. Any feedback is appreciated. ### Context This fixes frontend crashes that were encountered when certain Objective-C modules are included on Xcode 16. For example, by running `CC=/path/to/clang-19 xcodebuild clean build` on a project that contains the following Objective-C file: ```c #include <os/atomic.h> int main() { return memory_order_relaxed; } ``` This crashes the parser in release, when ASTReader tries to load the enumerator declaration.
2025-03-07[Clang] Check for uninitialized use in lambda within CXXOperatorCallExpr ↵zhaohui1-0/+17
(#129198) Track whether a LambdaExpr is an immediate operand of a CXXOperatorCallExpr using a new flag, isInCXXOperatorCall. This enables special handling of capture initializations to detect uninitialized variable uses, such as in `S s = [&]() { return s; }();`. Fix #128058
2025-03-06[OpenACC] implement AST/Sema for 'routine' construct with argumenterichkeane1-0/+3
The 'routine' construct has two forms, one which takes the name of a function that it applies to, and another where it implicitly figures it out based on the next declaration. This patch implements the former with the required restrictions on the name and the function-static-variables as specified. What has not been implemented is any clauses for this, any of the A.3.4 warnings, or the other form.
2025-03-04[clang] Fix missing diagnostic of declaration use when accessing TypeDecls ↵Matheus Izvekov1-18/+29
through typename access (#129681) We were missing a call to DiagnoseUseOfDecl when performing typename access. This refactors the code so that TypeDecl lookups funnel through a helper which performs all the necessary checks, removing some related duplication on the way. Fixes #58547 Differential Revision: https://reviews.llvm.org/D136533
2025-02-28[CUDA][HIP] check dtor in deferred diag (#129117)Yaxun (Sam) Liu1-0/+15
Currently the deferred diag fails to diagnose calling of host function in host device function in device compilation triggered by destructors. This can be further divided into two issuse: 1. the deferred diag visitor does not visit dtor of member and parent class when visiting dtor, which it should 2. the deferred diag visitor does not visit virtual dtor of explicit template class instantiation, which it should Due to these issues, some constexpr functions which call host functions are emitted on device side, which causes undefind symbols in linking stage, as revealed by https://github.com/llvm/llvm-project/issues/108548 By fixing these issue, clang will diag the issues early during compilation instead of linking.
2025-02-28Disable unique-object-duplication warning in templates (#129120)Devon Loehr1-5/+9
I've been trying to resolve instances of the unique-object-duplication warning in chromium code. Unfortunately, I've found that practically speaking, it's near-impossible to actually fix the problem when templates are involved. My understanding is that the warning is correct -- the variables it's flagging are indeed duplicated and potentially causing bugs as a result. The problem is that hiddenness is contagious: if a templated class or variable depends on something hidden, then it itself must also be hidden, even if the user explicitly marked it visible. In order to make it actually visible, the user must manually figure out everything that it depends on, mark them as visible, and do so recursively until all of its ancestors are visible. This process is extremely difficult and unergonomic, negating much of the benefits of templates since now each new use requires additional work. Furthermore, the process doesn't work if the user can't edit some of the files, e.g. if they're in a third-party library. Since a warning that can't practically be fixed isn't useful, this PR disables the warning for _all_ templated code by inverting the check. The warning remains active (and, in my experience, easily fixable) in non-templated code.
2025-02-24[clang] Implement __attribute__((format_matches)) (#116708)apple-fcloutier1-0/+3
This implements ``__attribute__((format_matches))``, as described in the RFC: https://discourse.llvm.org/t/rfc-format-attribute-attribute-format-like/83076 The ``format`` attribute only allows the compiler to check that a format string matches its arguments. If the format string is passed independently of its arguments, there is no way to have the compiler check it. ``format_matches(flavor, fmtidx, example)`` allows the compiler to check format strings against the ``example`` format string instead of against format arguments. See the changes to AttrDocs.td in this diff for more information. Implementation-wise, this change subclasses CheckPrintfHandler and CheckScanfHandler to allow them to collect specifiers into arrays, and implements comparing that two specifiers are equivalent. `checkFormatStringExpr` gets a new `ReferenceFormatString` argument that is piped down when calling a function with the `format_matches` attribute (and is `nullptr` otherwise); this is the string that the actual format string is compared against. Although this change does not enable -Wformat-nonliteral by default, IMO, all the pieces are now in place such that it could be.
2025-02-21Check for mutability better (#127843)Devon Loehr1-16/+19
This PR adds a function to determine if a type "looks" mutable. Since it's impossible to be totally sure if something can or can't be modified in C++, this makes a best-effort attempt to determine if variables of that type can be modified or not. The motivation for this change is the -Wunique-object-duplication warning, which had a false positive due to a missed case while checking for mutability. Pulling the logic into a separate function allows it to be written much more cleanly. There should be no behavior change, except that we no longer report function references to be mutable.
2025-02-21[C++20] [Modules] handling selectAny attribute for vardeclChuanqi Xu1-1/+2
Close https://github.com/llvm/llvm-project/issues/127963 The root cause of the problem seems to be that we didn't realize it simply.
2025-02-20[HLSL] Constant Buffers CodeGen (#124886)Helena Kotas1-0/+7
Translates `cbuffer` declaration blocks to `target("dx.CBuffer")` type. Creates global variables in `hlsl_constant` address space for all `cbuffer` constant and adds metadata describing which global constant belongs to which constant buffer. For explicit constant buffer layout information an explicit layout type `target("dx.Layout")` is used. This might change in the future. The constant globals are temporary and will be removed in upcoming pass that will translate `load` instructions in the `hlsl_constant` address space to constant buffer load intrinsics calls off a CBV handle (#124630, #112992). See [Constant buffer design doc](https://github.com/llvm/wg-hlsl/pull/94) for more details. Fixes #113514, #106596
2025-02-15[Sema] Avoid repeated hash lookups (NFC) (#127301)Kazu Hirata1-2/+3
2025-02-14Enable -Wunique-object-duplication inside templated code (#125902)Devon Loehr1-50/+60
Followup to #125526. This allows the unique object duplication warning to fire on code inside of templates. Previously, it was disabled there to prevent false positives if the template was never instantiated. The patch has two parts: first, we move the check from `FinalizeDeclaration` (which is only called during parsing) to `CheckCompleteVariableDeclaration` (which is also called during template instantiation). Since the code we're moving is fairly bulky, we abstract it into a separate function for convenience. Second, we disable the warning during template parsing, and add a check later to see if the variable we're acting on on originated from a template. If so, it has the potential to be duplicated just like an inline variable. ## Testing Unit tests for template have been added to the existing test suite. To evaluate the patch on real code, I ran it on chromium and on clang itself. As expected, in both cases we got strictly more warnings than before. I manually looked through each new warning, and they all seemed legitimate. In chromium, we found [79 new warnings across 55 files](https://github.com/user-attachments/files/18676635/new_warnings_chromium.txt), mostly in third-party code (for a total of 234 warnings across 137 files). In clang, we found [8 new warnings across 6 files](https://github.com/user-attachments/files/18676658/new_warnings_clang.txt), for a total of 17 warnings across 11 files.
2025-02-11[clang][Sema] Move computing enum bits into a separate function (#126096)Ilia Kuklin1-49/+5
Move the code that computes `NumNegativeBits` and `NumPositiveBits` for an enum to a separate function in `ASTContext.h`. This function needs to be called from LLDB as well (#115005)
2025-02-03Warn when unique objects might be duplicated in shared libraries (#125526)Devon Loehr1-0/+101
This is attempt 2 to merge this, the first one is #117622. This properly disables the tests when building for playstation, since the warning is disabled there. When a hidden object is built into multiple shared libraries, each instance of the library will get its own copy. If the object was supposed to be globally unique (e.g. a global variable or static data member), this can cause very subtle bugs. An object might be incorrectly duplicated if it: Is defined in a header (so it might appear in multiple TUs), and Has external linkage (otherwise it's supposed to be duplicated), and Has hidden visibility (or else the dynamic linker will handle it) The duplication is only a problem semantically if one of the following is true: The object is mutable (the copies won't be in sync), or Its initialization has side effects (it may now run more than once), or The value of its address is used (different copies have different addresses). To detect this, we add a new -Wunique-object-duplication warning. It warns on cases (1) and (2) above. To be conservative, we only warn in case (2) if we are certain the initializer has side effects, and we don't warn on new because the only side effect is some extra memory usage. We don't currently warn on case (3) because doing so is prone to false positives: there are many reasons for taking the address which aren't inherently problematic (e.g. passing to a function that expects a pointer). We only run into problems if the code inspects the value of the address. The check is currently disabled for windows, which uses its own analogue of visibility (declimport/declexport). The check is also disabled inside templates, since it can give false positives if a template is never instantiated. Resolving the warning The warning can be fixed in several ways: If the object in question doesn't need to be mutable, it should be made const. Note that the variable must be completely immutable, e.g. we'll warn on const int* p because the pointer itself is mutable. To silence the warning, it should instead be const int* const p. If the object must be mutable, it (or the enclosing function, in the case of static local variables) should be made visible using __attribute((visibility("default"))) If the object is supposed to be duplicated, it should be be given internal linkage. Testing I've tested the warning by running it on clang itself, as well as on chromium. Compiling clang resulted in [10 warnings across 6 files](https://github.com/user-attachments/files/17908069/clang-warnings.txt), while Chromium resulted in [160 warnings across 85 files](https://github.com/user-attachments/files/17908072/chromium-warnings.txt), mostly in third-party code. Almost all warnings were due to mutable variables. I evaluated the warnings by manual inspection. I believe all the resulting warnings are true positives, i.e. they represent potentially-problematic code where duplication might cause a problem. For the clang warnings, I also validated them by either adding const or visibility annotations as appropriate. Limitations I am aware of four main limitations with the current warning: We do not warn when the address of a duplicated object is taken, since doing so is prone to false positives. I'm hopeful that we can create a refined version in the future, however. We only warn for side-effectful initialization if we are certain side effects exist. Warning on potential side effects produced a huge number of false positives; I don't expect there's much that can be done about this in modern C++ code bases, since proving a lack of side effects is difficult. Windows uses a different system (declexport/import) instead of visibility. From manual testing, it seems to behave analogously to the visibility system for the purposes of this warning, but to keep things simple the warning is disabled on windows for now. We don't warn on code inside templates. This is unfortuate, since it masks many real issues, e.g. a templated variable which is implicitly instantiated the same way in multiple TUs should be globally unique, but may accidentally be duplicated. Unfortunately, we found some potential false positives during testing that caused us to disable the warning for now.
2025-02-03Revert "Warn when unique objects might be duplicated in shared libraries ↵Hans Wennborg1-101/+0
(#117622)" There are some buildbot breakages, see the PR. Reverting for now. This reverts commit d5684b8402d2175e80a2792db58e9a8e960a8544.
2025-02-03Warn when unique objects might be duplicated in shared libraries (#117622)Devon Loehr1-0/+101
When a hidden object is built into multiple shared libraries, each instance of the library will get its own copy. If the object was supposed to be globally unique (e.g. a global variable or static data member), this can cause very subtle bugs. An object might be incorrectly duplicated if it: - Is defined in a header (so it might appear in multiple TUs), and - Has external linkage (otherwise it's supposed to be duplicated), and - Has hidden visibility (or else the dynamic linker will handle it) The duplication is only a problem semantically if one of the following is true: 1. The object is mutable (the copies won't be in sync), or 2. Its initialization has side effects (it may now run more than once), or 3. The value of its address is used (different copies have different addresses). To detect this, we add a new -Wunique-object-duplication warning. It warns on cases (1) and (2) above. To be conservative, we only warn in case (2) if we are certain the initializer has side effects, and we don't warn on `new` because the only side effect is some extra memory usage. We don't currently warn on case (3) because doing so is prone to false positives: there are many reasons for taking the address which aren't inherently problematic (e.g. passing to a function that expects a pointer). We only run into problems if the code inspects the value of the address. The check is currently disabled for windows, which uses its own analogue of visibility (declimport/declexport). The check is also disabled inside templates, since it can give false positives if a template is never instantiated. ### Resolving the warning The warning can be fixed in several ways: - If the object in question doesn't need to be mutable, it should be made const. Note that the variable must be completely immutable, e.g. we'll warn on `const int* p` because the pointer itself is mutable. To silence the warning, it should instead be `const int* const p`. - If the object must be mutable, it (or the enclosing function, in the case of static local variables) should be made visible using `__attribute((visibility("default")))` - If the object is supposed to be duplicated, it should be be given internal linkage. ### Testing I've tested the warning by running it on clang itself, as well as on chromium. Compiling clang resulted in [10 warnings across 6 files](https://github.com/user-attachments/files/17908069/clang-warnings.txt), while Chromium resulted in [160 warnings across 85 files](https://github.com/user-attachments/files/17908072/chromium-warnings.txt), mostly in third-party code. Almost all warnings were due to mutable variables. I evaluated the warnings by manual inspection. I believe all the resulting warnings are true positives, i.e. they represent potentially-problematic code where duplication might cause a problem. For the clang warnings, I also validated them by either adding `const` or visibility annotations as appropriate. ### Limitations I am aware of four main limitations with the current warning: 1. We do not warn when the address of a duplicated object is taken, since doing so is prone to false positives. I'm hopeful that we can create a refined version in the future, however. 2. We only warn for side-effectful initialization if we are certain side effects exist. Warning on potential side effects produced a huge number of false positives; I don't expect there's much that can be done about this in modern C++ code bases, since proving a lack of side effects is difficult. 3. Windows uses a different system (declexport/import) instead of visibility. From manual testing, it seems to behave analogously to the visibility system for the purposes of this warning, but to keep things simple the warning is disabled on windows for now. 4. We don't warn on code inside templates. This is unfortuate, since it masks many real issues, e.g. a templated variable which is implicitly instantiated the same way in multiple TUs should be globally unique, but may accidentally be duplicated. Unfortunately, we found some potential false positives during testing that caused us to disable the warning for now.
2025-01-31Allow 'inline' on some declarations in MS compatibility mode (#125250)Aaron Ballman1-1/+4
Microsoft allows the 'inline' specifier on a typedef of a function type in C modes. This is used by a system header (ufxclient.h), so instead of giving a hard error, we diagnose with a warning. C++ mode and non- Microsoft compatibility modes are not impacted. Fixes https://github.com/llvm/llvm-project/issues/124869
2025-01-30[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#125023)Kazu Hirata1-1/+1
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> Literal migration would result in dyn_cast_if_present (see the definition of PointerUnion::dyn_cast), but this patch uses dyn_cast because we expect Entry to be nonnull.
2025-01-28[Clang] call HandleImmediateInvocation before checking for immediate ↵cor3ntin1-1/+3
escacalating expressions (reland) (#124708) HandleImmediateInvocation can call MarkExpressionAsImmediateEscalating and should always be called before CheckImmediateEscalatingFunctionDefinition. However, we were not doing that in `ActFunctionBody`. Fixes #119046
2025-01-27Revert "[Clang] call HandleImmediateInvocation before checking for immediate ↵cor3ntin1-0/+1
escacalating expressions" (#124646) Reverts llvm/llvm-project#124414 Turns out to be an important compile time regression, I'll come up with a less disruptive approach
2025-01-27[Clang] call HandleImmediateInvocation before checking for immediate ↵cor3ntin1-1/+0
escacalating expressions (#124414) HandleImmediateInvocation can call MarkExpressionAsImmediateEscalating and should always be called before CheckImmediateEscalatingFunctionDefinition. However, we were not doing that in `ActFunctionBody`. We simply move CheckImmediateEscalatingFunctionDefinition to PopExpressionEvaluationContext. Fixes #119046
2025-01-27[clang][Sema][FMV] Add a note to the 'cannot become multiversioned' ↵Jon Roelofs1-2/+5
diagnostic (#124364) ... pointing out the previous declaration.
2025-01-25[clang] Migrate away from PointerUnion::dyn_cast (NFC) (#124425)Kazu Hirata1-2/+4
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> This patch migrates uses of PointerUnion::dyn_cast to dyn_cast_if_present (see the definition of PointerUnion::dyn_cast). Note that we cannot use dyn_cast in any of the migrations in this patch; placing assert(!X.isNull()); just before any of dyn_cast_if_present in this patch triggers some failure in check-clang.
2025-01-22[SYCL] AST support for SYCL kernel entry point functions. (#122379)Tom Honermann1-1/+14
A SYCL kernel entry point function is a non-member function or a static member function declared with the `sycl_kernel_entry_point` attribute. Such functions define a pattern for an offload kernel entry point function to be generated to enable execution of a SYCL kernel on a device. A SYCL library implementation orchestrates the invocation of these functions with corresponding SYCL kernel arguments in response to calls to SYCL kernel invocation functions specified by the SYCL 2020 specification. The offload kernel entry point function (sometimes referred to as the SYCL kernel caller function) is generated from the SYCL kernel entry point function by a transformation of the function parameters followed by a transformation of the function body to replace references to the original parameters with references to the transformed ones. Exactly how parameters are transformed will be explained in a future change that implements non-trivial transformations. For now, it suffices to state that a given parameter of the SYCL kernel entry point function may be transformed to multiple parameters of the offload kernel entry point as needed to satisfy offload kernel argument passing requirements. Parameters that are decomposed in this way are reconstituted as local variables in the body of the generated offload kernel entry point function. For example, given the following SYCL kernel entry point function definition: ``` template<typename KernelNameType, typename KernelType> [[clang::sycl_kernel_entry_point(KernelNameType)]] void sycl_kernel_entry_point(KernelType kernel) { kernel(); } ``` and the following call: ``` struct Kernel { int dm1; int dm2; void operator()() const; }; Kernel k; sycl_kernel_entry_point<class kernel_name>(k); ``` the corresponding offload kernel entry point function that is generated might look as follows (assuming `Kernel` is a type that requires decomposition): ``` void offload_kernel_entry_point_for_kernel_name(int dm1, int dm2) { Kernel kernel{dm1, dm2}; kernel(); } ``` Other details of the generated offload kernel entry point function, such as its name and calling convention, are implementation details that need not be reflected in the AST and may differ across target devices. For that reason, only the transformation described above is represented in the AST; other details will be filled in during code generation. These transformations are represented using new AST nodes introduced with this change. `OutlinedFunctionDecl` holds a sequence of `ImplicitParamDecl` nodes and a sequence of statement nodes that correspond to the transformed parameters and function body. `SYCLKernelCallStmt` wraps the original function body and associates it with an `OutlinedFunctionDecl` instance. For the example above, the AST generated for the `sycl_kernel_entry_point<kernel_name>` specialization would look as follows: ``` FunctionDecl 'sycl_kernel_entry_point<kernel_name>(Kernel)' TemplateArgument type 'kernel_name' TemplateArgument type 'Kernel' ParmVarDecl kernel 'Kernel' SYCLKernelCallStmt CompoundStmt <original statements> OutlinedFunctionDecl ImplicitParamDecl 'dm1' 'int' ImplicitParamDecl 'dm2' 'int' CompoundStmt VarDecl 'kernel' 'Kernel' <initialization of 'kernel' with 'dm1' and 'dm2'> <transformed statements with redirected references of 'kernel'> ``` Any ODR-use of the SYCL kernel entry point function will (with future changes) suffice for the offload kernel entry point to be emitted. An actual call to the SYCL kernel entry point function will result in a call to the function. However, evaluation of a `SYCLKernelCallStmt` statement is a no-op, so such calls will have no effect other than to trigger emission of the offload kernel entry point. Additionally, as a related change inspired by code review feedback, these changes disallow use of the `sycl_kernel_entry_point` attribute with functions defined with a _function-try-block_. The SYCL 2020 specification prohibits the use of C++ exceptions in device functions. Even if exceptions were not prohibited, it is unclear what the semantics would be for an exception that escapes the SYCL kernel entry point function; the boundary between host and device code could be an implicit noexcept boundary that results in program termination if violated, or the exception could perhaps be propagated to host code via the SYCL library. Pending support for C++ exceptions in device code and clear semantics for handling them at the host-device boundary, this change makes use of the `sycl_kernel_entry_point` attribute with a function defined with a _function-try-block_ an error.
2025-01-17[clang][Sema] Move computing best enum types to a separate function (#120965)Ilia Kuklin1-71/+6
Move the code that computes BestType and BestPromotionType for an enum to a separate function which can be called from outside of Sema.
2025-01-15[Sema] Migrate away from PointerUnion::dyn_cast (NFC) (#123014)Kazu Hirata1-2/+2
Note that PointerUnion::dyn_cast has been soft deprecated in PointerUnion.h: // FIXME: Replace the uses of is(), get() and dyn_cast() with // isa<T>, cast<T> and the llvm::dyn_cast<T> Literal migration would result in dyn_cast_if_present (see the definition of PointerUnion::dyn_cast), but this patch uses dyn_cast because we expect EnumUnderlying to be nonnull.
2025-01-14Add Clang attribute to ensure that fields are initialized explicitly (#102040)higher-performance1-0/+2
This is a new Clang-specific attribute to ensure that field initializations are performed explicitly. For example, if we have ``` struct B { [[clang::explicit]] int f1; }; ``` then the diagnostic would trigger if we do `B b{};`: ``` field 'f1' is left uninitialized, but was marked as requiring initialization ``` This prevents callers from accidentally forgetting to initialize fields, particularly when new fields are added to the class.
2025-01-14[clang] Do not allow unorderable features in [[gnu::target{,_clones}]] (#98426)Dan Klishch1-1/+2
This partially addresses #98244.
2025-01-14Propagate lifetimebound from formal parameters to those in the canonical ↵higher-performance1-20/+48
declaration and use that for analysis (#107627) This partially fixes #62072 by making sure that re-declarations of a function do not have the effect of removing lifetimebound from the canonical declaration. It doesn't handle the implicit 'this' parameter, but that can be addressed in a separate fix.