Issue 139647
Summary [Clang] Static analyzer (with assertions) crashes when dealing with `std::call_once`
Labels clang:static analyzer
Assignees
Reporter ziqingluo-90
    A minimal example (https://godbolt.org/z/o99n7db3e):
```
#include <mutex>

class T {
 public: 
    T () {}
};

bool check() {
  static std::once_flag flag;
 auto fun = [](T S)->void{};
  std::call_once(flag, fun, T());

}
```

I think the issue is in fact in BodyFarm instead of CSA, so please help me to CC more appropriate community members and add proper tags if possible.

CSA uses `BodyFarm` to create the definition of `std::call_once`.  
```
/// Create a fake body for std::call_once.
/// Emulates the following function body:
///
/// \code
/// typedef struct once_flag_s {
///   unsigned long __state = 0;
/// } once_flag;
/// template<class Callable>
/// void call_once(once_flag& o, Callable func) {
///   if (!o.__state) {
/// func();
///   }
///   o.__state = 1;
/// }
/// \endcode
```

When `BodyFarm` crafts the definition, it needs to create an lvalue-to-rvalue conversion on the parameter of type C++ class `T`.
```
   Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
    if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
 QualType PTy = PDecl->getType().getNonReferenceType();
      ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
    }
```
However,  in `ImplicitCastExpr::Create`:
```
  // Per C++ [conv.lval]p3, lvalue-to-rvalue conversions on class and
  // std::nullptr_t have special semantics not captured by CK_LValueToRValue.
  assert((Kind != CK_LValueToRValue ||
          !(T->isNullPtrType() || T->getAsCXXRecordDecl())) &&
         "invalid type for lvalue-to-rvalue conversion");
```

_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to