JonasToth added inline comments.
================ Comment at: unittests/Analysis/ExprMutationAnalyzerTest.cpp:67 + if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { + if (DRE->getNameInfo().getAsString()[0] == 'p') + Finder = PointeeMutationFinder; ---------------- shuaiwang wrote: > JonasToth wrote: > > shuaiwang wrote: > > > JonasToth wrote: > > > > That doesn't look like a super idea. It is super hidden that variable > > > > 'p*' will be analyzed for pointee mutation and others aren't. > > > > Especially in 12 months and when someone else wants to change > > > > something, this will be the source of headaches. > > > > > > > > Don't you think there could be a better way of doing this switch? > > > Yeah... agree :) > > > But how about let's keep it this way just for now, and I'll pause the > > > work on supporting pointee analysis and fix it properly but in a separate > > > diff following this one? > > > > > > I've been thinking about this and also did some prototyping, and here are > > > my thoughts: > > > In order to properly fix this we need to change the interface of > > > `ExprMutationAnalyzer` to not simply return a `Stmt` but instead return a > > > `MutationTrace` with additional metadata. This wasn't needed before > > > because we can reconstruct a mutation chain by continuously calling > > > `findMutation`, and that works well for cases like "int x; int& r0 = x; > > > int& r1 = r0; r1 = 123;". But now that pointers come into play, and we > > > need to handle cases like "int *p; int *p2 = p; int& r = *p2; r = 123;", > > > and in order to reconstruct the mutation chain, we need to do > > > `findPointeeMutation(p)` -> `findPointeeMutation(p2)` -> > > > `findMutation(r)`, notice that we need to switch from calling > > > `findPointeeMutation` to calling `findMutation`. However we don't know > > > where the switch should happen simply based on what's returned from > > > `findPointeeMutation`, we need additional metadata for that. > > > > > > That interface change will unavoidably affect how memoization is done so > > > we need to change memoization as well. > > > > > > Now since we need to change both the interface and memoization anyway, we > > > might as well design them properly so that multiple-layers of pointers > > > can be supported nicely. I think we can end up with something like this: > > > ``` > > > class ExprMutationAnalyzer { > > > public: > > > struct MutationTrace { > > > const Stmt *Value; > > > const MutationTrace *Next; > > > // Other metadata > > > }; > > > > > > // Finds whether any mutative operations are performed on the given > > > expression after dereferencing `DerefLayers` times. > > > const MutationTrace *findMutation(const Expr *, int DerefLayers = 0); > > > const MutationTrace *findMutation(const Decl *, int DerefLayers = 0); > > > }; > > > ``` > > > This involves quite some refactoring, and doing this refactoring before > > > this diff and later rebasing seems quite some trouble that I'd like to > > > avoid. > > > > > > Let me know what do you think :) > > Is the second part of your answer part to adressing this testing issue? > > Given the whole Analyzer is WIP it is ok to postpone the testing change to > > later for me. But I feel that this is a quality issue that more experience > > clang develops should comment on because it still lands in trunk. Are you > > aware of other patches then clang-tidy that rely on EMA? > > > > Regarding you second part (its related to multi-layer pointer mutation?!): > > Having a dependency-graph that follows the general data flow _with_ > > mutation annotations would be nice to have. There is probably even > > something in clang (e.g. `CFG` is probably similar in idea, just with all > > execution paths), but I don't know enough to properly judge here. > > > > In my opinion it is ok, to not do the refactoring now and just support one > > layer of pointer indirection. Especially in C++ there is usually no need > > for multi-layer pointers but more a relict from C-style. > > C on the other hand relies on that. > > Designing EMA new for the more generalized functionality (if necessary) > > would be of course great, but again: Better analyzer ppl should be involved > > then me, even though I would still be very interested to help :) > The second part is more of trying to explain why I'd prefer to keep the test > this way just for this diff. > Basically we need a refactoring that makes EMA returns MutationTrace in order > to fix this test util here. > > But thinking more about this, maybe we don't need that (for now), this util > is to help restore a mutation chain, and since we don't support a chain of > mutation for pointers yet we can have a simpler version of `pointeeMutatedBy` > that doesn't support chaining. > > I mentioned multi-layer pointer mutation because _if_ we were to do a > refactoring, we'd better just do it right and take possible features needed > in the future into account. But the refactoring itself is motivated by the > need of fixing this testing util (and making the return value from > `findMutation` generally more useful.) > > BTW by `MutationTrace` it's not as complicated or sophisticated as `CFG`, > it's simply a trace helping understand why the mutation happens, for example > in this case: > ``` > int x; > int &y = x; > int &z = y; > z = 123; > ``` > it's a bit disconnected if we just say `z = 123` mutated > `declRefExpr(to(x))`, instead: > - `findMutation(x)` returns `y` > - `findMutation(y)` returns `z` > - `findMutation(z)` returns `z = 123` > This doesn't apply to (majority) of cases where the mutative expression is an > ancestor of the given expression, in those cases it's typically quite clear > why the ancestor expression mutated its descendant. > > Anyway, I'll remove this little hackery here and address other comments later > (hopefully today), and I'll do a refactoring before pointer analysis supports > chaining. Ok, understanding the decision making of the EMA would be a good thing to have in general as well. Repository: rC Clang https://reviews.llvm.org/D52219 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits