76 Commits

Author SHA1 Message Date
Balazs Benics
5c23e27ba1 [analyzer][NFC] Move away from using raw-for loops inside StaticAnalyzer
I'm involved with the Static Analyzer for the most part.
I think we should embrace newer language standard features and gradually
move forward.

Differential Revision: https://reviews.llvm.org/D154325
2023-07-05 08:56:13 +02:00
Balázs Kéri
4f0436dd15 [clang][analyzer] Merge apiModeling.StdCLibraryFunctions and StdCLibraryFunctionArgs checkers into one.
Main reason for this change is that these checkers were implemented in the same class
but had different dependency ordering. (NonNullParamChecker should run before StdCLibraryFunctionArgs
to get more special warning about null arguments, but the apiModeling.StdCLibraryFunctions was a modeling
checker that should run before other non-modeling checkers. The modeling checker changes state in a way
that makes it impossible to detect a null argument by NonNullParamChecker.)
To make it more simple, the modeling part is removed as separate checker and can be only used if
checker StdCLibraryFunctions is turned on, that produces the warnings too. Modeling the functions
without bug detection (for invalid argument) is not possible. The modeling of standard functions
does not happen by default from this change on.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D151225
2023-06-01 09:54:35 +02:00
Balázs Kéri
6012cadc40 [clang][analyzer] Display buffer sizes in StdCLibraryFunctionArgs checker
If a wrong (too small) buffer argument is found, the dynamic buffer size and
values of connected arguments are displayed in the warning message, if
these are simple known integer values.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D149321
2023-05-17 09:34:05 +02:00
Balázs Kéri
258c9bebbd [clang][analyzer] Handle special value AT_FDCWD in affected standard functions
Some file and directory related functions have an integer file descriptor argument
that can be a valid file descriptor or a special value AT_FDCWD. This value is
relatively often used in open source projects and is usually defined as a negative
number, and the checker reports false warnings (a valid file descriptor is not
negative) if this fix is not included.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D149160
2023-05-16 09:28:14 +02:00
Balázs Kéri
ce1fb03db8 [clang][analyzer] Improve bug reports of StdLibraryFunctionsChecker.
Add an additional explanation of what is wrong if a constraint is
not satisfied, in some cases.
Additionally the bug report generation is changed to use raw_ostream.

Reviewed By: Szelethus, NoQ

Differential Revision: https://reviews.llvm.org/D144003
2023-04-12 10:24:55 +02:00
Balázs Kéri
353155a1a5 [clang][analyzer][NFC] Refactor code of StdLibraryFunctionsChecker.
The code was difficult to maintain (big internal class definitions
with long inline functions, other functions of the same class at
different location far away, irregular ordering of classes and
function definitions). It is now improved to some extent.
New functions are added to RangeConstraint to remove code repetition,
these are useful for planned new features too.
Comments are improved.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D143751
2023-03-09 11:54:52 +01:00
Balázs Kéri
ddc5d40dd2 [clang][analyzer] Make messages of StdCLibraryFunctionsChecker user-friendly
Warnings and notes of checker alpha.unix.StdLibraryFunctionArgs are
improved. Previously one warning and one note was emitted for every
finding, now one warning is emitted only that contains a detailed
description of the found issue.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D143194
2023-02-15 09:22:48 +01:00
Kazu Hirata
6ad0788c33 [clang] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to remove #include "llvm/ADT/Optional.h".

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 12:31:01 -08:00
Balázs Kéri
3c7fe7d09d [clang][analyzer] Add stream related functions to StdLibraryFunctionsChecker.
Additional stream handling functions are added.
These are partially evaluated by StreamChecker, result of the addition is
check for more preconditions and construction of success and failure branches
with specific errno handling.

Reviewed By: Szelethus

Differential Revision: https://reviews.llvm.org/D140387
2023-01-06 11:04:24 +01:00
Balázs Kéri
da0660691f [clang][analyzer] No new nodes when bug is detected in StdLibraryFunctionsChecker.
The checker applies constraints in a sequence and adds new nodes for these states.
If a constraint violation is found this sequence should be stopped with a sink
(error) node. Instead the `generateErrorNode` did add a new error node as a new
branch that is parallel to the other node sequence, the other branch was not
stopped and analysis was continuing on that invalid branch.
To add an error node after any previous node a new version of `generateErrorNode`
is needed, this function is added here and used by `StdLibraryFunctionsChecker`.
The added test executes a situation where the checker adds a number of
constraints before it finds a constraint violation.

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D137722
2022-12-14 09:51:43 +01:00
Kazu Hirata
b5fdd533e5 [Checkers] Use std::optional in StdLibraryFunctionsChecker.cpp (NFC)
This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-10 08:09:00 -08:00
Kazu Hirata
180600660b [StaticAnalyzer] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03 11:34:24 -08:00
Gabor Marton
82a50812f7 [analyzer][StdLibraryFunctionsChecker] Add NoteTags for applied arg
constraints

In this patch I add a new NoteTag for each applied argument constraint.
This way, any other checker that reports a bug - where the applied
constraint is relevant - will display the corresponding note. With this
change we provide more information for the users to understand some
bug reports easier.

Differential Revision: https://reviews.llvm.org/D101526

Reviewed By: NoQ
2022-10-26 16:33:25 +02:00
Balázs Kéri
d56a1c6824 [clang][analyzer] Errno modeling code refactor (NFC).
Some of the code used in StdLibraryFunctionsChecker is applicable to
other checkers, this is put into common functions. Errno related
parts of the checker are simplified and renamed. Documentations in
errno_modeling functions are updated.

This change makes it available to have more checkers that perform
modeling of some standard functions. These can set the errno state
with common functions and the bug report messages (note tags) can
look similar.

Reviewed By: steakhal, martong

Differential Revision: https://reviews.llvm.org/D131879
2022-09-01 09:05:59 +02:00
Kazu Hirata
a210f404da [clang] Remove redundant virtual specifies (NFC)
Identified with modernize-use-override.
2022-07-24 22:02:58 -07:00
Balázs Kéri
7dc81c6244 [clang][analyzer] Fix StdLibraryFunctionsChecker 'mkdir' return value.
The functions 'mkdir', 'mknod', 'mkdirat', 'mknodat' return 0 on success
and -1 on failure. The checker modeled these functions with a >= 0
return value on success which is changed to 0 only. This fix makes
ErrnoChecker work better for these functions.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D127277
2022-06-23 11:27:26 +02:00
Balázs Kéri
957014da2d [clang][Analyzer] Add errno state to standard functions modeling.
This updates StdLibraryFunctionsChecker to set the state of 'errno'
by using the new errno_modeling functionality.
The errno value is set in the PostCall callback. Setting it in call::Eval
did not work for some reason and then every function should be
EvalCallAsPure which may be bad to do. Now the errno value and state
is not allowed to be checked in any PostCall checker callback because
it is unspecified if the errno was set already or will be set later
by this checker.

Reviewed By: martong, steakhal

Differential Revision: https://reviews.llvm.org/D125400
2022-06-21 08:56:41 +02:00
Balazs Benics
96ccb690a0 [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions
Depends on D125709

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D127742
2022-06-15 16:58:13 +02:00
Artem Dergachev
f68c0a2f58 [analyzer] Add path note tags to standard library function summaries.
The patch is straightforward except the tiny fix in BugReporterVisitors.cpp
that suppresses a default note for "Assuming pointer value is null" when
a note tag from the checker is present. This is probably the right thing to do
but also definitely not a complete solution to the problem of different sources
of path notes being unaware of each other, which is a large and annoying issue
that we have to deal with. Note tags really help there because they're nicely
introspectable. The problem is demonstrated by the newly added getenv() test.

Differential Revision: https://reviews.llvm.org/D122285
2022-04-28 17:17:05 -07:00
Vince Bridgers
5114db933d [analyzer] Clean checker options from bool to DefaultBool (NFC)
A recent review emphasized the preference to use DefaultBool instead of
bool for checker options. This change is a NFC and cleans up some of the
instances where bool was used, and could be changed to DefaultBool.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D123464
2022-04-23 14:47:29 -05:00
Zarko Todorovski
d8e5a0c42b [clang][NFC] Inclusive terms: replace some uses of sanity in clang
Rewording of comments to avoid using `sanity test, sanity check`.

Reviewed By: aaron.ballman, Quuxplusone

Differential Revision: https://reviews.llvm.org/D114025
2021-11-19 14:58:35 -05:00
Balazs Benics
edde4efc66 [analyzer] Introduce the assume-controlled-environment config option
If the `assume-controlled-environment` is `true`, we should expect `getenv()`
to succeed, and the result should not be considered tainted.
By default, the option will be `false`.

Reviewed By: NoQ, martong

Differential Revision: https://reviews.llvm.org/D111296
2021-10-13 10:50:26 +02:00
Balazs Benics
7fc150309d [analyzer] Bifurcate on getenv() calls
The `getenv()` function might return `NULL` just like any other function.
However, in case of `getenv()` a state-split seems justified since the
programmer should expect the failure of this function.

`secure_getenv(const char *name)` behaves the same way but is not handled
right now.
Note that `std::getenv()` is also not handled.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D111245
2021-10-13 10:50:26 +02:00
Gabor Marton
4b99f9c7db [analyzer][StdLibraryFunctionsChecker] Track dependent arguments
When we report an argument constraint violation, we should track those
other arguments that participate in the evaluation of the violation. By
default, we depend only on the argument that is constrained, however,
there are some special cases like the buffer size constraint that might
be encoded in another argument(s).

Differential Revision: https://reviews.llvm.org/D101358
2021-04-27 15:35:58 +02:00
Gabor Marton
a7cb951fa4 [Analyzer][StdLibraryFunctionsChecker] Describe arg constraints
In this patch, I provide a detailed explanation for each argument
constraint. This explanation is added in an extra 'note' tag, which is
displayed alongside the warning.
Since these new notes describe clearly the constraint, there is no need
to provide the number of the argument (e.g. 'Arg3') within the warning.
However, I decided to keep the name of the constraint in the warning (but
this could be a subject of discussion) in order to be able to identify
the different kind of constraint violations easily in a bug database
(e.g. CodeChecker).

Differential Revision: https://reviews.llvm.org/D101060
2021-04-23 17:27:54 +02:00
Charusso
9b3df78b4c [analyzer] DynamicSize: Rename 'size' to 'extent' 2021-04-05 19:20:43 +02:00
Vassil Vassilev
0cb7e7ca0c Make iteration over the DeclContext::lookup_result safe.
The idiom:
```
DeclContext::lookup_result R = DeclContext::lookup(Name);
for (auto *D : R) {...}
```

is not safe when in the loop body we trigger deserialization from an AST file.
The deserialization can insert new declarations in the StoredDeclsList whose
underlying type is a vector. When the vector decides to reallocate its storage
the pointer we hold becomes invalid.

This patch replaces a SmallVector with an singly-linked list. The current
approach stores a SmallVector<NamedDecl*, 4> which is around 8 pointers.
The linked list is 3, 5, or 7. We do better in terms of memory usage for small
cases (and worse in terms of locality -- the linked list entries won't be near
each other, but will be near their corresponding declarations, and we were going
to fetch those memory pages anyway). For larger cases: the vector uses a
doubling strategy for reallocation, so will generally be between half-full and
full. Let's say it's 75% full on average, so there's N * 4/3 + 4 pointers' worth
of space allocated currently and will be 2N pointers with the linked list. So we
break even when there are N=6 entries and slightly lose in terms of memory usage
after that. We suspect that's still a win on average.

Thanks to @rsmith!

Differential revision: https://reviews.llvm.org/D91524
2021-03-17 08:59:04 +00:00
Valeriy Savchenko
c7635040ce [analyzer] Fix StdLibraryFunctionsChecker performance issue
`initFunctionSummaries` lazily initializes a data structure with
function summaries for standard library functions.  It is called for
every pre-, post-, and eval-call events, i.e. 3 times for each call on
the path.  If the initialization doesn't find any standard library
functions in the translation unit, it will get re-tried (with the same
effect) many times even for small translation units.

For projects not using standard libraries, the speed-up can reach 50%
after this patch.

Differential Revision: https://reviews.llvm.org/D98244
2021-03-10 10:44:04 +03:00
Simon Pilgrim
879c12d95a Fix null dereference static analysis warning. NFCI.
Replace cast_or_null<> with cast<> as we immediately dereference the pointer afterward so we're not expecting a null pointer.
2021-01-26 16:19:18 +00:00
Gabor Marton
febe75032f [analyzer][StdLibraryFunctionsChecker] Add more return value contraints
This time, we add contraints to functions that either return with [0, -1] or
with a file descriptor.

Differential Revision: https://reviews.llvm.org/D92771
2020-12-08 17:04:29 +01:00
Gabor Marton
d14c631673 [analyzer][StdLibraryFunctionsChecker] Make close and mmap to accept -1 as fd
close:
It is quite often that users chose to call close even if the fd is
negative. Theoretically, it would be nicer to close only valid fds, but
in practice the implementations of close just returns with EBADF in case
of a non-valid fd param. So, we can eliminate many false positives if we
let close to take -1 as an fd. Other negative values are very unlikely,
because open and other fd factories return with -1 in case of failure.

mmap:
In the case of MAP_ANONYMOUS flag (which is supported e.g. in Linux) the
mapping is not backed by any file; its contents are initialized to zero.
The fd argument is ignored; however, some implementations require fd to
be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable
applications should ensure this.
Consequently, we must allow -1 as the 4th arg.

Differential Revision: https://reviews.llvm.org/D92764
2020-12-08 16:58:30 +01:00
Gabor Marton
b40b3196b3 [analyzer][StdLibraryFunctionsChecker] Add return value constraint to functions with BufferSize
Differential Revision: https://reviews.llvm.org/D92474
2020-12-02 17:54:48 +01:00
Balazs Benics
ee073c7985 [analyzer][StdLibraryFunctionsChecker] Fix typos in summaries of mmap and mmap64
The fd parameter of
```
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
```
should be constrained to the range [0, IntMax] as that is of type int.
Constraining to the range [0, Off_tMax] would result in a crash as that is
of a signed type with the value of 0xff..f (-1).

The crash would happen when we try to apply the arg constraints.
At line 583: assert(Min <= Max), as 0 <= -1 is not satisfied

The mmap64 is fixed for the same reason.

Reviewed By: martong, vsavchenko

Differential Revision: https://reviews.llvm.org/D92307
2020-11-30 18:06:28 +01:00
Gabor Marton
11d2e63ab0 [analyzer][StdLibraryFunctionsChecker] Separate the signature from the summaries
The signature should not be part of the summaries as many FIXME comments
suggests. By separating the signature, we open up the way to a generic
matching implementation which could be used later under the hoods of
CallDescriptionMap.

Differential Revision: https://reviews.llvm.org/D88100
2020-09-23 10:59:34 +02:00
Gabor Marton
d63a945a13 [analyzer][StdLibraryFunctionsChecker] Fix getline/getdelim signatures
It is no longer needed to add summaries of 'getline' for different
possible underlying types of ssize_t. We can just simply lookup the
type.

Differential Revision: https://reviews.llvm.org/D88092
2020-09-23 10:48:14 +02:00
Gabor Marton
a012bc4c42 [analyzer][StdLibraryFunctionsChecker] Elaborate the summary of fread and fwrite
Add the BufferSize argument constraint to fread and fwrite. This change
itself makes it possible to discover a security critical case, described
in SEI-CERT ARR38-C.

We also add the not-null constraint on the 3rd arguments.

In this patch, I also remove those lambdas that don't take any
parameters (Fwrite, Fread, Getc), thus making the code better
structured.

Differential Revision: https://reviews.llvm.org/D87081
2020-09-15 16:35:39 +02:00
Gabor Marton
a97648b938 [analyzer][StdLibraryFunctionsChecker] Add better diagnostics
Differential Revision: https://reviews.llvm.org/D79431
2020-09-10 12:43:40 +02:00
Gabor Marton
b7586afc4d [analyzer][StdLibraryFunctionsChecker] Remove strcasecmp
There are 2 reasons to remove strcasecmp and strncasecmp.
1) They are also modeled in CStringChecker and the related argumentum
   contraints are checked there.
2) The argument constraints are checked in CStringChecker::evalCall.
   This is fundamentally flawed, they should be checked in checkPreCall.
   Even if we set up CStringChecker as a weak dependency for
   StdLibraryFunctionsChecker then the latter reports the warning always.
   Besides, CStringChecker fails to discover the constraint violation
   before the call, so, its evalCall returns with `true` and then
   StdCLibraryFunctions also tries to evaluate, this causes an assertion
   in CheckerManager.

Either we fix CStringChecker to handle the call prerequisites in
checkPreCall, or we must not evaluate any pure functions in
StdCLibraryFunctions that are also handled in CStringChecker.
We do the latter in this patch.

Differential Revision: https://reviews.llvm.org/D87239
2020-09-10 12:29:39 +02:00
Gabor Marton
d01280587d [analyzer][StdLibraryFunctionsChecker] Add POSIX pthread handling functions
Differential Revision: https://reviews.llvm.org/D84415
2020-09-07 17:47:01 +02:00
Gabor Marton
f0b9dbcfc7 [analyzer][StdLibraryFunctionsChecker] Add POSIX time handling functions
Differential Revision: https://reviews.llvm.org/D84248
2020-09-04 18:44:12 +02:00
Gabor Marton
fe0972d3e4 [analyzer][StdLibraryFunctionsChecker] Do not match based on the restrict qualifier in C++
The "restrict" keyword is illegal in C++, however, many libc
implementations use the "__restrict" compiler intrinsic in functions
prototypes. The "__restrict" keyword qualifies a type as a restricted type
even in C++.
In case of any non-C99 languages, we don't want to match based on the
restrict qualifier because we cannot know if the given libc implementation
qualifies the paramter type or not.

Differential Revision: https://reviews.llvm.org/D87097
2020-09-04 11:48:38 +02:00
Gabor Marton
a787a4ed16 [analyzer][StdLibraryFunctionsChecker] Use Optionals throughout the summary API
By using optionals, we no longer have to check the validity of types that we
get from a lookup. This way, the definition of the summaries have a declarative
form, there are no superflous conditions in the source code.

Differential Revision: https://reviews.llvm.org/D86531
2020-09-01 11:36:20 +02:00
Zurab Tsinadze
25bbe234e4 [analyzer] StdLibraryFunctionsChecker: Add support for new functions
`toupper`, `tolower`, `toascii` functions were added to
StdLibraryFunctionsChecker to fully cover CERT STR37-C rule:
https://wiki.sei.cmu.edu/confluence/x/BNcxBQ

Differential Revision: https://reviews.llvm.org/D85093
2020-08-12 16:20:00 +02:00
Gabor Marton
3ff220de90 [analyzer][StdLibraryFunctionsChecker] Add POSIX networking functions
Summary:
Adding networking functions from the POSIX standard (2017). This includes
functions that deal with sockets from socket.h, netdb.h.

In 'socket.h' of some libc implementations (e.g. glibc) with C99, sockaddr
parameter is a transparent union of the underlying sockaddr_ family of pointers
instead of being a pointer to struct sockaddr. In these cases, the standardized
signature will not match, thus we try to match with another signature that has
the joker Irrelevant type. In the case of transparent unions, we also not add
those constraints which require pointer types for the sockaddr param.

Interestingly, in 'netdb.h' sockaddr is not handled as a transparent union.

Tags: #clang

Differential Revision: https://reviews.llvm.org/D83407
2020-07-20 22:46:24 +02:00
Benjamin Kramer
b44470547e Make helpers static. NFC. 2020-07-09 13:48:56 +02:00
Gabor Marton
db4d5f7048 [analyzer][StdLibraryFunctionsChecker] Add POSIX file handling functions
Adding file handling functions from the POSIX standard (2017).
A new checker option is introduced to enable them.
In follow-up patches I am going to upstream networking, pthread, and other
groups of POSIX functions.

Differential Revision: https://reviews.llvm.org/D82288
2020-07-02 14:28:05 +02:00
Gabor Marton
634258b806 [analyzer] StdLibraryFunctionsChecker: Add support to lookup types
Summary:
In this patch I am trying to get rid of the `Irrelevant` types from the
signatures of the functions from the standard C library. For that I've
introduced `lookupType()` to be able to lookup arbitrary types in the global
scope. This makes it possible to define the signatures precisely.

Note 1) `fread`'s signature is now fixed to have the proper `FILE *restrict`
type when C99 is the language.
Note 2) There are still existing `Irrelevant` types, but they are all from
POSIX. I am planning to address those together with the missing POSIX functions
(in D79433).

Reviewers: xazax.hun, NoQ, Szelethus, balazske

Subscribers: whisperity, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D80016
2020-05-29 17:42:05 +02:00
Gabor Marton
16506d7890 [analyzer] StdLibraryFunctionsChecker: Add sanity checks for constraints
Summary:
Once we found a matching FunctionDecl for the given summary then we
validate the given constraints against that FunctionDecl. E.g. we
validate that a NotNull constraint is applied only on arguments that
have pointer types.

This is needed because when we matched the signature of the summary we
were working with incomplete function types, i.e. some intricate type
could have been marked as `Irrelevant` in the signature.

Reviewers: NoQ, Szelethus, balazske

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, steakhal, ASDenysPetrov, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77658
2020-05-29 16:38:45 +02:00
Gabor Marton
41928c97b6 [analyzer] ApiModeling: Add buffer size arg constraint with multiplier involved
Summary:
Further develop the buffer size argumentum constraint so it can handle sizes
that we can get by multiplying two variables.

Reviewers: Szelethus, NoQ, steakhal

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, Charusso, ASDenysPetrov, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77148
2020-05-29 16:24:26 +02:00
Gabor Marton
bd03ef19be [analyzer] ApiModeling: Add buffer size arg constraint
Summary:
Introducing a new argument constraint to confine buffer sizes. It is typical in
C APIs that a parameter represents a buffer and another param holds the size of
the buffer (or the size of the data we want to handle from the buffer).

Reviewers: NoQ, Szelethus, Charusso, steakhal

Subscribers: whisperity, xazax.hun, baloghadamsoftware, szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy, dkrupp, gamesh411, ASDenysPetrov, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77066
2020-05-29 16:13:57 +02:00