================ @@ -985,6 +985,20 @@ auto buildTransferMatchSwitch() { isOptionalMemberCallWithNameMatcher(hasName("isNull")), transferOptionalIsNullCall) + // NullableValue::makeValue, NullableValue::makeValueInplace + // Only NullableValue has these methods, but this + // will also pass for other types + .CaseOfCFGStmt<CXXMemberCallExpr>( + isOptionalMemberCallWithNameMatcher( + hasAnyName("makeValue", "makeValueInplace")), + [](const CXXMemberCallExpr *E, const MatchFinder::MatchResult &, + LatticeTransferState &State) { + if (RecordStorageLocation *Loc = + getImplicitObjectLocation(*E, State.Env)) { + setHasValue(*Loc, State.Env.getBoolLiteralValue(true), State.Env); + } + }) + ---------------- vbvictor wrote:
I'd prefer 2nd option because we have more control over what method belong to what class. Imagine this situation: ```cpp struct optional1() { hasNull(); // check that it has value but it's nullptr isNull(); // check that it has no value inside } struct optional2() { hasNull(); // check that it has no value inside } ``` If we go with 1st option, we would write `NonStdNoValue: hasNull;isNull`, but that would produce errors because `optional1::hasNull` doesn't actually check for no value, `optional1::isNull` does. To express intentional behavior, we need to write `NonStdNoValue: optional2::hasNull;optional1::isNull`. I don't think we need to worry too much about the length of the default value. https://github.com/llvm/llvm-project/pull/144313 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits