ziqingluo-90 added inline comments.

================
Comment at: clang/lib/Analysis/UnsafeBufferUsage.cpp:2077
+
   for (const auto &[VD, Fixables] : FixablesForUnsafeVars.byVar) {
     FixItsForVariable[VD] =
----------------
NoQ wrote:
> There's a bug in variable naming: `FixablesForUnsafeVars`actually contains 
> fixables for *all* variables. Rashmi correctly renames it in D150489 to 
> reflect its actual behavior. So IIUC you're generating fixits for all 
> variables here, which is probably not what you want.
Thanks for pointing out the incorrectness of the variable name.   Actually, 
whether a variable is unsafe is irrelevant to this function.  The function only 
cares about all variables that need fixes.  So I think the incorrect name of 
the variable does not affect the functionality of my changes here.


================
Comment at: clang/lib/Analysis/UnsafeBufferUsage.cpp:2278-2281
+          if (isParameterOf(Impl.first, D))
+            ParmsNeedFix.insert(Impl.first);
+          if (isParameterOf(Impl.second, D))
+            ParmsNeedFix.insert(Impl.second);
----------------
NoQ wrote:
> Does this really go in both directions? Shouldn't it be just one direction?
> 
> ```lang=c++
> void foo(int *p) {
>   int *q = new int[10];
>   p = q;
>   q[5] = 7;
> }
> ```
> In this case `q` is an unsafe local buffer, but `p` is a (mostly) safe 
> single-object pointer that doesn't need fixing, despite implication from `q` 
> to `p`. Of course this example is somewhat unrealistic (people don't usually 
> overwrite their parameters), but it is also the only situation where the 
> other direction matters.
You are right!  It should be one-direction.


================
Comment at: clang/lib/Analysis/UnsafeBufferUsage.cpp:2293
+    //      search of connected components.
+    if (!ParmsNeedFix.empty()) {
+      auto First = ParmsNeedFix.begin(), Last = First;
----------------
NoQ wrote:
> What about the situation where params aren't seen as unsafe yet, but they're 
> discovered to be unsafe later? Eg.
> ```
> void foo(int *p, int *q) {
>   int *p2 = p;
>   p2[5] = 7;
>   int *q2 = q;
>   q2[5] = 7;
> }
> ```
> Will we notice that `p` and `q` need to be fixed simultaneously?
> 
> ---
> 
> I suspect that the problem of parameter grouping can't be solved by 
> pre-populating strategy implications between all parameters. It'll either 
> cause you to implicate all parameters (even the ones that will never need 
> fixing), or cause you to miss connections between parameters that do need 
> fixing (as the connection is discovered later).
> 
> Connection between parameters needs to be added *after* the implications 
> algorithm has finished. And once it's there (might be already there if I 
> missed something), then this part of code probably becomes unnecessary.
Yes.  They will be noticed.  Here is why:

The code here first forms a ring over `p` and  `q` in the assignment (directed) 
graph:  
```
p <--> q
```
Then the two initialization statements (implemented in [[ 
https://reviews.llvm.org/D150489 | D150489 ]]) add two more edges to the graph:
```
p2 --> p <--> q <-- q2
```
The algorithm later searches the graph starting from unsafe variables `p2` and 
`q2`, respectively,  Starting from `p2`, the algorithm discovers that `p2` and 
`p`, as well as `p` and `q` depend on each other.  Starting from `q2`,  the 
algorithm discovers that `q2` and `q`, as well as `p` and `q` depend on each 
other.   The dependency graph is sort of undirected. So eventually, the four 
variables `p2`, `p`, `q`, `q2` are in the same group.



================
Comment at: 
clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-multi-parm-span.cpp:13-15
+   expected-note{{change type of 'p' to 'std::span' to preserve bounds 
information, and change 'q' and 'a' to 'std::span' to propagate bounds 
information between them}} \
+   expected-note{{change type of 'q' to 'std::span' to preserve bounds 
information, and change 'p' and 'a' to 'std::span' to propagate bounds 
information between them}} \
+   expected-note{{change type of 'a' to 'std::span' to preserve bounds 
information, and change 'p' and 'q' to 'std::span' to propagate bounds 
information between them}}
----------------
NoQ wrote:
> QoL thing: //"to propagate bounds information between them"// isn't the 
> correct reason in this case. Bounds information doesn't propagate between `p` 
> and `q` and `a`. Each of them carries its own, completely unrelated bounds 
> information.
> 
> We need to come up with a different reason. Or it might be better to combine 
> the warnings into one warning here, so that we didn't need a reason:
> ```
> warning: 'p', 'q' and 'a' are unsafe pointers used for buffer access
> note: change type of 'p', 'q' and 'a' to 'std::span' to preserve bounds 
> information
> ```
> 
> This gets a bit worse when parameters are implicated indirectly, but it still 
> mostly works fine, for example:
> ```
> void foo(int *p, int *q) {
>   int *p2 = p;
>   p2[5] = 7;
>   int *q2 = q;
>   q2[5] = 7;
> }
> ```
> would produce:
> ```
> warning: 'p2' and 'q2' are unsafe pointers used for buffer access
> note: change type of 'p2' and 'q2' to 'std::span' to preserve bounds 
> information, and
>       change 'p' and 'q' to 'std::span' to propagate bounds information 
> between them
> ```
> 
> ---
> 
> In any case, this shows that the relationship between parameters (grouped 
> together simply for being parameters) is very different from the relationship 
> within groups of variables implicated by assignments (even if two or more of 
> them are parameters). All the way down to the warning/note printer, we 
> probably need to continue giving the parameter relationship a special 
> treatment.
This is a good argument!  An edge from `p` to `q` in an assignment graph stands 
for not only that fixing `p` implicates fixing `q` but also that the bounds 
information is propagated from `q` to `p`.   In this sense, the way I connect 
parameters is inappropriate.

But my concern is that although treating parameters specially could improve the 
quality of the diagnostic messages, the code may be more complex and less 
re-used.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D153059

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

Reply via email to