Open
Description
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");