From: Richard Trieu Date: Wed, 29 Jul 2015 17:03:34 +0000 (+0000) Subject: Disable -Wpessimizing-move and -Wredundant-move in template instantiations. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8147824ed3cfe14d9753eafa69d4196f926620b9;p=clang Disable -Wpessimizing-move and -Wredundant-move in template instantiations. Dependent types can throw off the analysis for these warnings, possibly giving conflicting warnings and fix-its. Disabling the warning in template instantiations will prevent this problem, and will still catch the non-dependent cases in templates. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@243538 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index fd067775ac..f66bc7f37a 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -5926,6 +5926,9 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr, if (!InitExpr) return; + if (!S.ActiveTemplateInstantiations.empty()) + return; + QualType DestType = InitExpr->getType(); if (!DestType->isRecordType()) return; diff --git a/test/SemaCXX/warn-pessmizing-move.cpp b/test/SemaCXX/warn-pessmizing-move.cpp index f5a4b90946..5645564c74 100644 --- a/test/SemaCXX/warn-pessmizing-move.cpp +++ b/test/SemaCXX/warn-pessmizing-move.cpp @@ -196,3 +196,40 @@ A test10() { // expected-warning@-1{{prevents copy elision}} // CHECK-NOT: fix-it } + +namespace templates { + struct A {}; + struct B { B(A); }; + struct C { C(); C(C&&); }; + struct D { D(C); }; + + // Warn once here since the type is not dependent. + template + A test1() { + A a; + return std::move(a); + // expected-warning@-1{{prevents copy elision}} + // expected-note@-2{{remove std::move call}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + } + void run_test1() { + test1(); + test1(); + test1(); + test1(); + } + + // Either a pessimizing move, a redundant move, or no warning could be + // emitted, given the right types. So just drop the warning. + template + T1 test2() { + T2 t; + return std::move(t); + } + void run_test2() { + test2(); + test2(); + test2(); + } +} diff --git a/test/SemaCXX/warn-redundant-move.cpp b/test/SemaCXX/warn-redundant-move.cpp index 06f9c58bae..d160695207 100644 --- a/test/SemaCXX/warn-redundant-move.cpp +++ b/test/SemaCXX/warn-redundant-move.cpp @@ -103,6 +103,43 @@ D test5(D d) { // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:"" } +namespace templates { + struct A {}; + struct B { B(A); }; + struct C { C(); C(C&&); }; + struct D { D(C); }; + + // Warn once here since the type is not dependent. + template + B test1() { + A a; + return std::move(a); + // expected-warning@-1{{redundant move in return statement}} + // expected-note@-2{{remove std::move call here}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + } + void run_test1() { + test1(); + test1(); + test1(); + test1(); + } + + // Either a pessimizing move, a redundant move, or no warning could be + // emitted, given the right types. So just drop the warning. + template + T1 test2() { + T2 t; + return std::move(t); + } + void run_test2() { + test2(); + test2(); + test2(); + } +} + // No more fix-its past here. // CHECK-NOT: fix-it