|
Revision tags: llvmorg-20.1.0, llvmorg-20.1.0-rc3, llvmorg-20.1.0-rc2, llvmorg-20.1.0-rc1, llvmorg-21-init, llvmorg-19.1.7, llvmorg-19.1.6, llvmorg-19.1.5, llvmorg-19.1.4, llvmorg-19.1.3, llvmorg-19.1.2, llvmorg-19.1.1, llvmorg-19.1.0, llvmorg-19.1.0-rc4, llvmorg-19.1.0-rc3, llvmorg-19.1.0-rc2, llvmorg-19.1.0-rc1, llvmorg-20-init, llvmorg-18.1.8, llvmorg-18.1.7, llvmorg-18.1.6, llvmorg-18.1.5, llvmorg-18.1.4, llvmorg-18.1.3, llvmorg-18.1.2, llvmorg-18.1.1, llvmorg-18.1.0, llvmorg-18.1.0-rc4, llvmorg-18.1.0-rc3, llvmorg-18.1.0-rc2, llvmorg-18.1.0-rc1, llvmorg-19-init, llvmorg-17.0.6, llvmorg-17.0.5, llvmorg-17.0.4, llvmorg-17.0.3, llvmorg-17.0.2, llvmorg-17.0.1, llvmorg-17.0.0, llvmorg-17.0.0-rc4, llvmorg-17.0.0-rc3, llvmorg-17.0.0-rc2, llvmorg-17.0.0-rc1, llvmorg-18-init, llvmorg-16.0.6, llvmorg-16.0.5, llvmorg-16.0.4, llvmorg-16.0.3, llvmorg-16.0.2, llvmorg-16.0.1, llvmorg-16.0.0, llvmorg-16.0.0-rc4, llvmorg-16.0.0-rc3, llvmorg-16.0.0-rc2, llvmorg-16.0.0-rc1, llvmorg-17-init, llvmorg-15.0.7, llvmorg-15.0.6, llvmorg-15.0.5, llvmorg-15.0.4, llvmorg-15.0.3, llvmorg-15.0.2, llvmorg-15.0.1, llvmorg-15.0.0, llvmorg-15.0.0-rc3, llvmorg-15.0.0-rc2, llvmorg-15.0.0-rc1, llvmorg-16-init, llvmorg-14.0.6, llvmorg-14.0.5, llvmorg-14.0.4, llvmorg-14.0.3, llvmorg-14.0.2, llvmorg-14.0.1, llvmorg-14.0.0, llvmorg-14.0.0-rc4, llvmorg-14.0.0-rc3, llvmorg-14.0.0-rc2, llvmorg-14.0.0-rc1, llvmorg-15-init, llvmorg-13.0.1, llvmorg-13.0.1-rc3, llvmorg-13.0.1-rc2, llvmorg-13.0.1-rc1 |
|
| #
9b5c9c46 |
| 02-Nov-2021 |
Balazs Benics <[email protected]> |
[analyzer] Dump checker name if multiple checkers evaluate the same call
Previously, if accidentally multiple checkers `eval::Call`-ed the same `CallEvent`, in debug builds the analyzer detected thi
[analyzer] Dump checker name if multiple checkers evaluate the same call
Previously, if accidentally multiple checkers `eval::Call`-ed the same `CallEvent`, in debug builds the analyzer detected this and crashed with the message stating this. Unfortunately, the message did not state the offending checkers violating this invariant. This revision addresses this by printing a more descriptive message before aborting.
Reviewed By: martong
Differential Revision: https://reviews.llvm.org/D112889
show more ...
|
|
Revision tags: llvmorg-13.0.0, llvmorg-13.0.0-rc4, llvmorg-13.0.0-rc3, llvmorg-13.0.0-rc2, llvmorg-13.0.0-rc1, llvmorg-14-init |
|
| #
3dae0191 |
| 29-Jun-2021 |
Balazs Benics <[email protected]> |
[analyzer] Make CheckerManager::hasPathSensitiveCheckers() complete again
It turns out that the CheckerManager::hasPathSensitiveCheckers() missed checking for the BeginFunctionCheckers. It seems lik
[analyzer] Make CheckerManager::hasPathSensitiveCheckers() complete again
It turns out that the CheckerManager::hasPathSensitiveCheckers() missed checking for the BeginFunctionCheckers. It seems like other callbacks are also missing: - ObjCMessageNilCheckers - BeginFunctionCheckers - NewAllocatorCheckers - PointerEscapeCheckers - EndOfTranslationUnitCheckers
In this patch, I wanted to use a fold-expression, but until C++17 arrives we are left with the old-school method.
When I tried to write a unittest I observed an interesting behavior. I subscribed only to the BeginFunction event, it was not fired. However, when I also defined the PreCall with an empty handler, suddenly both fired. I could add this test demonstrating the issue, but I don't think it would serve much value in a long run. I don't expect regressions for this.
However, I think it would be great to enforce the completeness of this list in a runtime check. I could not come up with a solution for this though.
PS: Thank you @Szelethus for helping me debugging this.
Differential Revision: https://reviews.llvm.org/D105101
Reviewed by: vsavchenko
show more ...
|
|
Revision tags: llvmorg-12.0.1, llvmorg-12.0.1-rc4, llvmorg-12.0.1-rc3, llvmorg-12.0.1-rc2, llvmorg-12.0.1-rc1, llvmorg-12.0.0, llvmorg-12.0.0-rc5, llvmorg-12.0.0-rc4, llvmorg-12.0.0-rc3, llvmorg-12.0.0-rc2, llvmorg-11.1.0, llvmorg-11.1.0-rc3, llvmorg-12.0.0-rc1, llvmorg-13-init, llvmorg-11.1.0-rc2, llvmorg-11.1.0-rc1, llvmorg-11.0.1, llvmorg-11.0.1-rc2, llvmorg-11.0.1-rc1, llvmorg-11.0.0, llvmorg-11.0.0-rc6, llvmorg-11.0.0-rc5, llvmorg-11.0.0-rc4, llvmorg-11.0.0-rc3, llvmorg-11.0.0-rc2, llvmorg-11.0.0-rc1, llvmorg-12-init, llvmorg-10.0.1, llvmorg-10.0.1-rc4, llvmorg-10.0.1-rc3, llvmorg-10.0.1-rc2 |
|
| #
37c1bf21 |
| 25-Jun-2020 |
Nithin Vadukkumchery Rajendrakumar <[email protected]> |
[analyzer] Enable constructor support in evalCall event.
Pass EvalCallOptions via runCheckersForEvalCall into defaultEvalCall. Update the AnalysisOrderChecker to support evalCall for testing.
Diffe
[analyzer] Enable constructor support in evalCall event.
Pass EvalCallOptions via runCheckersForEvalCall into defaultEvalCall. Update the AnalysisOrderChecker to support evalCall for testing.
Differential Revision: https://reviews.llvm.org/D82256
show more ...
|
|
Revision tags: llvmorg-10.0.1-rc1, llvmorg-10.0.0, llvmorg-10.0.0-rc6, llvmorg-10.0.0-rc5, llvmorg-10.0.0-rc4, llvmorg-10.0.0-rc3 |
|
| #
f2be30de |
| 01-Mar-2020 |
Kirstóf Umann <[email protected]> |
[analyzer][NFC] Merge checkNewAllocator's paramaters into CXXAllocatorCall
Party based on this thread: http://lists.llvm.org/pipermail/cfe-dev/2020-February/064754.html.
This patch merges two of CX
[analyzer][NFC] Merge checkNewAllocator's paramaters into CXXAllocatorCall
Party based on this thread: http://lists.llvm.org/pipermail/cfe-dev/2020-February/064754.html.
This patch merges two of CXXAllocatorCall's parameters, so that we are able to supply a CallEvent object to check::NewAllocatorCall (see the description of D75430 to see why this would be great).
One of the things mentioned by @NoQ was the following:
I think at this point we might actually do a good job sorting out this check::NewAllocator issue because we have a "separate" "Environment" to hold the other SVal, which is "objects under construction"! - so we should probably simply teach CXXAllocatorCall to extract the value from the objects-under-construction trait of the program state and we're good.
I had MallocChecker in my crosshair for now, so I admittedly threw together something as a proof of concept. Now that I know that this effort is worth pursuing though, I'll happily look for a solution better then demonstrated in this patch.
Differential Revision: https://reviews.llvm.org/D75431
show more ...
|
| #
2aac0c47 |
| 28-Feb-2020 |
Kristóf Umann <[email protected]> |
Reland "[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes"
Originally commited in rG57b8a407493c34c3680e7e1e4cb82e097f43744a, bu
Reland "[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes"
Originally commited in rG57b8a407493c34c3680e7e1e4cb82e097f43744a, but it broke the modules bot. This is solved by putting the contructors of the CheckerManager class to the Frontend library.
Differential Revision: https://reviews.llvm.org/D75360
show more ...
|
| #
56abcfad |
| 23-Mar-2020 |
Jonas Devlieghere <[email protected]> |
Revert "[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes"
Temporarily reverting this patch because it breaks the modules build.
|
| #
57b8a407 |
| 28-Feb-2020 |
Kristóf Umann <[email protected]> |
[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes
Its been a while since my CheckerRegistry related patches landed, allow me to
[analyzer][NFC] Tie CheckerRegistry to CheckerManager, allow CheckerManager to be constructed for non-analysis purposes
Its been a while since my CheckerRegistry related patches landed, allow me to refresh your memory:
During compilation, TblGen turns clang/include/clang/StaticAnalyzer/Checkers/Checkers.td into (build directory)/tools/clang/include/clang/StaticAnalyzer/Checkers/Checkers.inc. This is a file that contains the full name of the checkers, their options, etc.
The class that is responsible for parsing this file is CheckerRegistry. The job of this class is to establish what checkers are available for the analyzer (even from plugins and statically linked but non-tblgen generated files!), and calculate which ones should be turned on according to the analyzer's invocation.
CheckerManager is the class that is responsible for the construction and storage of checkers. This process works by first creating a CheckerRegistry object, and passing itself to CheckerRegistry::initializeManager(CheckerManager&), which will call the checker registry functions (for example registerMallocChecker) on it.
The big problem here is that these two classes lie in two different libraries, so their interaction is pretty awkward. This used to be far worse, but I refactored much of it, which made things better but nowhere near perfect.
---
This patch changes how the above mentioned two classes interact. CheckerRegistry is mainly used by CheckerManager, and they are so intertwined, it makes a lot of sense to turn in into a field, instead of a one-time local variable. This has additional benefits: much of the information that CheckerRegistry conveniently holds is no longer thrown away right after the analyzer's initialization, and opens the possibility to pass CheckerManager in the shouldRegister* function rather then LangOptions (D75271).
There are a few problems with this. CheckerManager isn't the only user, when we honor help flags like -analyzer-checker-help, we only have access to a CompilerInstance class, that is before the point of parsing the AST. CheckerManager makes little sense without ASTContext, so I made some changes and added new constructors to make it constructible for the use of help flags.
Differential Revision: https://reviews.llvm.org/D75360
show more ...
|
| #
57f70d18 |
| 09-Mar-2020 |
Adam Balogh <[email protected]> |
[Analyzer] Mark constant member functions const in CheckerManager
Most of the getter functions (and a reporter function) in `CheckerManager` are constant but not marked as `const`. This prevents fun
[Analyzer] Mark constant member functions const in CheckerManager
Most of the getter functions (and a reporter function) in `CheckerManager` are constant but not marked as `const`. This prevents functions having only a constant reference to `CheckerManager` using these member functions. This patch fixes this issue.
Differential Revision: https://reviews.llvm.org/D75839
show more ...
|
|
Revision tags: llvmorg-10.0.0-rc2, llvmorg-10.0.0-rc1, llvmorg-11-init, llvmorg-9.0.1, llvmorg-9.0.1-rc3, llvmorg-9.0.1-rc2, llvmorg-9.0.1-rc1 |
|
| #
96484286 |
| 12-Nov-2019 |
Mark de Wever <[email protected]> |
[Analyzer] Use a reference in a range-based for
Let the checkers use a reference instead of a copy in a range-based for loop.
This avoids new warnings due to D68912 adds -Wrange-loop-analysis to -W
[Analyzer] Use a reference in a range-based for
Let the checkers use a reference instead of a copy in a range-based for loop.
This avoids new warnings due to D68912 adds -Wrange-loop-analysis to -Wall.
Differential Revision: https://reviews.llvm.org/D70047
show more ...
|
|
Revision tags: llvmorg-9.0.0, llvmorg-9.0.0-rc6, llvmorg-9.0.0-rc5 |
|
| #
72649423 |
| 12-Sep-2019 |
Kristof Umann <[email protected]> |
[analyzer][NFC] Fix inconsistent references to checkers as "checks"
Traditionally, clang-tidy uses the term check, and the analyzer uses checker, but in the very early years, this wasn't the case, a
[analyzer][NFC] Fix inconsistent references to checkers as "checks"
Traditionally, clang-tidy uses the term check, and the analyzer uses checker, but in the very early years, this wasn't the case, and code originating from the early 2010's still incorrectly refer to checkers as checks.
This patch attempts to hunt down most of these, aiming to refer to checkers as checkers, but preserve references to callback functions (like checkPreCall) as checks.
Differential Revision: https://reviews.llvm.org/D67140
llvm-svn: 371760
show more ...
|
|
Revision tags: llvmorg-9.0.0-rc4, llvmorg-9.0.0-rc3, llvmorg-9.0.0-rc2, llvmorg-9.0.0-rc1, llvmorg-10-init, llvmorg-8.0.1, llvmorg-8.0.1-rc4, llvmorg-8.0.1-rc3 |
|
| #
44820630 |
| 19-Jun-2019 |
Artem Dergachev <[email protected]> |
[analyzer] NFC: Change evalCall() to provide a CallEvent.
This changes the checker callback signature to use the modern, easy to use interface. Additionally, this unblocks future work on allowing ch
[analyzer] NFC: Change evalCall() to provide a CallEvent.
This changes the checker callback signature to use the modern, easy to use interface. Additionally, this unblocks future work on allowing checkers to implement evalCall() for calls that don't correspond to any call-expression or require additional information that's only available as part of the CallEvent, such as C++ constructors and destructors.
Differential Revision: https://reviews.llvm.org/D62440
llvm-svn: 363893
show more ...
|
|
Revision tags: llvmorg-8.0.1-rc2 |
|
| #
b7ca72a1 |
| 29-May-2019 |
Csaba Dabis <[email protected]> |
[analyzer] print() JSONify: Checker messages implementation
Summary: -
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, a.si
[analyzer] print() JSONify: Checker messages implementation
Summary: -
Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus
Reviewed By: NoQ
Subscribers: szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62086
llvm-svn: 361982
show more ...
|
|
Revision tags: llvmorg-8.0.1-rc1, llvmorg-8.0.0, llvmorg-8.0.0-rc5 |
|
| #
748c139a |
| 08-Mar-2019 |
Kristof Umann <[email protected]> |
[analyzer] Emit an error rather than assert on invalid checker option input
Asserting on invalid input isn't very nice, hence the patch to emit an error instead.
This is the first of many patches t
[analyzer] Emit an error rather than assert on invalid checker option input
Asserting on invalid input isn't very nice, hence the patch to emit an error instead.
This is the first of many patches to overhaul the way we handle checker options.
Differential Revision: https://reviews.llvm.org/D57850
llvm-svn: 355704
show more ...
|
|
Revision tags: llvmorg-8.0.0-rc4, llvmorg-8.0.0-rc3, llvmorg-7.1.0, llvmorg-7.1.0-rc1, llvmorg-8.0.0-rc2, llvmorg-8.0.0-rc1 |
|
| #
2946cd70 |
| 19-Jan-2019 |
Chandler Carruth <[email protected]> |
Update the file headers across all of the LLVM projects in the monorepo to reflect the new license.
We understand that people may be surprised that we're moving the header entirely to discuss the ne
Update the file headers across all of the LLVM projects in the monorepo to reflect the new license.
We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach.
Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository.
llvm-svn: 351636
show more ...
|
|
Revision tags: llvmorg-7.0.1, llvmorg-7.0.1-rc3, llvmorg-7.0.1-rc2, llvmorg-7.0.1-rc1 |
|
| #
0e912f3b |
| 20-Oct-2018 |
Aleksei Sidorin <[email protected]> |
[NFC][Test commit] Fix typos in a comment
llvm-svn: 344847
|
| #
33e5a158 |
| 21-Sep-2018 |
George Karpenkov <[email protected]> |
[analyzer] Associate diagnostics created in checkEndFunction with a return statement, if possible
If not possible, use the last line of the declaration, as before.
Differential Revision: https://re
[analyzer] Associate diagnostics created in checkEndFunction with a return statement, if possible
If not possible, use the last line of the declaration, as before.
Differential Revision: https://reviews.llvm.org/D52326
llvm-svn: 342768
show more ...
|
|
Revision tags: llvmorg-7.0.0, llvmorg-7.0.0-rc3, llvmorg-7.0.0-rc2, llvmorg-7.0.0-rc1 |
|
| #
ed8c05cc |
| 16-Jul-2018 |
Reka Kovacs <[email protected]> |
[analyzer] Make checkEndFunction() give access to the return statement.
Differential Revision: https://reviews.llvm.org/D49387
llvm-svn: 337215
|
|
Revision tags: llvmorg-6.0.1, llvmorg-6.0.1-rc3, llvmorg-6.0.1-rc2 |
|
| #
9fc8faf9 |
| 09-May-2018 |
Adrian Prantl <[email protected]> |
Remove \brief commands from doxygen comments.
This is similar to the LLVM change https://reviews.llvm.org/D46290.
We've been running doxygen with the autobrief option for a couple of years now. Thi
Remove \brief commands from doxygen comments.
This is similar to the LLVM change https://reviews.llvm.org/D46290.
We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all.
Patch produced by
for i in $(git grep -l '\@brief'); do perl -pi -e 's/\@brief //g' $i & done for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
Differential Revision: https://reviews.llvm.org/D46320
llvm-svn: 331834
show more ...
|
|
Revision tags: llvmorg-6.0.1-rc1, llvmorg-5.0.2, llvmorg-5.0.2-rc2, llvmorg-5.0.2-rc1, llvmorg-6.0.0 |
|
| #
e580d831 |
| 26-Feb-2018 |
Eugene Zelenko <[email protected]> |
[StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 326146
|
|
Revision tags: llvmorg-6.0.0-rc3, llvmorg-6.0.0-rc2 |
|
| #
1c64e617 |
| 18-Jan-2018 |
Artem Dergachev <[email protected]> |
[analyzer] operator new: Add a new ProgramPoint for check::NewAllocator.
Add PostAllocatorCall program point to represent the moment in the analysis between the operator new() call and the construct
[analyzer] operator new: Add a new ProgramPoint for check::NewAllocator.
Add PostAllocatorCall program point to represent the moment in the analysis between the operator new() call and the constructor call. Pointer cast from "void *" to the correct object pointer type has already happened by this point.
The new program point, unlike the previously used PostImplicitCall, contains a reference to the new-expression, which allows adding path diagnostics over it.
Differential Revision: https://reviews.llvm.org/D41800 rdar://problem/12180598
llvm-svn: 322796
show more ...
|
| #
13b2026b |
| 17-Jan-2018 |
Artem Dergachev <[email protected]> |
[analyzer] operator new: Add a new checker callback, check::NewAllocator.
The callback runs after operator new() and before the construction and allows the checker to access the casted return value
[analyzer] operator new: Add a new checker callback, check::NewAllocator.
The callback runs after operator new() and before the construction and allows the checker to access the casted return value of operator new() (in the sense of r322780) which is not available in the PostCall callback for the allocator call.
Update MallocChecker to use the new callback instead of PostStmt<CXXNewExpr>, which gets called after the constructor.
Differential Revision: https://reviews.llvm.org/D41406 rdar://problem/12180598
llvm-svn: 322787
show more ...
|
|
Revision tags: llvmorg-6.0.0-rc1, llvmorg-5.0.1, llvmorg-5.0.1-rc3, llvmorg-5.0.1-rc2, llvmorg-5.0.1-rc1, llvmorg-5.0.0, llvmorg-5.0.0-rc5, llvmorg-5.0.0-rc4, llvmorg-5.0.0-rc3, llvmorg-5.0.0-rc2, llvmorg-5.0.0-rc1, llvmorg-4.0.1, llvmorg-4.0.1-rc3, llvmorg-4.0.1-rc2, llvmorg-4.0.1-rc1, llvmorg-4.0.0, llvmorg-4.0.0-rc4, llvmorg-4.0.0-rc3, llvmorg-4.0.0-rc2, llvmorg-4.0.0-rc1 |
|
| #
b570195c |
| 13-Jan-2017 |
Anna Zaks <[email protected]> |
[analyzer] Add LocationContext as a parameter to checkRegionChanges
This patch adds LocationContext to checkRegionChanges and removes wantsRegionChangeUpdate as it was unused.
A patch by Krzysztof
[analyzer] Add LocationContext as a parameter to checkRegionChanges
This patch adds LocationContext to checkRegionChanges and removes wantsRegionChangeUpdate as it was unused.
A patch by Krzysztof Wiśniewski!
Differential Revision: https://reviews.llvm.org/D27090
llvm-svn: 291869
show more ...
|
|
Revision tags: llvmorg-3.9.1, llvmorg-3.9.1-rc3, llvmorg-3.9.1-rc2, llvmorg-3.9.1-rc1 |
|
| #
1485992e |
| 16-Nov-2016 |
Anna Zaks <[email protected]> |
[analyzer] Remove unused check::RegionChanges::wantsRegionChangeUpdate callback
Remove the check::RegionChanges::wantsRegionChangeUpdate callback as it is no longer used (since checkPointerEscape ha
[analyzer] Remove unused check::RegionChanges::wantsRegionChangeUpdate callback
Remove the check::RegionChanges::wantsRegionChangeUpdate callback as it is no longer used (since checkPointerEscape has been added).
A patch by Krzysztof Wiśniewski!
Differential Revision: https://reviews.llvm.org/D26759
llvm-svn: 287175
show more ...
|
|
Revision tags: llvmorg-3.9.0, llvmorg-3.9.0-rc3, llvmorg-3.9.0-rc2, llvmorg-3.9.0-rc1, llvmorg-3.8.1, llvmorg-3.8.1-rc1, llvmorg-3.8.0, llvmorg-3.8.0-rc3 |
|
| #
8d922aa7 |
| 19-Feb-2016 |
Devin Coughlin <[email protected]> |
[analyzer] Add checker callback for beginning of function.
Add a checker callback that is called when the analyzer starts analyzing a function either at the top level or when inlined. This will be u
[analyzer] Add checker callback for beginning of function.
Add a checker callback that is called when the analyzer starts analyzing a function either at the top level or when inlined. This will be used by a follow-on patch making the DeallocChecker path sensitive.
Differential Revision: http://reviews.llvm.org/D17418
llvm-svn: 261293
show more ...
|
|
Revision tags: llvmorg-3.8.0-rc2, llvmorg-3.8.0-rc1, llvmorg-3.7.1, llvmorg-3.7.1-rc2, llvmorg-3.7.1-rc1 |
|
| #
02c6abc5 |
| 15-Sep-2015 |
Aaron Ballman <[email protected]> |
Silencing a -Wreturn-type warning; NFC.
llvm-svn: 247693
|