This is an archive of the discontinued LLVM Phabricator instance.

[PATCH] New diagnostic for non-idiomatic copy or move operations
AbandonedPublic

Authored by aaron.ballman on Dec 4 2015, 6:13 AM.

Details

Reviewers
dblaikie
rsmith
Summary

All copy operations were created equal (as far as the core language is concerned), but some copy operations are more equal than others (as far as the library is concerned). The same is true of move operations. This patch diagnoses copy and move operations (constructors and assignment operators) that are non-idiomatic so that users are not surprised when their copyable type cannot be placed in a standard library container or used with a standard library algorithm.

Idiomatic copy and move operations are (where T is the class type for the object):
Copy Constructor: takes a const T&
Move constructor: takes a T&&
Copy Assignment: takes a const T&, returns a T&, and has no ref-qualifiers
Move Assignment: takes a T&&, returns a T&, and has no ref-qualifiers

One thing this patch does not have, but I would like to add, are fix-it hints to correct the types involved. However, I cannot find a way to get the full source range for the type, including qualifiers. For a parameter of type 'const volatile T&', the TypeLoc appears to only track the location of T&, but not the qualifiers. Assistance in understanding how to do this would be appreciated.

Diff Detail

Event Timeline

aaron.ballman retitled this revision from to [PATCH] New diagnostic for non-idiomatic copy or move operations.
aaron.ballman updated this object.
aaron.ballman added reviewers: rsmith, dblaikie.
aaron.ballman added a subscriber: cfe-commits.

I should note for clarity, this is a WIP. There are still a lot of test cases that require updating due to the new diagnostic. I also wanted to get a feel for whether people felt this belongs under -Wall or not.

As I wade through a lot of diagnostics from our test suite, I notice a recurring pattern is that this is diagnosing in the presence of idiomatic constructors or assignment operators. e.g.,

struct S {
  S(const S&) = delete;
  S(S&); // We diagnose, and suggest const T& here
};

struct T {
  T(const T&) = default;
  T(T&); // We diagnose, and suggest const T& here
};

Would it make sense to delay this checking until the class definition is complete, and then diagnose only the operations where the suggestion in the diagnostic would not result in an ambiguous declaration? Or, perhaps suppress the diagnostic entirely in the presence of multiple overloads of the operation. e.g, not diagnose the following:

struct U {
  U(U&);
  U(volatile U&);

  U& operator=(U&);
  void operator=(const U&);
};
aaron.ballman abandoned this revision.Dec 11 2015, 10:05 AM

Abandoning this revision, will post a new patch approach shortly.