<div dir="ltr"><div>Hi list,<br></div><div><br></div><div>I have the following code to analyze:</div><div><br></div><div>struct BoolConvertibleStruct {<br>    int n;<br>    BoolConvertibleStruct(int m) : n(m) {}<br>    operator bool() const { return n != 0; }<br>};<br><br>BoolConvertibleStruct StructFunc() {<br>    return 1;<br>}</div><div><br></div><div>I have reduced my problem to wanting to analyze StructFunc() to figure out the truth value of its return value. (The actual problem is more complicated and you might recognize that BoolConvertibleStruct is a stand-in for std::unique_ptr<T>, among other things :-P)</div><div><br></div><div>I have the following sample checker:<br></div><div><br></div><div>class Analyzer : public Checker<check::EndFunction> {<br> public:<br>    void checkEndFunction(const ReturnStmt* ret, CheckerContext& cx) const {<br>        const auto* func = cast<FunctionDecl>(cx.getStackFrame()->getDecl());<br>        if (func->getQualifiedNameAsString() != "StructFunc")<br>            return;<br><br>        ProgramStateRef state = cx.getState();<br>        SValBuilder& builder = cx.getSValBuilder();<br>        ASTContext& ast = cx.getASTContext();<br><br>        SVal returnValue = cx.getSVal(ret->getRetValue());<br>        SVal falseValue = builder.makeZeroVal(ast.BoolTy);<br>        SVal returnedFalse = builder.evalEQ(state, returnValue, falseValue);<br><br>        errs() << "Evaluating (" << returnValue << " == " << falseValue<br>            << ") -> " << returnedFalse << "\n";<br>    }<br>};</div><div><br></div><div>However when I run it on my sample code I get this output:</div><div><br></div><div>Evaluating (lazyCompoundVal{0x7f98f1871c70,Element{SymRegion{conj_$0{struct BoolConvertibleStruct *, LC1, S973, #1}},0 S64b,struct BoolConvertibleStruct}} == 0 U1b) -> Unknown</div><div><br></div><div>It seems to me that the result should be able to be easily modeled, but I'm not sure how to go about it. (I don't even see the "1" stored in the field showing up in the LazyCompoundVal.) Looking at the source code, it looks like I will have to somehow transform the LazyCompoundVal to something else because evalBinOp will always return Unknown if either side is a LazyCompoundVal. I have tried these things so far:<br></div><div><br></div><div>- Getting the CXXConversionDecl for BoolConvertibleStruct::operator bool() and creating a CXXMemberCallExpr, then calling cx.getSVal() on that; the result is Unknown</div><div>- Getting the FieldDecl for BoolConvertibleStruct::n and calling state->getLValue(field, returnValue); the resulting SVal crashes when I try to print it</div><div>- Using builder.evalCast() to cast returnValue to ast.BoolTy; the result of the cast is also Unknown<br></div><div>- Using state->isNull() to query the truth value directly; the result is underconstrained</div><div><br></div><div>Some suggestion about what to try next (or even "this definitely won't work") would be appreciated.<br></div><div><br></div><div>Regards,<br></div><div>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">Philip</div></div></div>