There's been several requests for warnings with std::move. I was planning a creating a new warning group for all of them once a few more get implemented.
On Mon, Jan 12, 2015 at 1:52 PM, Jordan Rose <[email protected]> wrote: > Out of curiosity, why is this a separate warning group and not just part > of -Wself-assign? Or at least a subgroup? > > Jordan > > > On Jan 9, 2015, at 22:04, Richard Trieu <[email protected]> wrote: > > > > Author: rtrieu > > Date: Sat Jan 10 00:04:18 2015 > > New Revision: 225581 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=225581&view=rev > > Log: > > Add a new warning, -Wself-move, to Clang. > > > > -Wself-move is similiar to -Wself-assign. This warning is triggered when > > a value is attempted to be moved to itself. See r221008 for a bug that > > would have been caught with this warning. > > > > > > Added: > > cfe/trunk/test/SemaCXX/warn-self-move.cpp > > Modified: > > cfe/trunk/include/clang/Basic/DiagnosticGroups.td > > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > cfe/trunk/lib/Sema/SemaExpr.cpp > > > > Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=225581&r1=225580&r2=225581&view=diff > > > ============================================================================== > > --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original) > > +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Sat Jan 10 > 00:04:18 2015 > > @@ -294,6 +294,7 @@ def BindToTemporaryCopy : DiagGroup<"bin > > [CXX98CompatBindToTemporaryCopy]>; > > def SelfAssignmentField : DiagGroup<"self-assign-field">; > > def SelfAssignment : DiagGroup<"self-assign", [SelfAssignmentField]>; > > +def SelfMove : DiagGroup<"self-move">; > > def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; > > def Sentinel : DiagGroup<"sentinel">; > > def MissingMethodReturnType : DiagGroup<"missing-method-return-type">; > > @@ -586,6 +587,7 @@ def Most : DiagGroup<"most", [ > > Reorder, > > ReturnType, > > SelfAssignment, > > + SelfMove, > > SizeofArrayArgument, > > SizeofArrayDecay, > > StringPlusInt, > > > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=225581&r1=225580&r2=225581&view=diff > > > ============================================================================== > > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat Jan 10 > 00:04:18 2015 > > @@ -4701,6 +4701,9 @@ def warn_addition_in_bitshift : Warning< > > def warn_self_assignment : Warning< > > "explicitly assigning value of variable of type %0 to itself">, > > InGroup<SelfAssignment>, DefaultIgnore; > > +def warn_self_move : Warning< > > + "explicitly moving variable of type %0 to itself">, > > + InGroup<SelfMove>, DefaultIgnore; > > > > def warn_string_plus_int : Warning< > > "adding %0 to a string does not append to the string">, > > > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=225581&r1=225580&r2=225581&view=diff > > > ============================================================================== > > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jan 10 00:04:18 2015 > > @@ -9380,6 +9380,90 @@ static inline UnaryOperatorKind ConvertT > > return Opc; > > } > > > > +/// DiagnoseSelfMove - Emits a warning if a value is moved to itself. > > +static void DiagnoseSelfMove(Sema &S, const Expr *LHSExpr, const Expr > *RHSExpr, > > + SourceLocation OpLoc) { > > + if (!S.ActiveTemplateInstantiations.empty()) > > + return; > > + > > + // Strip parens and casts away. > > + LHSExpr = LHSExpr->IgnoreParenImpCasts(); > > + RHSExpr = RHSExpr->IgnoreParenImpCasts(); > > + > > + // Check for a call expression > > + const CallExpr *CE = dyn_cast<CallExpr>(RHSExpr); > > + if (!CE || CE->getNumArgs() != 1) > > + return; > > + > > + // Check for a call to std::move > > + const FunctionDecl *FD = CE->getDirectCallee(); > > + if (!FD || !FD->isInStdNamespace() || !FD->getIdentifier() || > > + !FD->getIdentifier()->isStr("move")) > > + return; > > + > > + // Get argument from std::move > > + RHSExpr = CE->getArg(0); > > + > > + const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr); > > + const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr); > > + > > + // Two DeclRefExpr's, check that the decls are the same. > > + if (LHSDeclRef && RHSDeclRef) { > > + if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) > > + return; > > + if (LHSDeclRef->getDecl()->getCanonicalDecl() != > > + RHSDeclRef->getDecl()->getCanonicalDecl()) > > + return; > > + > > + S.Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() > > + << LHSExpr->getSourceRange() > > + << RHSExpr->getSourceRange(); > > + return; > > + } > > + > > + // Member variables require a different approach to check for self > moves. > > + // MemberExpr's are the same if every nested MemberExpr refers to the > same > > + // Decl and that the base Expr's are DeclRefExpr's with the same Decl > or > > + // the base Expr's are CXXThisExpr's. > > + const Expr *LHSBase = LHSExpr; > > + const Expr *RHSBase = RHSExpr; > > + const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr); > > + const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr); > > + if (!LHSME || !RHSME) > > + return; > > + > > + while (LHSME && RHSME) { > > + if (LHSME->getMemberDecl()->getCanonicalDecl() != > > + RHSME->getMemberDecl()->getCanonicalDecl()) > > + return; > > + > > + LHSBase = LHSME->getBase(); > > + RHSBase = RHSME->getBase(); > > + LHSME = dyn_cast<MemberExpr>(LHSBase); > > + RHSME = dyn_cast<MemberExpr>(RHSBase); > > + } > > + > > + LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase); > > + RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase); > > + if (LHSDeclRef && RHSDeclRef) { > > + if (!LHSDeclRef->getDecl() || !RHSDeclRef->getDecl()) > > + return; > > + if (LHSDeclRef->getDecl()->getCanonicalDecl() != > > + RHSDeclRef->getDecl()->getCanonicalDecl()) > > + return; > > + > > + S.Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() > > + << LHSExpr->getSourceRange() > > + << RHSExpr->getSourceRange(); > > + return; > > + } > > + > > + if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase)) > > + S.Diag(OpLoc, diag::warn_self_move) << LHSExpr->getType() > > + << LHSExpr->getSourceRange() > > + << RHSExpr->getSourceRange(); > > +} > > + > > /// DiagnoseSelfAssignment - Emits a warning if a value is assigned to > itself. > > /// This warning is only emitted for builtin assignment operations. It > is also > > /// suppressed in the event of macro expansions. > > @@ -9507,8 +9591,10 @@ ExprResult Sema::CreateBuiltinBinOp(Sour > > VK = LHS.get()->getValueKind(); > > OK = LHS.get()->getObjectKind(); > > } > > - if (!ResultTy.isNull()) > > + if (!ResultTy.isNull()) { > > DiagnoseSelfAssignment(*this, LHS.get(), RHS.get(), OpLoc); > > + DiagnoseSelfMove(*this, LHS.get(), RHS.get(), OpLoc); > > + } > > RecordModifiableNonNullParam(*this, LHS.get()); > > break; > > case BO_PtrMemD: > > > > Added: cfe/trunk/test/SemaCXX/warn-self-move.cpp > > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-self-move.cpp?rev=225581&view=auto > > > ============================================================================== > > --- cfe/trunk/test/SemaCXX/warn-self-move.cpp (added) > > +++ cfe/trunk/test/SemaCXX/warn-self-move.cpp Sat Jan 10 00:04:18 2015 > > @@ -0,0 +1,40 @@ > > +// RUN: %clang_cc1 -fsyntax-only -Wself-move -std=c++11 -verify %s > > + > > +// definitions for std::move > > +namespace std { > > +inline namespace foo { > > +template <class T> struct remove_reference { typedef T type; }; > > +template <class T> struct remove_reference<T&> { typedef T type; }; > > +template <class T> struct remove_reference<T&&> { typedef T type; }; > > + > > +template <class T> typename remove_reference<T>::type &&move(T &&t); > > +} > > +} > > + > > +void int_test() { > > + int x = 5; > > + x = std::move(x); // expected-warning{{explicitly moving}} > > + (x) = std::move(x); // expected-warning{{explicitly moving}} > > + > > + using std::move; > > + x = move(x); // expected-warning{{explicitly moving}} > > +} > > + > > +int global; > > +void global_int_test() { > > + global = std::move(global); // expected-warning{{explicitly moving}} > > + (global) = std::move(global); // expected-warning{{explicitly > moving}} > > + > > + using std::move; > > + global = move(global); // expected-warning{{explicitly moving}} > > +} > > + > > +class field_test { > > + int x; > > + field_test(field_test&& other) { > > + x = std::move(x); // expected-warning{{explicitly moving}} > > + x = std::move(other.x); > > + other.x = std::move(x); > > + other.x = std::move(other.x); // expected-warning{{explicitly > moving}} > > + } > > +}; > > > > > > _______________________________________________ > > cfe-commits mailing list > > [email protected] > > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
