History log of /llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp (Results 1 – 25 of 697)
Revision (<<< Hide revision tags) (Show revision tags >>>) Date Author Comments
# abc8812d 29-Jan-2025 Jason Rice <ricejasonf@gmail.com>

[Clang][P1061] Add stuctured binding packs (#121417)

This is an implementation of P1061 Structure Bindings Introduce a Pack
without the ability to use packs outside of templates. There is a couple
o

[Clang][P1061] Add stuctured binding packs (#121417)

This is an implementation of P1061 Structure Bindings Introduce a Pack
without the ability to use packs outside of templates. There is a couple
of ways the AST could have been sliced so let me know what you think.
The only part of this change that I am unsure of is the
serialization/deserialization stuff. I followed the implementation of
other Exprs, but I do not really know how it is tested. Thank you for
your time considering this.

---------

Co-authored-by: Yanzuo Liu <zwuis@outlook.com>

show more ...


Revision tags: llvmorg-21-init
# 8fb42300 22-Jan-2025 Tom Honermann <tom.honermann@intel.com>

[SYCL] AST support for SYCL kernel entry point functions. (#122379)

A SYCL kernel entry point function is a non-member function or a static
member function declared with the `sycl_kernel_entry_poin

[SYCL] AST support for SYCL kernel entry point functions. (#122379)

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.

show more ...


Revision tags: llvmorg-19.1.7
# db81e8c4 06-Jan-2025 erichkeane <ekeane@nvidia.com>

[OpenACC] Initial sema implementation of 'update' construct

This executable construct has a larger list of clauses than some of the
others, plus has some additional restrictions. This patch impleme

[OpenACC] Initial sema implementation of 'update' construct

This executable construct has a larger list of clauses than some of the
others, plus has some additional restrictions. This patch implements
the AST node, plus the 'cannot be the body of a if, while, do, switch,
or label' statement restriction. Future patches will handle the
rest of the restrictions, which are based on clauses.

show more ...


# 21c785d7 03-Jan-2025 erichkeane <ekeane@nvidia.com>

[OpenACC] Implement 'set' construct sema

The 'set' construct is another fairly simple one, it doesn't have an
associated statement and only a handful of allowed clauses. This patch
implements it and

[OpenACC] Implement 'set' construct sema

The 'set' construct is another fairly simple one, it doesn't have an
associated statement and only a handful of allowed clauses. This patch
implements it and all the rules for it, allowing 3 of its for clauses.
The only exception is default_async, which will be implemented in a
future patch, because it isn't just being enabled, it needs a complete
new implementation.

show more ...


# bb27d5e5 02-Jan-2025 Donát Nagy <donat.nagy@ericsson.com>

[analyzer] Don't assume third iteration in loops (#119388)

This commit ensures that if the loop condition is opaque (the analyzer
cannot determine whether it's true or false) and there were at leas

[analyzer] Don't assume third iteration in loops (#119388)

This commit ensures that if the loop condition is opaque (the analyzer
cannot determine whether it's true or false) and there were at least two
iterations, then the analyzer doesn't make the unjustified assumption
that it can enter yet another iteration.

Note that the presence of a loop suggests that the developer thought
that two iterations can happen (otherwise an `if` would've been
sufficient), but it does not imply that the developer expected three or
four iterations -- and in fact there are many false positives where a
loop iterates over a two-element (or three-element) data structure, but
the analyzer cannot understand the loop condition and blindly assumes
that there may be three or more iterations. (In particular, analyzing
the FFMPEG project produces 100+ such false positives.)

Moreover, this provides some performance improvements in the sense that
the analyzer won't waste time on traversing the execution paths with 3
or 4 iterations in a loop (which are very similar to the paths with 2
iterations) and therefore will be able to traverse more branches
elsewhere on the `ExplodedGraph`.

This logic is disabled if the user enables the widen-loops analyzer
option (which is disabled by default), because the "simulate one final
iteration after the invalidation" execution path would be suppressed by
the "exit the loop if the loop condition is opaque and there were at
least two iterations" logic. If we want to support loop widening, we
would need to create a follow-up commit which ensures that it "plays
nicely" with this logic.

show more ...


# 4bbdb018 19-Dec-2024 erichkeane <ekeane@nvidia.com>

[OpenACC] Implement 'init' and 'shutdown' constructs

These two constructs are very simple and similar, and only support 3
different clauses, two of which are already implemented. This patch
adds AS

[OpenACC] Implement 'init' and 'shutdown' constructs

These two constructs are very simple and similar, and only support 3
different clauses, two of which are already implemented. This patch
adds AST nodes for both constructs, and leaves the device_num clause
unimplemented, but enables the other two.

show more ...


# 2b9abf0d 19-Dec-2024 Thurston Dang <thurston@google.com>

Revert "[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (#116462)"

This reverts commit 89da344e5879e5347b5057520d5230e40ae24831.

Reason: buildbot breakages e.g., https://lab.llvm.org/b

Revert "[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (#116462)"

This reverts commit 89da344e5879e5347b5057520d5230e40ae24831.

Reason: buildbot breakages e.g., https://lab.llvm.org/buildbot/#/builders/55/builds/4556 (for which the reverted patch is the only code change)

show more ...


# 89da344e 19-Dec-2024 Vinay Deshmukh <32487576+vinay-deshmukh@users.noreply.github.com>

[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (#116462)

Resolves #100762

Gist of the change:
1. All the symbol analysis, constraint manager and expression parsing
logic was alre

[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond) (#116462)

Resolves #100762

Gist of the change:
1. All the symbol analysis, constraint manager and expression parsing
logic was already present, but the previous code didn't "visit" the
expressions within `assume()` by parsing those expressions, all of the
code "just works" by evaluating the SVals, and hence leaning on the same
logic that makes the code with `__builtin_assume` work
2. "Ignore" an expression from adding in CFG if it has side-effects (
similar to CGStmt.cpp (todo add link))
3. Add additional test case for ternary operator handling and modify
CFG.cpp's VisitGuardedExpr code for `continue`-ing if the `ProgramPoint`
is a `StmtPoint`

---------

Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>

show more ...


# e34cc7c9 17-Dec-2024 erichkeane <ekeane@nvidia.com>

[OpenACC] Implement 'wait' construct

The arguments to this are the same as for the 'wait' clause, so this
reuses all of that infrastructure. So all this has to do is support a
pair of clauses that a

[OpenACC] Implement 'wait' construct

The arguments to this are the same as for the 'wait' clause, so this
reuses all of that infrastructure. So all this has to do is support a
pair of clauses that are already implemented (if and async), plus create
an AST node. This patch does so, and adds proper testing.

show more ...


Revision tags: llvmorg-19.1.6
# 010d0115 10-Dec-2024 erichkeane <ekeane@nvidia.com>

[OpenACC] Create AST nodes for 'data' constructs

These constructs are all very similar and closely related, so this patch
creates the AST nodes for them, serialization, printing/etc.
Additionally th

[OpenACC] Create AST nodes for 'data' constructs

These constructs are all very similar and closely related, so this patch
creates the AST nodes for them, serialization, printing/etc.
Additionally the restrictions are all added as tests/todos in the tests,
as those will have to be implemented once we get those clauses implemented.

show more ...


Revision tags: llvmorg-19.1.5
# b343f3f3 02-Dec-2024 Donát Nagy <donat.nagy@ericsson.com>

[analyzer][NFC] Cleanup BranchNodeBuilder (#117898)

Previously `BranchNodeBuilder` had a machinery to mark the two possible
branches (true, false) as infeasible, but this was completely useless in

[analyzer][NFC] Cleanup BranchNodeBuilder (#117898)

Previously `BranchNodeBuilder` had a machinery to mark the two possible
branches (true, false) as infeasible, but this was completely useless in
practice, because the `BranchNodeBuilder` objects where short-lived
local variables so the `markInfeasible()` calls did not affect any later
calls.

The only theoretical exception was that in `ExprEngine::processBranch`
the methods of `BranchNodeBuilder` were called within a `for` loop that
iterates over the nodes created by the `check::BranchCondition`
callbacks.

However, currently only two checkers listen to `check::BranchCondition`
and neither of them produces multiple out nodes. This is fortunate,
because if the `for` loop had multiple iterations, then the lingering
effects of `markInfeasible()` would have caused wildly incorrect
behavior.

_For example, let's assume that a hypothetical `check::BranchCondition`
callback transitions to two different states, and the condition
expression happens to be true in the first and false in the second. In
this situation the first iteration of the loop would mark the false
branch as 'infeasible' and then in the second iteration the analyzer
would skip creating the transition to the false branch (from the state
where that is the 'right' path forward)._

After removing `markInfeasible()`, it became clear that the
`isFeasible()` calls in `ExprEngine::processBranch` are redundant
because they only guarded a `generateNode` call -- which immediately
calls `isFeasible()` and does nothing on an infeasible branch.

At this point in the refactoring the only code writing the feasibility
data members is their initialization in the constructors of
`BranchNodeBuilder` and the only code reading them is the check at the
beginning of `BranchNodeBuilder::generateNode`, so it was
straightforward to remove them completely and simplify the logic of
`generateNode()` to let it directly check the nullness of the
`CFGBlock*` pointer that it wants to use.

Finally, after these changes it became clear that in
`ExprEngine::processBranch` the `else` branch
(corresponding to the case when `assumeCondition` fails) is equivalent
to the "normal" case, so I eliminated it as well.

I also update the capitalization of a few variables that are already
affected by this change.

show more ...


# 820403c4 29-Nov-2024 Balazs Benics <benicsbalazs@gmail.com>

[analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) (#118096)

Like in the test case:
```c++
struct String {
String(const String &) {}
};

struct MatchComponent {
unsigned

[analyzer] Never create Regions wrapping reference TypedValueRegions (NFCI) (#118096)

Like in the test case:
```c++
struct String {
String(const String &) {}
};

struct MatchComponent {
unsigned numbers[2];
String prerelease;
MatchComponent(MatchComponent const &) = default;
};

MatchComponent get();
void consume(MatchComponent const &);

MatchComponent parseMatchComponent() {
MatchComponent component = get();
component.numbers[0] = 10;
component.numbers[1] = 20;
return component; // We should have no stack addr escape warning here.
}

void top() {
consume(parseMatchComponent());
}
```

When calling `consume(parseMatchComponent())` the
`parseMatchComponent()` would return a copy of a temporary of
`component`. That copy would invoke the
`MatchComponent::MatchComponent(const MatchComponent &)` ctor.

That ctor would have a (reference typed) ParamVarRegion, holding the
location (lvalue) of the object we are about to copy (&component). So
far so good, but just before evaluating the binding operation for
initializing the `numbers` field of the temporary, we evaluate the
ArrayInitLoopExpr representing the by-value elementwise copy of the
array `component.numbers`. This is represented by a LazyCompoundVal,
because we (usually) don't just copy large arrays and bind many
individual direct bindings. Rather, we take a snapshot by using a LCV.

However, notice that the LCV representing this copy would look like
this:
lazyCompoundVal{ParamVarRegion{"reference param of cctor"}.numbers}

Notice that it refers to the numbers field of a reference. It would be
much better to desugar the reference to the actual object, thus it
should be: `lazyCompoundVal{component.numbers}`

Actually, when binding the result of the ArrayInitLoopExpr to the
`temp_object.numbers` in the compiler-generated member initializer of
the cctor, we should have two individual direct bindings because this is
a "small array":
```
binding &Element{temp_object.numbers, 0} <- loadFrom(&Element{component.numbers, 0})
binding &Element{temp_object.numbers, 1} <- loadFrom(&Element{component.numbers, 1})
```
Where `loadFrom(...)` would be:
```
loadFrom(&Element{component.numbers, 0}): 10 U32b
loadFrom(&Element{component.numbers, 1}): 20 U32b
```
So the store should look like this, after PostInitializer of
`temp_object.numbers`:
```
temp_object at offset 0: 10 U32b
temp_object at offset 32: 20 U32b
```

The lesson is that it's okay to have TypedValueRegions of references as
long as we don't form subregions of those. If we ever want to refer to a
subregion of a "reference" we actually meant to "desugar" the reference
and slice a subregion of the pointee of the reference instead.

Once this canonicalization is in place, we can also drop the special
handling of references in `ProcessInitializer`, because now reference
TypedValueRegions are eagerly desugared into their referee region when
forming a subregion of it.

There should be no practical differences, but there are of course bugs
that this patch may surface.

show more ...


Revision tags: llvmorg-19.1.4
# 39351f8e 07-Nov-2024 erichkeane <ekeane@nvidia.com>

[OpenACC] Implement AST/Sema for combined constructs

Combined constructs (OpenACC 3.3 section 2.11) are a short-cut for
writing a `loop` construct immediately inside of a `compute` construct.
Howeve

[OpenACC] Implement AST/Sema for combined constructs

Combined constructs (OpenACC 3.3 section 2.11) are a short-cut for
writing a `loop` construct immediately inside of a `compute` construct.
However, this interaction requires we do additional work to ensure that
we get the semantics between the two correct, as well as diagnostics.

This patch adds the semantic analysis for the constructs (but no
clauses), as well as the AST nodes.

show more ...


Revision tags: llvmorg-19.1.3
# f3e804b9 16-Oct-2024 Donát Nagy <donat.nagy@ericsson.com>

[analyzer][clang-tidy][NFC] Clean up eagerly-assume handling (#112209)

This commit is a collection of several very minor code quality
improvements. The main goal is removing the misleading "Bin" su

[analyzer][clang-tidy][NFC] Clean up eagerly-assume handling (#112209)

This commit is a collection of several very minor code quality
improvements. The main goal is removing the misleading "Bin" substring
from the names of several methods and variables (like
`evalEagerlyAssumedBinOpBifurcation`) that are also applied for the
unary logical not operator.

In addition to this, I clarified the doc-comment of the method
`evalEagerlyAssumedBinOpBifurcation` and refactored the body of this
method to fix the capitalization of variable names and replace an
obsolete use of `std::tie` with a structured binding.

Finally, the data member `eagerlyAssumeBinOpBifurcation` of the class
`AnalyzerOptions` was completely removed (including a line in clang-tidy
that sets it to true), because it was never read by any code.

Note that the eagerly-assume mode of the analyzer is controlled by a
different boolean member of `AnalyzerOptions` which is called
`ShouldEagerlyAssume` and is defined via the macro magic from
`AnalyzerOptions.def`.

show more ...


Revision tags: llvmorg-19.1.2
# 8d661fd9 04-Oct-2024 Pavel Skripkin <paskripkin@gmail.com>

[analyzer] use `invalidateRegions()` in `VisitGCCAsmStmt` (#109838)


# d412cea8 03-Oct-2024 Erich Keane <ekeane@nvidia.com>

[OpenACC] Implement 'tile' attribute AST (#110999)

The 'tile' clause shares quite a bit of the rules with 'collapse', so a
followup patch will add those tests/behaviors. This patch deals with
addi

[OpenACC] Implement 'tile' attribute AST (#110999)

The 'tile' clause shares quite a bit of the rules with 'collapse', so a
followup patch will add those tests/behaviors. This patch deals with
adding the AST node.

The 'tile' clause takes a series of integer constant expressions, or *.
The asterisk is now represented by a new OpenACCAsteriskSizeExpr node,
else this clause is very similar to others.

show more ...


Revision tags: llvmorg-19.1.1, llvmorg-19.1.0
# d84d9559 09-Sep-2024 Nicolas van Kempen <nvankemp@gmail.com>

[clang][analyzer] Fix #embed crash (#107764)

Fix #107724.


# e4bb68b8 06-Sep-2024 Arseniy Zaostrovnykh <necto.ne@gmail.com>

[analyzer] Model constructor initializer for an array member (#107537)

Bind the array member to the compound region associated with the
initializer list, e.g.:

class C {
int arr[2];

[analyzer] Model constructor initializer for an array member (#107537)

Bind the array member to the compound region associated with the
initializer list, e.g.:

class C {
int arr[2];
C() : arr{1, 2} {}
};
C c;

This change enables correct values in `c.arr[0]` and `c.arr[1]`

CPP-5647

show more ...


Revision tags: llvmorg-19.1.0-rc4
# 89fb8490 31-Aug-2024 Chris B <chris.bieneman@me.com>

[HLSL] Implement output parameter (#101083)

HLSL output parameters are denoted with the `inout` and `out` keywords
in the function declaration. When an argument to an output parameter is
construct

[HLSL] Implement output parameter (#101083)

HLSL output parameters are denoted with the `inout` and `out` keywords
in the function declaration. When an argument to an output parameter is
constructed a temporary value is constructed for the argument.

For `inout` pamameters the argument is initialized via copy-initialization
from the argument lvalue expression to the parameter type. For `out`
parameters the argument is not initialized before the call.

In both cases on return of the function the temporary value is written
back to the argument lvalue expression through an implicit assignment
binary operator with casting as required.

This change introduces a new HLSLOutArgExpr ast node which represents
the output argument behavior. The OutArgExpr has three defined children:
- An OpaqueValueExpr of the argument lvalue expression.
- An OpaqueValueExpr of the copy-initialized parameter.
- A BinaryOpExpr assigning the first with the value of the second.

Fixes #87526

---------

Co-authored-by: Damyan Pepper <damyanp@microsoft.com>
Co-authored-by: John McCall <rjmccall@gmail.com>

show more ...


# 190449a5 28-Aug-2024 Arseniy Zaostrovnykh <necto.ne@gmail.com>

[analyzer] Detect leaks of stack addresses via output params, indirect globals 3/3 (#105648)

Fix some false negatives of StackAddrEscapeChecker:
- Output parameters
```
void top(int **out) {

[analyzer] Detect leaks of stack addresses via output params, indirect globals 3/3 (#105648)

Fix some false negatives of StackAddrEscapeChecker:
- Output parameters
```
void top(int **out) {
int local = 42;
*out = &local; // Noncompliant
}
```
- Indirect global pointers
```
int **global;

void top() {
int local = 42;
*global = &local; // Noncompliant
}
```

Note that now StackAddrEscapeChecker produces a diagnostic if a function
with an output parameter is analyzed as top-level or as a callee. I took
special care to make sure the reports point to the same primary location
and, in many cases, feature the same primary message. That is the
motivation to modify Core/BugReporter.cpp and Core/ExplodedGraph.cpp

To avoid false positive reports when a global indirect pointer is
assigned a local address, invalidated, and then reset, I rely on the
fact that the invalidation symbol will be a DerivedSymbol of a
ConjuredSymbol that refers to the same memory region.

The checker still has a false negative for non-trivial escaping via a
returned value. It requires a more sophisticated traversal akin to
scanReachableSymbols, which out of the scope of this change.

CPP-4734

---------

This is the last of the 3 stacked PRs, it must not be merged before
https://github.com/llvm/llvm-project/pull/105652 and
https://github.com/llvm/llvm-project/pull/105653

show more ...


Revision tags: llvmorg-19.1.0-rc3
# 5e95571a 15-Aug-2024 Pavel Skripkin <paskripkin@gmail.com>

[analyzer] Do not reason about locations passed as inline asm input (#103714)

If pointer is passed as input operand for inline assembly, it's possible
that asm block will change memory behind this

[analyzer] Do not reason about locations passed as inline asm input (#103714)

If pointer is passed as input operand for inline assembly, it's possible
that asm block will change memory behind this pointer. So if pointer is
passed inside inline asm block, it's better to not guess and assume
memory has unknown state.

Without such change, we observed a lot of FP with hand-written `memcpy`
and friends.

show more ...


# 69c6a3fa 05-Aug-2024 Haojian Wu <hokein.wu@gmail.com>

More -Wswitch warning fixes for a42e515e3a9f3bb4e44389c097b89104d95b9b29


Revision tags: llvmorg-19.1.0-rc2, llvmorg-19.1.0-rc1, llvmorg-20-init
# 5c93a94f 19-Jul-2024 Michael Kruse <llvm-project@meinersbur.de>

[Clang][OpenMP] Add interchange directive (#93022)

Add the interchange directive which will be introduced in the upcoming
OpenMP 6.0 specification. A preview has been published in [Technical
Repor

[Clang][OpenMP] Add interchange directive (#93022)

Add the interchange directive which will be introduced in the upcoming
OpenMP 6.0 specification. A preview has been published in [Technical
Report 12](https://www.openmp.org/wp-content/uploads/openmp-TR12.pdf).

show more ...


# c661422d 18-Jul-2024 Michael Kruse <llvm-project@meinersbur.de>

[Clang] Handle OMPReverseDirectiveClass in switch


# 87c51e2a 10-Jul-2024 T-Gruber <100079402+T-Gruber@users.noreply.github.com>

Run PreStmt/PostStmt checker for GCCAsmStmt (#95409)

Fixes #94940

Run PreStmt and PostStmt checker for GCCAsmStmt.
Unittest to validate that corresponding callback functions are triggered.


12345678910>>...28