Balazs Benics 7e5821bae8
Reapply "[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond)" (#129234)
This is the second attempt to bring initial support for [[assume()]] in
the Clang Static Analyzer.
The first attempt (#116462) was reverted in
2b9abf0db2d106c7208b4372e662ef5df869e6f1 due to some weird failure in a
libcxx test involving `#pragma clang loop vectorize(enable)
interleave(enable)`.

The failure could be reduced into:
```c++
template <class ExecutionPolicy>
void transform(ExecutionPolicy) {
  #pragma clang loop vectorize(enable) interleave(enable)
  for (int i = 0; 0;) { // The DeclStmt of "i" would be added twice in the ThreadSafety analysis.
    // empty
  }
}
void entrypoint() {
  transform(1);
}
```

As it turns out, the problem with the initial patch was this:
```c++
for (const auto *Attr : AS->getAttrs()) {
  if (const auto *AssumeAttr = dyn_cast<CXXAssumeAttr>(Attr)) {
    Expr *AssumeExpr = AssumeAttr->getAssumption();
    if (!AssumeExpr->HasSideEffects(Ctx)) {
      childrenBuf.push_back(AssumeExpr);
    }
  }
  // Visit the actual children AST nodes.
  // For CXXAssumeAttrs, this is always a NullStmt.
  llvm::append_range(childrenBuf, AS->children()); // <--- This was not meant to be part of the "for" loop.
  children = childrenBuf;
}
return;
 ```

The solution was simple. Just hoist it from the loop.

I also had a closer look at `CFGBuilder::VisitAttributedStmt`, where I also spotted another bug.
We would have added the CFG blocks twice if the AttributedStmt would have both the `[[fallthrough]]` and the `[[assume()]]` attributes. With my fix, it will only once add the blocks. Added a regression test for this.

Co-authored-by: Vinay Deshmukh <vinay_deshmukh AT outlook DOT com>
2025-03-06 08:09:09 +01:00
..

C language Family Front-end

Welcome to Clang.

This is a compiler front-end for the C family of languages (C, C++ and Objective-C) which is built as part of the LLVM compiler infrastructure project.

Unlike many other compiler frontends, Clang is useful for a number of things beyond just compiling code: we intend for Clang to be host to a number of different source-level tools. One example of this is the Clang Static Analyzer.

If you're interested in more (including how to build Clang) it is best to read the relevant websites. Here are some pointers: