Bug 385750 - Annotation for write occurrence: does not work with arrays
Summary: Annotation for write occurrence: does not work with arrays
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-editor (show other bugs)
Version: 8.0   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
: 509382 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-07-23 10:48 EDT by Axel Mueller CLA
Modified: 2020-09-04 15:23 EDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Axel Mueller CLA 2012-07-23 10:48:43 EDT
Build Identifier: Juno, CDT 8.1

In the following code the editor does not correctly mark the write occurrences for the variables array and array2. 

int main( int argc, char **argv )
{
  int * array = new int[512];
  int array2[100];
  for (int i = 0; i < 512; ++i)
  {
    array[i] = i; // not marked as write occurrence
    array2[i] = i;// not marked as write occurrence
  }

  delete [] array;
}



Reproducible: Always
Comment 1 Axel Mueller CLA 2013-05-03 20:03:59 EDT
Patch pushed to Gerrit https://git.eclipse.org/r/#/c/12515/

This will handle the cases marked with NEW
int main( int argc, char **argv )
{
  int * array = new int[512];  // write occurrence
  *array=5; // NEW: write occurrence
  &array2=3;  // NEW: write occurrence
  int array2[100];
  for (int i = 0; i < 512; ++i)
  {
    array[i] = i; // NEW: write occurrence
    array2[i] = i;// NEW: write occurrence
  }

  delete [] array;
}
Comment 2 Sergey Prigogin CLA 2013-05-29 17:10:39 EDT
The clause "the value the variable points to is changed" needs clarification.

Here are few examples that are not clear:

What if the variable is a pointer to struct and one of the struct members is changed?

Can the rule be applied recursively, like in ****a = 0;

You can probably think of other non-obvious examples.
Comment 3 Axel Mueller CLA 2013-05-29 17:26:19 EDT
(In reply to comment #2)
> The clause "the value the variable points to is changed" needs clarification.
> 
> Here are few examples that are not clear:
> 
> What if the variable is a pointer to struct and one of the struct members is
> changed?
> 
> Can the rule be applied recursively, like in ****a = 0;
> 
> You can probably think of other non-obvious examples.
I thought the examples listed in CPPMarkOccurrences would clarify this.

 struct A { 
    void m();
    int x; 
  };
  
 void test(A* ap) {
   ap->x = 1;  // write access for ap
   ap->m();    // write access for ap	
   (*ap).m();  // write access for ap
 
   int * ip;
   *ip = 1;   // write access for ip
   ip[1] = 1; // write access for ip
   int b = ip[0];  // read access for ip
    
   int ipp[5][5];
   ipp[1][2] = 1; // write access for ipp
   **ipp = 1;     // write access for ipp


You can define two sloppy rules:
1) replacing "." with "->" does not change read/write flags
2) indirection operator "*" and array subscripting "[]" do not change read/write flags
Comment 4 Sergey Prigogin CLA 2013-05-29 17:38:29 EDT
(In reply to comment #3)

Do you agree that the rules in comment #3 lead to the following?

struct A { int i; };
struct B { A* const a; };
const B* const b;

b->a->p = 0; // Write access to both, 'b' and 'a'!
Comment 5 Sergey Prigogin CLA 2013-05-29 17:39:39 EDT
(In reply to comment #4)

Sorry, I meant b->a->i = 0
Comment 6 Axel Mueller CLA 2013-05-29 18:18:50 EDT
I would agree. 
But this example is in principle identical to:

struct C { int i; };
struct D { C const a; };
const D d;
d.a.i = 0;

The editor shows write occurrence for 'd' and 'a' (and 'i' of course).
(I know that my example would not compile. But that is not the point here.)

In your example b and a are both const with respect to the pointer. Therefore, there is from the semantics point of view only read access possible. 
But try a different look. This is what you see in the debuggers Variable View when you completely expand b:
->b       const B * const  0x602010
  ->a     A * const        0x602030
     i    int              0

Then you will see that the write access flag is for the whole tree. If a member of the tree is changed all members above are marked as write occurrence.
Comment 7 Sergey Prigogin CLA 2013-05-29 18:33:48 EDT
(In reply to comment #6)
> In your example b and a are both const with respect to the pointer.
> Therefore, there is from the semantics point of view only read access
> possible. 

Exactly. Showing write access for const variables would look silly.

> But try a different look. This is what you see in the debuggers Variable
> View when you completely expand b:
> ->b       const B * const  0x602010
>   ->a     A * const        0x602030
>      i    int              0
> 
> Then you will see that the write access flag is for the whole tree.

This may be a limitation of CDT debugging framework or GDB. Neither 0x602010, nor 0x602030 change as a result of the assignment, don't they?
Comment 8 Axel Mueller CLA 2013-05-29 18:58:31 EDT
(In reply to comment #7)
> (In reply to comment #6)
> > In your example b and a are both const with respect to the pointer.
> > Therefore, there is from the semantics point of view only read access
> > possible. 
> 
> Exactly. Showing write access for const variables would look silly.
Depends how we define write access :)

> 
> > But try a different look. This is what you see in the debuggers Variable
> > View when you completely expand b:
> > ->b       const B * const  0x602010
> >   ->a     A * const        0x602030
> >      i    int              0
> > 
> > Then you will see that the write access flag is for the whole tree.
> 
> This may be a limitation of CDT debugging framework or GDB. Neither
> 0x602010, nor 0x602030 change as a result of the assignment, don't they?
There is a misunderstanding. Both addresses do not change. Only 'i' is marked as changed in the Variable View when you step through the code. I thought the picture of a tree would clarify my intentions.

But perhaps we should go back to my initial comment.
> int array2[100];
> array2[i] = i;// not marked as write occurrence
I am mainly interested in this part ([] and * operator). This would be very helpful for my daily work where I want to see where is actual write access to my data.
I stumbled about the −> operator when I extended the test cases in VariableReadWriteFlagsTest. If you are not happy about this part I can remove it from the patch.
Comment 9 Sergey Prigogin CLA 2013-05-29 19:08:15 EDT
(In reply to comment #8)
> But perhaps we should go back to my initial comment.
> > int array2[100];
> > array2[i] = i;// not marked as write occurrence
> I am mainly interested in this part ([] and * operator). This would be very
> helpful for my daily work where I want to see where is actual write access
> to my data.

I agree that it would be helpful.

> I stumbled about the −> operator when I extended the test cases in
> VariableReadWriteFlagsTest. If you are not happy about this part I can
> remove it from the patch.

The challenge is to come up with a set of rules for what is considered write access and what is not, so that these rules would not lead to silly results like write access for const variables.
Comment 10 Axel Mueller CLA 2013-05-29 19:17:53 EDT
(In reply to comment #9)
> (In reply to comment #8)
> > But perhaps we should go back to my initial comment.
> > > int array2[100];
> > > array2[i] = i;// not marked as write occurrence
> > I am mainly interested in this part ([] and * operator). This would be very
> > helpful for my daily work where I want to see where is actual write access
> > to my data.
> 
> I agree that it would be helpful.
> 
> > I stumbled about the −> operator when I extended the test cases in
> > VariableReadWriteFlagsTest. If you are not happy about this part I can
> > remove it from the patch.
> 
> The challenge is to come up with a set of rules for what is considered write
> access and what is not, so that these rules would not lead to silly results
> like write access for const variables.
But even if we limit the patch to [] and * operator we still could get write access for const variables.

int * const x = new int();
*x = 1;

I think the main problem here is that for pointers we actually need two markers (as we can set the const attribute differently) but we only have one in the editor (and two different markers would be very confusing).
Comment 11 Axel Mueller CLA 2013-06-03 16:13:00 EDT
The current implementation of Mark Occurrences in the editor shows read/write access to a *variable*. But what very often we want to see the read/write access to an *object*. In case of non-pointer type variables this is identical. However, for pointer type variables we ignore the read/write access to the underlying object and expose only the read/write access to the pointer itself. A good coding style is to declare the pointer parameter of a function as const where only the object it points to can be changed. 

void foo(A * const bar) {
	bar->x = 1; // marked as *read* access for bar
}

In this case Mark Occurrences will exhibit only read accesses. Rendering this feature rather pointless [sic].
However, if I use instead a reference as function parameter I get the much different result
void foo(A & bar) {
	bar.x = 1;  // marked as *write* access for bar
}
Both function codes are identical but Mark Occurrences gives me different results!

I think we have now the following options:

1) just leave Mark Occurrences as it is and close this bug as WONTFIX 
=> obviously not my preferred option :-)

2) rewrite my patch as suggested in comment #8 and have exceptions for [] and * operator
=> we would introduce then an inconsistency which would be difficult to comprehend for the user (see example code above)

3) take my patch as is
=> we would confuse the user why a const variable can have write access (see comment #4 and #10 )

4) take my patch as is but introduce a preference option for Mark Occurrences where you decide if you want to see read/write access to variables or to objects
=> Where should we place this preference? How difficult would it be to switch between the two options (i.e. how many mouse clicks would it take)? How would you distinguish the results? How would a user know about this preference key? Aren't there enough options in CDT to choose from?

5) take my patch as is and add some modifications to introduce a new marker which will display read/write access to objects. This marker will be shown in addition to the existing marker for variables
=> don't we have enough markers already that fill the editor's sidebar?

6) take my patch as is and add some modifications to change the marker text from 
"Write occurrence of 'bar'"
to
"Read occurrence of variable 'bar', write occurence of object '*bar'"


I would prefer option 6)
Comment 12 Sergey Prigogin CLA 2013-06-03 16:35:11 EDT
(In reply to comment #11)

Option 6 is the best in my opinion.
Comment 13 Nathan Ridge CLA 2015-03-05 02:04:22 EST
What's the status of this? 

Alex, do you have plans to implement option (6)?
Comment 14 Axel Mueller CLA 2015-03-11 10:17:48 EDT
(In reply to Nathan Ridge from comment #13)
> What's the status of this? 
> 
> Alex, do you have plans to implement option (6)?
I had started working on this in 2013. Unfortunately, it got a little more complicated than expected and then I run out of time. Sorry, but I don't think that I will have enough time to continue my work in the near future.
Comment 15 Nathan Ridge CLA 2016-12-17 14:52:25 EST
*** Bug 509382 has been marked as a duplicate of this bug. ***