kinu added a comment.

Thanks!  Updated the patch.



================
Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:650
+      assert(FieldsForInit.size() + R->getNumBases() == Inits.size());
+      for ([[maybe_unused]] const CXXBaseSpecifier &Base : R->bases()) {
+        assert(InitIdx < Inits.size());
----------------
mboehme wrote:
> This `[[maybe_unused]]` seems unnecesary, as `Base` is definitely used in the 
> `isLambda()` check?
I removed the isLambda check below from this patch, let me keep this line for 
now


================
Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:655
+               GetCanonicalType(Init->getType()));
+        if (Base.getType()->getAsCXXRecordDecl()->isLambda()) {
+          // FIXME: Figure out what to do for lambdas.
----------------
mboehme wrote:
> - Can this actually happen? (How do you make a lambda a base class?)
> - Why does this need to be handled separately? (Isn't a lambda just a normal 
> class, modulo sugar? What is different about lambdas that means we can't 
> handle them like other classes?)
> 
> Depending on the answers to the above, would also be useful to capture them 
> as comments in the source code.
> 
> I assume you encountered this scenario somewhere. Can you add a test (with 
> incorrect behavior marked as a FIXME) that exercises this?
I hit this case in one of real code so added this afterwards...

but actually can I drop this part from this patch but come back in a separate 
patch once I clarify the behavior?  I somehow lost the note about in which file 
this happened, and I need to confirm a few things before I can add a test :(


================
Comment at: clang/lib/Analysis/FlowSensitive/Transfer.cpp:683-686
+      // `ModeledFields` also contains from all the bases, but only the modeled
+      // ones. Having an initializer list for a struct basically populates all
+      // the fields for the struct, so the fields set that is populated here
+      // should match the modeled fields without additional filtering.
----------------
mboehme wrote:
> Rewrote this a bit with the aim of making it clearer -- WDYT?
Much better, applied!


================
Comment at: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp:2191
+TEST(TransferTest, AssignmentOperatorWithInitAndInheritance) {
+  // This is a crash repro.
+  std::string Code = R"(
----------------
mboehme wrote:
> IIUC, the crash was happening because `copyRecord()` assumes that the source 
> and destination have the same fields. More specifically, there was an 
> unspoken invariant in the framework that a `RecordStorageLocation` should 
> always contain exactly the fields returned by 
> `DataflowAnalysisContext::getModeledFields()`), but our treatment of 
> `InitListExpr` was violating this invariant.
> 
> IOW, this wasn't really an issue with the way we treat copy/move operations 
> but with `InitlistExpr`.
> 
> I understand that we want to have a test the reproduces the exact 
> circumstances that led to the crash, but maybe it's enough to have one of 
> these, and have the focus of the testing be on testing the actual invariant 
> that we want to maintain? IOW, maybe keep this test but delete the additional 
> tests below?
Dropped the additional tests below.


================
Comment at: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp:2208-2220
+        const ValueDecl *S1Decl = findValueDecl(ASTCtx, "S1");
+        const ValueDecl *S2Decl = findValueDecl(ASTCtx, "S2");
+        const ValueDecl *S3Decl = findValueDecl(ASTCtx, "S3");
+        const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
+
+        const Environment &Env =
+              getEnvironmentAtAnnotation(Results, "p");
----------------
mboehme wrote:
> 
(Now this part is removed)


================
Comment at: clang/unittests/Analysis/FlowSensitive/TransferTest.cpp:2498
+TEST(TransferTest, ReturnStructWithInheritance) {
+  // This is a crash repro. (Returning a struct involves copy/move constructor)
+  std::string Code = R"(
----------------
mboehme wrote:
> I don't think this is true -- the `return S1` in `target()` will use NRVO.
> 
> But I also don't think it's relevant -- I believe the crash this is 
> reproducing was triggered by the `InitListExpr`, not the return statement?
> 
> Given the other tests added in this patch, do we need this test?
It will use NRVO but in AST this still seems to generate CXXConstructExpr with 
isCopyOrMoveConstructor() == true because omitting the ctor is not mandatory in 
compilers.

I can drop this one, but I'm also a bit torn because this was the original 
crash repro that puzzled me a bit.

I refined the comment to explain it a bit better; how does it look now?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159284/new/

https://reviews.llvm.org/D159284

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

Reply via email to