haoNoQ wrote:
> (As usual, `BinaryConditionalOperator` comes to mind as the example of an
> expression that loads its sub-expressions multiple times. Let me see if I can
> break it.)
Yeah, for completeness, I guess it may theoretically be a problem in a test
such as this one, in the context of `TypeErasedDataflowAnalysisTest.cpp` where
there's this little `is_null` analysis:
```
TEST_F(TopTest, CastNeedsAValue) {
std::string Code = R"(
struct Base {};
struct Derived: Base {};
__attribute__((noreturn)) Derived *fail();
Base *unknown();
void target() {
Derived *DPtr = static_cast<Derived *>(unknown()) ?: fail();
// [[p]]
}
)";
runDataflow(
Code,
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
const AnalysisOutputs &AO) {
AO.ACFG.getCFG().dump(AO.ASTCtx.getLangOpts(), true);
ASSERT_THAT(Results.keys(), UnorderedElementsAre("p"));
const Environment &Env = getEnvironmentAtAnnotation(Results, "p");
Env.dump();
const ValueDecl *DPtrDecl = findValueDecl(AO.ASTCtx, "DPtr");
ASSERT_THAT(DPtrDecl, NotNull());
EXPECT_EQ(Env.getValue(*DPtrDecl)->getProperty("is_null"),
&Env.getBoolLiteralValue(false));
});
}
```
- where we wouldn't notice that `DPtr2` is non-null unless we eagerly assign a
value to the static cast expression, because we'll be looking up the value of
the operator `?:` from the next CFG block, which would be unconditionally equal
to the condition value, which we've already forgot.
But all of this *would* only be a problem if we model the GNU binary form of
operator `?:` in the first place. And it's not like we even model null checks.
And even then, that's completely ridiculous code.
So, yeah, IIUC I can just skip the value. I'll get back to this tomorrow.
https://github.com/llvm/llvm-project/pull/179060
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits