Closed Bug 1397344 Opened 7 years ago Closed 7 years ago

Use Decay to ensure StoreCopyPassByXXX stores the value by copy not by reference.

Categories

(Core :: XPCOM, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla57
Tracking Status
firefox57 --- fixed

People

(Reporter: JamesCheng, Assigned: JamesCheng)

Details

Attachments

(1 file)

Accidentally found this issue, 
just write a sample as below,

template<typename T>
struct StoreCopyPassByValue
{
  typedef T stored_type;
  typedef T passed_type;
  stored_type m;
  template <typename A>
  explicit StoreCopyPassByValue(A&& a) : m(forward<A>(a)) {}
  passed_type PassAsParameter() { return m; }
};

template<class... Arg>
void DispatchTo(Arg&&... args)
{
  NewRunnableMethod<StoreCopyPassByValue<typename std::decay<Arg>::type>...>(..., forward<Args>(args)...);
}
int main()
{
  int a = 9487;
  Test(move(a)); // OK, The Arg will be deduced to "int", so passed and stored type 
                 will be int.
  Test(a);       // Error, The Arg will be deduced to "int&", so passed and stored type 
                 will be int&. It may record a local variable by reference not 
                 value.
  return 0;
}

Should we consider to use Decay such as 

  typedef typename Decay<T>::Type stored_type;
  typedef typename Decay<T>::Type passed_type;

to ensure the stored type and passed type as our expectation?
I need to manually do the decay in above sample

ni author gerald for his feedback.
Flags: needinfo?(gsquelart)
s/Test/DispatchTo for typo
Attachment #8905419 - Flags: review?(gsquelart)
Good idea!
Flags: needinfo?(gsquelart)
Comment on attachment 8905419 [details]
Bug 1397344 - Use Decay to ensure StoreCopyPassByXXX stores the value by copy not by reference.

https://reviewboard.mozilla.org/r/177240/#review183016

Nice one, thank you.

A suggestion:

::: xpcom/threads/nsThreadUtils.h:860
(Diff revision 1)
>  
>  template<typename T>
>  struct StoreCopyPassByConstLRef
>  {
> -  typedef T stored_type;
> -  typedef const T& passed_type;
> +  typedef typename mozilla::Decay<T>::Type stored_type;
> +  typedef const typename mozilla::Decay<T>::Type& passed_type;

For all four decayed `passed_type` typedefs, I think you could just re-use `stored_type`, e.g.: `typedef stored_type& passed_type;`.

It should be a little bit more readable; and especially for the ones with references, it will emphasize that we're passing references to the stored copy (as opposed to the original argument).
Attachment #8905419 - Flags: review?(gsquelart) → review+
Thanks for your suggestion. I'll update the patch.
Pushed by jacheng@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/5b3b0c446caa
Use Decay to ensure StoreCopyPassByXXX stores the value by copy not by reference. r=gerald
https://hg.mozilla.org/mozilla-central/rev/5b3b0c446caa
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
You need to log in before you can comment on or make changes to this bug.