[all-commits] [llvm/llvm-project] 7e5821: Reapply "[analyzer] Handle [[assume(cond)]] as __b...

Balazs Benics via All-commits all-commits at lists.llvm.org
Wed Mar 5 23:09:32 PST 2025


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 7e5821bae80db3f3f0fe0d5f8ce62f79e548eed5
      https://github.com/llvm/llvm-project/commit/7e5821bae80db3f3f0fe0d5f8ce62f79e548eed5
  Author: Balazs Benics <benicsbalazs at gmail.com>
  Date:   2025-03-06 (Thu, 06 Mar 2025)

  Changed paths:
    M clang/include/clang/AST/AttrIterator.h
    M clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    M clang/lib/Analysis/CFG.cpp
    M clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
    M clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
    M clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    A clang/test/Analysis/cxx23-assume-attribute.cpp
    M clang/test/Analysis/out-of-bounds-new.cpp

  Log Message:
  -----------
  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>



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list