[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-03-06 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr closed 
https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-03-06 Thread Max Winkler via cfe-commits

MaxEW707 wrote:

Thanks all for the review :).

I will need one of you to commit on my behalf since I do not have write access.

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-03-05 Thread Timm Baeder via cfe-commits

https://github.com/tbaederr approved this pull request.

Much better, thanks.

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-03-05 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 updated 
https://github.com/llvm/llvm-project/pull/76646

>From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sat, 30 Dec 2023 22:00:38 -0500
Subject: [PATCH 1/4] Warn on self move for inlined static cast

---
 clang/lib/Sema/SemaChecking.cpp   | 19 ++-
 clang/test/SemaCXX/warn-self-move.cpp | 13 +
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(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}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

>From ecd9d5bf0d3fa0bc3e64266c6e7586da25438652 Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sun, 31 Dec 2023 17:47:03 -0500
Subject: [PATCH 2/4] use auto

---
 clang/lib/Sema/SemaChecking.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a21410434d8099..ecb3269d0d30c7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18845,7 +18845,7 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const 
Expr *RHSExpr,
 
   // Check for a call expression or static_cast expression
   const CallExpr *CE = 

[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-02-29 Thread Timm Baeder via cfe-commits


@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const auto *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();

tbaederr wrote:

```suggestion
  if (const auto *CE = dyn_cast(RHSExpr);
  CE && CE->getNumArgs() == 1 && CE->isCallToStdMove())
RHSExpr = CE->getArg(0);
  else if (const auto *CXXSCE = dyn_cast(RHSExpr);
  CXXSCE && CXXSCE->isXValue())
RHSExpr = CXXSCE->getSubExpr();
  else
return;
```

I think that would be shorter and cleaner. (This replaces the few lines above 
as well but I can't add a suggestion like that in Github).

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-02-29 Thread Shafik Yaghmour via cfe-commits


@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(x);  // expected-warning{{explicitly moving}}

shafik wrote:

Can you add some tests where we should not get diagnostics for example like the 
one right below but w/ `static_cast`

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-02-29 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik edited https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-02-29 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik approved this pull request.

LGTM, any objections @tbaederr 

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2024-01-29 Thread Max Winkler via cfe-commits

MaxEW707 wrote:

Ping

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-31 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 updated 
https://github.com/llvm/llvm-project/pull/76646

>From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sat, 30 Dec 2023 22:00:38 -0500
Subject: [PATCH 1/2] Warn on self move for inlined static cast

---
 clang/lib/Sema/SemaChecking.cpp   | 19 ++-
 clang/test/SemaCXX/warn-self-move.cpp | 13 +
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(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}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

>From ecd9d5bf0d3fa0bc3e64266c6e7586da25438652 Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sun, 31 Dec 2023 17:47:03 -0500
Subject: [PATCH 2/2] use auto

---
 clang/lib/Sema/SemaChecking.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a21410434d8099..ecb3269d0d30c7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18845,7 +18845,7 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const 
Expr *RHSExpr,
 
   // Check for a call expression or static_cast expression
   const CallExpr *CE = 

[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-31 Thread Timm Baeder via cfe-commits


@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);

tbaederr wrote:

```suggestion
  const auto *CXXSCE = dyn_cast(RHSExpr);
```

https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Max Winkler (MaxEW707)


Changes

There are code bases that inline `std::move` manually via `static_cast`.
Treat a static cast to an xvalue as an inlined `std::move` call and warn on a 
self move.

---
Full diff: https://github.com/llvm/llvm-project/pull/76646.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaChecking.cpp (+14-5) 
- (modified) clang/test/SemaCXX/warn-self-move.cpp (+13) 


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(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}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

``




https://github.com/llvm/llvm-project/pull/76646
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang][Sema] Warn on self move for inlined static cast (PR #76646)

2023-12-30 Thread Max Winkler via cfe-commits

https://github.com/MaxEW707 created 
https://github.com/llvm/llvm-project/pull/76646

There are code bases that inline `std::move` manually via `static_cast`.
Treat a static cast to an xvalue as an inlined `std::move` call and warn on a 
self move.

>From a081f8266f24405523e6d283318bd898fd2d376a Mon Sep 17 00:00:00 2001
From: MaxEW707 <82551778+maxew...@users.noreply.github.com>
Date: Sat, 30 Dec 2023 22:00:38 -0500
Subject: [PATCH] Warn on self move for inlined static cast

---
 clang/lib/Sema/SemaChecking.cpp   | 19 ++-
 clang/test/SemaCXX/warn-self-move.cpp | 13 +
 2 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a69325f029514..a21410434d8099 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -18843,17 +18843,26 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, 
const Expr *RHSExpr,
   LHSExpr = LHSExpr->IgnoreParenImpCasts();
   RHSExpr = RHSExpr->IgnoreParenImpCasts();
 
-  // Check for a call expression
+  // Check for a call expression or static_cast expression
   const CallExpr *CE = dyn_cast(RHSExpr);
-  if (!CE || CE->getNumArgs() != 1)
+  const CXXStaticCastExpr *CXXSCE = dyn_cast(RHSExpr);
+  if (!CE && !CXXSCE)
 return;
 
   // Check for a call to std::move
-  if (!CE->isCallToStdMove())
+  if (CE && (CE->getNumArgs() != 1 || !CE->isCallToStdMove()))
 return;
 
-  // Get argument from std::move
-  RHSExpr = CE->getArg(0);
+  // Check for a static_cast(..) to an xvalue which we can treat as an
+  // inlined std::move
+  if (CXXSCE && !CXXSCE->isXValue())
+return;
+
+  // Get argument from std::move or static_cast
+  if (CE)
+RHSExpr = CE->getArg(0);
+  else
+RHSExpr = CXXSCE->getSubExpr();
 
   const DeclRefExpr *LHSDeclRef = dyn_cast(LHSExpr);
   const DeclRefExpr *RHSDeclRef = dyn_cast(RHSExpr);
diff --git a/clang/test/SemaCXX/warn-self-move.cpp 
b/clang/test/SemaCXX/warn-self-move.cpp
index 0987e9b6bf6017..d0158626424142 100644
--- a/clang/test/SemaCXX/warn-self-move.cpp
+++ b/clang/test/SemaCXX/warn-self-move.cpp
@@ -16,6 +16,9 @@ void int_test() {
   x = std::move(x);  // expected-warning{{explicitly moving}}
   (x) = std::move(x);  // expected-warning{{explicitly moving}}
 
+  x = static_cast(x);  // expected-warning{{explicitly moving}}
+  (x) = static_cast(x);  // expected-warning{{explicitly moving}}
+
   using std::move;
   x = move(x); // expected-warning{{explicitly moving}} \
expected-warning {{unqualified call to 'std::move}}
@@ -26,6 +29,9 @@ void global_int_test() {
   global = std::move(global);  // expected-warning{{explicitly moving}}
   (global) = std::move(global);  // expected-warning{{explicitly moving}}
 
+  global = static_cast(global);  // expected-warning{{explicitly 
moving}}
+  (global) = static_cast(global);  // expected-warning{{explicitly 
moving}}
+
   using std::move;
   global = move(global); // expected-warning{{explicitly moving}} \
  expected-warning {{unqualified call to 
'std::move}}
@@ -35,11 +41,14 @@ class field_test {
   int x;
   field_test(field_test&& other) {
 x = std::move(x);  // expected-warning{{explicitly moving}}
+x = static_cast(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}}
+other.x = static_cast(other.x);  // expected-warning{{explicitly 
moving}}
   }
   void withSuggest(int x) {
+x = static_cast(x); // expected-warning{{explicitly moving variable 
of type 'int' to itself; did you mean to move to member 'x'?}}
 x = std::move(x); // expected-warning{{explicitly moving variable of type 
'int' to itself; did you mean to move to member 'x'?}}
   }
 };
@@ -50,11 +59,15 @@ struct C { C() {}; ~C() {} };
 void struct_test() {
   A a;
   a = std::move(a);  // expected-warning{{explicitly moving}}
+  a = static_cast(a);  // expected-warning{{explicitly moving}}
 
   B b;
   b = std::move(b);  // expected-warning{{explicitly moving}}
+  b = static_cast(b);  // expected-warning{{explicitly moving}}
   b.a = std::move(b.a);  // expected-warning{{explicitly moving}}
+  b.a = static_cast(b.a);  // expected-warning{{explicitly moving}}
 
   C c;
   c = std::move(c);  // expected-warning{{explicitly moving}}
+  c = static_cast(c);  // expected-warning{{explicitly moving}}
 }

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