Index: include/clang/Basic/DiagnosticGroups.td =================================================================== --- include/clang/Basic/DiagnosticGroups.td +++ include/clang/Basic/DiagnosticGroups.td @@ -495,6 +495,7 @@ def GNUZeroLineDirective : DiagGroup<"gnu-zero-line-directive">; def GNUZeroVariadicMacroArguments : DiagGroup<"gnu-zero-variadic-macro-arguments">; def Fallback : DiagGroup<"fallback">; +def NonIdiomaticCopyMove : DiagGroup<"non-idiomatic-copy-move">; // This covers both the deprecated case (in C++98) // and the extension case (in C++11 onwards). Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -4166,6 +4166,15 @@ "%select{copy|move}0 assignment operator of %1 is implicitly deleted " "because field %2 is of %select{reference|const-qualified}4 type %3">; +def warn_non_idiomatic_copy_move_ctor : Warning< + "non-idiomatic %select{copy|move}0 constructor declaration; consider " + "%select{'const T&'|'T&&'}0 instead">, + InGroup; +def warn_non_idiomatic_copy_move_assign : Warning< + "non-idiomatic %select{copy|move}0 assignment operator declaration; consider " + "%select{returning 'T&'|'%select{const T&|T&&}0'|removing ref-qualifiers}1 " + "instead">, InGroup; + // These should be errors. def warn_undefined_internal : Warning< "%select{function|variable}0 %q1 has internal linkage but is not defined">, Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -4899,6 +4899,67 @@ } } +static void DiagnoseNonIdiomaticConstructor(Sema &S, + const CXXConstructorDecl *Ctor, + bool Move) { + // This is already known to be a copy or move constructor, so there is at + // least one parameter of a sensible class type. Check the qualifiers on that + // type to determine if they are idiomatic or not. + QualType ParamType = Ctor->getParamDecl(0)->getType(); + assert(ParamType->isReferenceType() && + "Copy or move ctor with non-reference type"); + QualType RefType = + S.Context.getCanonicalType(ParamType.getNonReferenceType()); + + if (RefType.isVolatileQualified() || + ((!Move && !RefType.isConstQualified()) || + (Move && RefType.isConstQualified()))) + S.Diag(Ctor->getParamDecl(0)->getLocation(), + diag::warn_non_idiomatic_copy_move_ctor) << Move; +} + +static void DiagnoseNonIdiomaticAssignment(Sema &S, + const CXXMethodDecl *Assign, + bool Move) { + // Check that there are no ref-qualifiers. + if (Assign->getRefQualifier() != RQ_None) { + S.Diag(Assign->getLocation(), diag::warn_non_idiomatic_copy_move_assign) + << Move << /*ref-qualifier*/ 2; + return; + } + + // Check that the return type is an lvalue reference type that is an + // unqualified reference to the class type. + QualType ClassType = S.Context.getTagDeclType(Assign->getParent()); + QualType ReturnType = Assign->getReturnType(); + if (!ReturnType->isLValueReferenceType() || + ReturnType.getNonReferenceType().hasQualifiers() || + S.Context.getCanonicalType(ReturnType).getNonReferenceType() != + ClassType) { + S.Diag(Assign->getReturnTypeSourceRange().getBegin(), + diag::warn_non_idiomatic_copy_move_assign) << Move << /*return*/ 0; + return; + } + + // This is already known to be a copy or move assignment operator, so there + // is at least one parameter of a sensible class type. Check that it is an + // idiomatic parameter type. For a move assignment, if the non-reference type + // has any qualifiers, it is not idiomatic. For a copy assignment, if the type + // is not a reference type, or if it is a reference type that is not solely + // const-qualified, it is not idiomatic. + QualType ParamType = + S.Context.getCanonicalType(Assign->getParamDecl(0)->getType()); + QualType ParamNonRefType = ParamType.getNonReferenceType(); + if ((Move && ParamNonRefType.hasQualifiers()) || + (!Move && (!ParamType->isReferenceType() || + ParamNonRefType.isVolatileQualified() || + !ParamNonRefType.isConstQualified()))) { + S.Diag(Assign->getParamDecl(0)->getLocation(), + diag::warn_non_idiomatic_copy_move_assign) << Move << /*param*/ 1; + return; + } +} + /// \brief Perform semantic checks on a class definition that has been /// completing, introducing implicitly-declared members, checking for /// abstract types, etc. @@ -5038,6 +5099,62 @@ DeclareInheritingConstructors(Record); checkClassLevelDLLAttribute(Record); + + // Diagnose non-idiomatic copy/move constructors. Do not diagnose an operation + // in the presence of an idiomatic variant or multiple non-idiomatic variants. + if (Record->hasUserDeclaredCopyConstructor() || + Record->hasUserDeclaredMoveConstructor()) { + SmallVector CopyCtors, MoveCtors; + for (const auto *Ctor : Record->ctors()) { + // If the constructor has default arguments or has been flagged as being + // invalid, skip it. + if (Ctor->isInvalidDecl() || Ctor->getNumParams() != 1) + continue; + if (Ctor->isCopyConstructor()) + CopyCtors.push_back(Ctor); + else if (Ctor->isMoveConstructor()) + MoveCtors.push_back(Ctor); + } + + // If there are multiple copy/move constructors (considered separately), + // then no diagnostics should be triggered even if some of the constructors + // are non-idiomatic. If there is only one such constructor, and it is non- + // idiomatic, then diagnose. + if (CopyCtors.size() == 1) + DiagnoseNonIdiomaticConstructor(*this, CopyCtors.front(), false); + if (MoveCtors.size() == 1) + DiagnoseNonIdiomaticConstructor(*this, MoveCtors.front(), true); + } + + // Diagnose non-idiomatic copy/move assignment operators. Do not diagnose an + // operation in the presence of an idiomatic variant or multiple non-idiomatic + // variants. + if (Record->hasUserDeclaredCopyAssignment() || + Record->hasUserDeclaredMoveAssignment()) { + SmallVector CopyAssigns, MoveAssigns; + // If the assignment operator has been flagged as being invalid, skip it. + for (const auto *M : Record->methods()) { + if (M->isInvalidDecl()) + continue; + if (M->isCopyAssignmentOperator()) + CopyAssigns.push_back(M); + else if (M->isMoveAssignmentOperator()) + MoveAssigns.push_back(M); + } + + // If there are multiple copy/move assignment operators (considered + // separately), then no diagnostics should be triggered even if some of the + // operators are non-idiomatic. If there is only one such operator, and it + // is non-idiomatic, then diagnose. + if (CopyAssigns.size() == 1) + DiagnoseNonIdiomaticAssignment(*this, CopyAssigns.front(), false); + if (MoveAssigns.size() == 1) + DiagnoseNonIdiomaticAssignment(*this, MoveAssigns.front(), true); + } + + if (Record->hasUserDeclaredCopyAssignment() || + Record->hasUserDeclaredMoveAssignment()) { + } } /// Look up the special member function that would be called by a special Index: test/Analysis/NewDelete-checker-test.cpp =================================================================== --- test/Analysis/NewDelete-checker-test.cpp +++ test/Analysis/NewDelete-checker-test.cpp @@ -71,7 +71,7 @@ //----- Other cases void testNewMemoryIsInHeap() { int *p = new int; - if (global != p) // condition is always true as 'p' wraps a heap region that + if (global != p) // condition is always true as 'p' wraps a heap region that // is different from a region wrapped by 'global' global = p; // pointer escapes } @@ -278,7 +278,7 @@ explicit shared_ptr(T *p) : p(p), control(new control_block) { control->retain(); } - shared_ptr(shared_ptr &other) : p(other.p), control(other.control) { + shared_ptr(const shared_ptr &other) : p(other.p), control(other.control) { if (control) control->retain(); } Index: test/Analysis/inlining/path-notes.cpp =================================================================== --- test/Analysis/inlining/path-notes.cpp +++ test/Analysis/inlining/path-notes.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-non-idiomatic-copy-move -Wno-tautological-undefined-compare %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-non-idiomatic-copy-move -Wno-tautological-undefined-compare // RUN: FileCheck --input-file=%t.plist %s class Foo { Index: test/Analysis/operator-calls.cpp =================================================================== --- test/Analysis/operator-calls.cpp +++ test/Analysis/operator-calls.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s +// RUN: %clang_cc1 -std=c++11 -Wno-non-idiomatic-copy-move -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s void clang_analyzer_eval(bool); struct X0 { }; Index: test/CXX/basic/basic.types/p10.cpp =================================================================== --- test/CXX/basic/basic.types/p10.cpp +++ test/CXX/basic/basic.types/p10.cpp @@ -20,7 +20,7 @@ struct BeingDefined; extern BeingDefined beingdefined; -struct BeingDefined { +struct BeingDefined { static constexpr BeingDefined& t = beingdefined; }; @@ -75,7 +75,7 @@ template constexpr CtorTemplate(T); }; struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} - constexpr CopyCtorOnly(CopyCtorOnly&); + constexpr CopyCtorOnly(const CopyCtorOnly&); }; constexpr int f(CopyCtorOnly) { return 0; } // expected-error {{'CopyCtorOnly' is not a literal type}} struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} Index: test/CXX/class.access/p4.cpp =================================================================== --- test/CXX/class.access/p4.cpp +++ test/CXX/class.access/p4.cpp @@ -95,11 +95,11 @@ A a; // expected-error {{calling a private constructor}} A A::foo; // okay - + class B : A { }; // expected-error {{base class 'test2::A' has private default constructor}} B b; // expected-note{{implicit default constructor}} - - class C : virtual A { + + class C : virtual A { public: C(); }; @@ -149,7 +149,7 @@ virtual Base<1>, // expected-error 2 {{base class 'Base<1>' has private destructor}} Base2, // expected-error 2 {{base class 'test3::Base2' has private destructor}} virtual Base3 - {}; + {}; Derived3 d3; // expected-note {{implicit default constructor}}\ // expected-note{{implicit destructor}}} } @@ -201,12 +201,12 @@ // Implicit copy assignment operator uses. namespace test5 { class A { - void operator=(const A &); // expected-note 2 {{implicitly declared private here}} + A& operator=(const A &); // expected-note 2 {{implicitly declared private here}} }; class Test1 { A a; }; // expected-error {{private member}} void test1() { - Test1 a; + Test1 a; a = Test1(); // expected-note{{implicit copy}} } @@ -247,7 +247,7 @@ }; } -// Ignored operator new and delete overloads are not +// Ignored operator new and delete overloads are not namespace test8 { typedef __typeof__(sizeof(int)) size_t; @@ -355,11 +355,11 @@ class X { ~X(); // expected-note {{declared private here}} }; - + struct Y1 { operator X(); }; - + void g() { const X &xr = Y1(); // expected-error{{temporary of type 'test14::X' has private destructor}} } @@ -393,7 +393,7 @@ }; template class A; - template class A; // expected-note 4 {{in instantiation}} + template class A; // expected-note 4 {{in instantiation}} template class B : public A { // TODO: These first two accesses can be detected as ill-formed at @@ -454,7 +454,7 @@ // PR8325 namespace test19 { class A { ~A(); }; - // The destructor is not implicitly referenced here. Contrast to test16, + // The destructor is not implicitly referenced here. Contrast to test16, // testing PR7281, earlier in this file. void b(A* x) { throw x; } } Index: test/CXX/class/class.union/p1.cpp =================================================================== --- test/CXX/class/class.union/p1.cpp +++ test/CXX/class/class.union/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s void abort() __attribute__((noreturn)); @@ -24,11 +24,11 @@ }; class CopyCtor { // expected-note 2{{because no constructor can be used to copy an object of type 'const CopyCtor'}} - CopyCtor(CopyCtor &cc) { abort(); } + CopyCtor(CopyCtor &cc) { abort(); } // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; class CopyAssign { // expected-note 2 {{because no assignment operator can be used to copy an object of type 'const CopyAssign'}} - CopyAssign& operator=(CopyAssign& CA) { abort(); } + CopyAssign& operator=(CopyAssign& CA) { abort(); } // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; class Dtor { Index: test/CXX/class/p6-0x.cpp =================================================================== --- test/CXX/class/p6-0x.cpp +++ test/CXX/class/p6-0x.cpp @@ -4,8 +4,8 @@ class Trivial { int n; void f(); }; class NonTrivial1 { NonTrivial1(const NonTrivial1 &); }; class NonTrivial2 { NonTrivial2(NonTrivial2 &&); }; -class NonTrivial3 { NonTrivial3 operator=(const NonTrivial3 &); }; -class NonTrivial4 { NonTrivial4 operator=(NonTrivial4 &&); }; +class NonTrivial3 { NonTrivial3& operator=(const NonTrivial3 &); }; +class NonTrivial4 { NonTrivial4& operator=(NonTrivial4 &&); }; class NonTrivial5 { ~NonTrivial5(); }; static_assert(__is_trivial(Trivial), "Trivial is not trivial"); Index: test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp =================================================================== --- test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp +++ test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p1.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify %s -std=c++11 +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move %s -std=c++11 // A function that is explicitly defaulted shall struct A { Index: test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp =================================================================== --- test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp +++ test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp @@ -22,7 +22,8 @@ X3(); private: - X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} + X3(X3&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; // Check for instantiation of default arguments @@ -38,7 +39,7 @@ struct X4 { X4(); X4(const X4&, T = get_value_badly()); // expected-note{{in instantiation of}} -}; +}; // Check for "dangerous" default arguments that could cause recursion. struct X5 { Index: test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp =================================================================== --- test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp +++ test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx0x-no-extra-copy.cpp @@ -21,7 +21,7 @@ X3(); private: - X3(X3&); + X3(X3&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; template Index: test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp =================================================================== --- test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp +++ test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-non-idiomatic-copy-move -std=c++11 %s // FIXME: test with non-std qualifiers Index: test/CXX/drs/dr0xx.cpp =================================================================== --- test/CXX/drs/dr0xx.cpp +++ test/CXX/drs/dr0xx.cpp @@ -70,7 +70,7 @@ }; const volatile B b = a; - struct C { C(C&); }; + struct C { C(C&); }; // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} struct D : C {}; struct E { operator D&(); } e; const C c = e; @@ -901,7 +901,8 @@ struct A { operator B() const; }; struct C {}; struct B { - B(B&); // expected-note {{candidate}} + B(B&); // expected-note {{candidate}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} B(C); operator C() const; }; Index: test/CXX/drs/dr1xx.cpp =================================================================== --- test/CXX/drs/dr1xx.cpp +++ test/CXX/drs/dr1xx.cpp @@ -826,7 +826,8 @@ namespace dr177 { // dr177: yes struct B {}; struct A { - A(A &); // expected-note {{not viable: expects an l-value}} + A(A &); // expected-note {{not viable: expects an l-value}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} A(const B &); }; B b; Index: test/CXX/drs/dr3xx.cpp =================================================================== --- test/CXX/drs/dr3xx.cpp +++ test/CXX/drs/dr3xx.cpp @@ -357,7 +357,8 @@ namespace dr331 { // dr331: yes struct A { - A(volatile A&); // expected-note {{candidate}} + A(volatile A&); // expected-note {{candidate}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} } const a, b(a); // expected-error {{no matching constructor}} } @@ -1010,7 +1011,7 @@ } namespace dr385 { // dr385: yes - struct A { protected: void f(); }; + struct A { protected: void f(); }; struct B : A { using A::f; }; struct C : A { void g(B b) { b.f(); } }; void h(B b) { b.f(); } Index: test/CXX/drs/dr5xx.cpp =================================================================== --- test/CXX/drs/dr5xx.cpp +++ test/CXX/drs/dr5xx.cpp @@ -157,7 +157,7 @@ template void b3(Base *); void test(int n, const int cn, int **p, int *S::*pm) { - int *a[3], *S::*am[3]; + int *a[3], *S::*am[3]; const Derived cd = Derived(); Derived d[3]; @@ -742,10 +742,12 @@ }; #if __cplusplus >= 201103L struct C { - C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} + C &operator=(const C&) &; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} \ + // expected-warning {{non-idiomatic copy assignment operator declaration; consider removing ref-qualifiers instead}} }; struct D { - D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} + D &operator=(const D&) &&; // expected-note {{not viable}} expected-note {{nearly matches}} expected-note {{here}} \ + // expected-warning {{non-idiomatic copy assignment operator declaration; consider removing ref-qualifiers instead}} }; void test(C c, D d) { c = c; Index: test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp =================================================================== --- test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp +++ test/CXX/expr/expr.prim/expr.prim.lambda/p14.cpp @@ -10,13 +10,14 @@ class NonConstCopy { public: - NonConstCopy(NonConstCopy&); // expected-note{{would lose const}} + NonConstCopy(NonConstCopy&); // expected-note{{would lose const}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; void capture_by_copy(NonCopyable nc, NonCopyable &ncr, const NonConstCopy nco) { (void)[nc] { }; // expected-error{{capture of variable 'nc' as type 'NonCopyable' calls private copy constructor}} (void)[=] { - ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}} + ncr.foo(); // expected-error{{capture of variable 'ncr' as type 'NonCopyable' calls private copy constructor}} }(); [nco] {}(); // expected-error{{no matching constructor for initialization of 'const NonConstCopy'}} Index: test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp =================================================================== --- test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp +++ test/CXX/expr/expr.prim/expr.prim.lambda/p21.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify -Wno-non-idiomatic-copy-move // expected-no-diagnostics struct DirectInitOnly { Index: test/CXX/special/class.copy/implicit-move.cpp =================================================================== --- test/CXX/special/class.copy/implicit-move.cpp +++ test/CXX/special/class.copy/implicit-move.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-inaccessible-base -Wno-non-idiomatic-copy-move %s // Tests for implicit (non-)declaration of move constructor and // assignment: p9, p11, p20, p23. @@ -142,16 +142,16 @@ static_assert(!noexcept(cntco = ContainsNonTrivialCopyOnly()), ""); ContainsConst cc; - cc = ContainsConst(); // expected-error {{no viable}} + cc = ContainsConst(); // expected-error {{no viable}} ContainsRef cr; - cr = ContainsRef(); // expected-error {{no viable}} + cr = ContainsRef(); // expected-error {{no viable}} DirectVirtualBase dvb; - dvb = DirectVirtualBase(); // expected-error {{no viable}} + dvb = DirectVirtualBase(); // expected-error {{no viable}} IndirectVirtualBase ivb; - ivb = IndirectVirtualBase(); // expected-error {{no viable}} + ivb = IndirectVirtualBase(); // expected-error {{no viable}} } struct ContainsRValueRef { Index: test/CXX/special/class.copy/p11.0x.copy.cpp =================================================================== --- test/CXX/special/class.copy/p11.0x.copy.cpp +++ test/CXX/special/class.copy/p11.0x.copy.cpp @@ -49,7 +49,7 @@ HasAccess HAb(HAa); struct NonConst { - NonConst(NonConst&); + NonConst(NonConst&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct Ambiguity { Ambiguity(const Ambiguity&); Index: test/CXX/special/class.copy/p12-0x.cpp =================================================================== --- test/CXX/special/class.copy/p12-0x.cpp +++ test/CXX/special/class.copy/p12-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-non-idiomatic-copy-move // expected-no-diagnostics Index: test/CXX/special/class.copy/p18-cxx11.cpp =================================================================== --- test/CXX/special/class.copy/p18-cxx11.cpp +++ test/CXX/special/class.copy/p18-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify -Wno-non-idiomatic-copy-move // expected-no-diagnostics // C++98 [class.copy]p10 / C++11 [class.copy]p18. Index: test/CXX/special/class.copy/p20.cpp =================================================================== --- test/CXX/special/class.copy/p20.cpp +++ test/CXX/special/class.copy/p20.cpp @@ -7,10 +7,10 @@ struct NonConstCopy { NonConstCopy(); - NonConstCopy &operator=(NonConstCopy&); + NonConstCopy &operator=(NonConstCopy&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; -struct VirtualInheritsNonConstCopy : virtual NonConstCopy { +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { VirtualInheritsNonConstCopy(); VirtualInheritsNonConstCopy &operator=(const VirtualInheritsNonConstCopy&); }; @@ -29,7 +29,7 @@ NonConstCopy ncc_array[2][3]; }; -struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { +struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { ImplicitNonConstCopy4(); }; Index: test/CXX/special/class.copy/p23-cxx11.cpp =================================================================== --- test/CXX/special/class.copy/p23-cxx11.cpp +++ test/CXX/special/class.copy/p23-cxx11.cpp @@ -50,7 +50,7 @@ InaccessibleMoveAssign &operator=(InaccessibleMoveAssign &&); }; class NonConstCopyAssign { - NonConstCopyAssign &operator=(NonConstCopyAssign &); + NonConstCopyAssign &operator=(NonConstCopyAssign &); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; // A defaulted copy/move assignment operator for class X is defined as deleted Index: test/CXX/special/class.copy/p25-0x.cpp =================================================================== --- test/CXX/special/class.copy/p25-0x.cpp +++ test/CXX/special/class.copy/p25-0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -verify %s +// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-non-idiomatic-copy-move // expected-no-diagnostics Index: test/CXX/special/class.copy/p8-cxx11.cpp =================================================================== --- test/CXX/special/class.copy/p8-cxx11.cpp +++ test/CXX/special/class.copy/p8-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 %s -verify +// RUN: %clang_cc1 -std=c++11 %s -verify -Wno-non-idiomatic-copy-move // expected-no-diagnostics // C++98 [class.copy]p5 / C++11 [class.copy]p8. Index: test/CXX/special/class.copy/p9.cpp =================================================================== --- test/CXX/special/class.copy/p9.cpp +++ test/CXX/special/class.copy/p9.cpp @@ -7,10 +7,10 @@ struct NonConstCopy { NonConstCopy(); - NonConstCopy(NonConstCopy&); + NonConstCopy(NonConstCopy&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; -struct VirtualInheritsNonConstCopy : virtual NonConstCopy { +struct VirtualInheritsNonConstCopy : virtual NonConstCopy { VirtualInheritsNonConstCopy(); VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&); }; Index: test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp =================================================================== --- test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp +++ test/CXX/stmt.stmt/stmt.dcl/p3-0x.cpp @@ -38,13 +38,13 @@ { Y y2; // expected-note{{jump bypasses variable with a non-trivial destructor}} inner: - f(); + f(); } return; } struct Z { - Z operator=(const Z&); + Z& operator=(const Z&); }; void test_Z() { Index: test/CXX/stmt.stmt/stmt.dcl/p3.cpp =================================================================== --- test/CXX/stmt.stmt/stmt.dcl/p3.cpp +++ test/CXX/stmt.stmt/stmt.dcl/p3.cpp @@ -36,7 +36,7 @@ } struct Z { - Z operator=(const Z&); + Z& operator=(const Z&); }; void test_Z() { Index: test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp =================================================================== --- test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp +++ test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wno-non-idiomatic-copy-move %s // expected-no-diagnostics #if !__has_feature(cxx_access_control_sfinae) Index: test/CodeGenCXX/copy-assign-synthesis-3.cpp =================================================================== --- test/CodeGenCXX/copy-assign-synthesis-3.cpp +++ test/CodeGenCXX/copy-assign-synthesis-3.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -verify %s +// RUN: %clang_cc1 -emit-llvm-only -verify -Wno-non-idiomatic-copy-move %s // expected-no-diagnostics struct A { Index: test/OpenMP/for_firstprivate_messages.cpp =================================================================== --- test/OpenMP/for_firstprivate_messages.cpp +++ test/OpenMP/for_firstprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/for_lastprivate_messages.cpp =================================================================== --- test/OpenMP/for_lastprivate_messages.cpp +++ test/OpenMP/for_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -fopenmp -Wno-non-idiomatic-copy-move %s void foo() { } Index: test/OpenMP/for_reduction_messages.cpp =================================================================== --- test/OpenMP/for_reduction_messages.cpp +++ test/OpenMP/for_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -ferror-limit 150 -o - %s void foo() { } Index: test/OpenMP/for_simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/for_simd_lastprivate_messages.cpp +++ test/OpenMP/for_simd_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/for_simd_reduction_messages.cpp +++ test/OpenMP/for_simd_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 %s void foo() { } Index: test/OpenMP/parallel_copyin_messages.cpp =================================================================== --- test/OpenMP/parallel_copyin_messages.cpp +++ test/OpenMP/parallel_copyin_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_for_copyin_messages.cpp =================================================================== --- test/OpenMP/parallel_for_copyin_messages.cpp +++ test/OpenMP/parallel_for_copyin_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_for_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_lastprivate_messages.cpp +++ test/OpenMP/parallel_for_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/parallel_for_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_reduction_messages.cpp +++ test/OpenMP/parallel_for_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_for_simd_copyin_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_copyin_messages.cpp +++ test/OpenMP/parallel_for_simd_copyin_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -o - %s void foo() { } Index: test/OpenMP/parallel_for_simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_lastprivate_messages.cpp +++ test/OpenMP/parallel_for_simd_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/parallel_for_simd_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -o - %s void foo() { } Index: test/OpenMP/parallel_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_reduction_messages.cpp +++ test/OpenMP/parallel_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_sections_copyin_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_copyin_messages.cpp +++ test/OpenMP/parallel_sections_copyin_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_sections_lastprivate_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_lastprivate_messages.cpp +++ test/OpenMP/parallel_sections_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/parallel_sections_reduction_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_reduction_messages.cpp +++ test/OpenMP/parallel_sections_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 100 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -ferror-limit 100 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -ferror-limit 100 -o - %s void foo() { } Index: test/OpenMP/parallel_sections_shared_messages.cpp =================================================================== --- test/OpenMP/parallel_sections_shared_messages.cpp +++ test/OpenMP/parallel_sections_shared_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 %s void foo() { } Index: test/OpenMP/parallel_shared_messages.cpp =================================================================== --- test/OpenMP/parallel_shared_messages.cpp +++ test/OpenMP/parallel_shared_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 %s void foo() { } Index: test/OpenMP/sections_lastprivate_messages.cpp =================================================================== --- test/OpenMP/sections_lastprivate_messages.cpp +++ test/OpenMP/sections_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/sections_reduction_messages.cpp =================================================================== --- test/OpenMP/sections_reduction_messages.cpp +++ test/OpenMP/sections_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -ferror-limit 150 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -ferror-limit 150 -o - %s void foo() { } Index: test/OpenMP/simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/simd_lastprivate_messages.cpp +++ test/OpenMP/simd_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/simd_reduction_messages.cpp =================================================================== --- test/OpenMP/simd_reduction_messages.cpp +++ test/OpenMP/simd_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 %s void foo() { } Index: test/OpenMP/single_copyprivate_messages.cpp =================================================================== --- test/OpenMP/single_copyprivate_messages.cpp +++ test/OpenMP/single_copyprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/target_map_messages.cpp =================================================================== --- test/OpenMP/target_map_messages.cpp +++ test/OpenMP/target_map_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 %s void foo() { } @@ -97,7 +97,7 @@ #pragma omp target map(to, x) foo(); #pragma omp target map(to x) // expected-error {{expected ',' or ')' in 'map' clause}} -#pragma omp target map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected variable name, array element or array section}} +#pragma omp target map(tofrom: argc > 0 ? x : y) // expected-error 2 {{expected variable name, array element or array section}} #pragma omp target map(argc) #pragma omp target map(S1) // expected-error {{'S1' does not refer to a value}} #pragma omp target map(a, b, c, d, f) // expected-error {{incomplete type 'S1' where a complete type is required}} expected-error 2 {{type 'S2' is not mappable to target}} Index: test/OpenMP/task_shared_messages.cpp =================================================================== --- test/OpenMP/task_shared_messages.cpp +++ test/OpenMP/task_shared_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -ferror-limit 100 %s void foo() { } Index: test/OpenMP/taskloop_firstprivate_messages.cpp =================================================================== --- test/OpenMP/taskloop_firstprivate_messages.cpp +++ test/OpenMP/taskloop_firstprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/taskloop_lastprivate_messages.cpp =================================================================== --- test/OpenMP/taskloop_lastprivate_messages.cpp +++ test/OpenMP/taskloop_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/taskloop_simd_firstprivate_messages.cpp =================================================================== --- test/OpenMP/taskloop_simd_firstprivate_messages.cpp +++ test/OpenMP/taskloop_simd_firstprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/taskloop_simd_lastprivate_messages.cpp =================================================================== --- test/OpenMP/taskloop_simd_lastprivate_messages.cpp +++ test/OpenMP/taskloop_simd_lastprivate_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/OpenMP/teams_reduction_messages.cpp =================================================================== --- test/OpenMP/teams_reduction_messages.cpp +++ test/OpenMP/teams_reduction_messages.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -verify -fopenmp -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -o - %s -// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++98 -o - %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp -std=c++11 -o - %s void foo() { } Index: test/OpenMP/teams_shared_messages.cpp =================================================================== --- test/OpenMP/teams_shared_messages.cpp +++ test/OpenMP/teams_shared_messages.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -fopenmp %s +// RUN: %clang_cc1 -verify -Wno-non-idiomatic-copy-move -fopenmp %s void foo() { } Index: test/Parser/cxx0x-ambig.cpp =================================================================== --- test/Parser/cxx0x-ambig.cpp +++ test/Parser/cxx0x-ambig.cpp @@ -38,7 +38,7 @@ constexpr T() {} constexpr T(int) {} constexpr T(T, T, T, T) {} - constexpr T operator=(T) const { return *this; } + constexpr T operator=(T) const { return *this; } // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} constexpr operator int() const { return 4; } }; constexpr T a, b, c, d; Index: test/SemaCUDA/implicit-copy.cu =================================================================== --- test/SemaCUDA/implicit-copy.cu +++ test/SemaCUDA/implicit-copy.cu @@ -2,10 +2,10 @@ // RUN: %clang_cc1 -std=gnu++11 -triple nvptx64-unknown-unknown -fcuda-is-device -fsyntax-only -verify %s struct CopyableH { - const CopyableH& operator=(const CopyableH& x) { return *this; } + const CopyableH& operator=(const CopyableH& x) { return *this; } // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} }; struct CopyableD { - __attribute__((device)) const CopyableD& operator=(const CopyableD x) { return *this; } + __attribute__((device)) const CopyableD& operator=(const CopyableD x) { return *this; } // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} }; struct SimpleH { Index: test/SemaCUDA/implicit-member-target.cu =================================================================== --- test/SemaCUDA/implicit-member-target.cu +++ test/SemaCUDA/implicit-member-target.cu @@ -98,7 +98,7 @@ struct A5_copy_ctor_constness { __host__ A5_copy_ctor_constness() {} - __host__ A5_copy_ctor_constness(A5_copy_ctor_constness&) {} + __host__ A5_copy_ctor_constness(A5_copy_ctor_constness&) {} // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct B5_copy_ctor_constness : A5_copy_ctor_constness { Index: test/SemaCXX/MicrosoftCompatibility.cpp =================================================================== --- test/SemaCXX/MicrosoftCompatibility.cpp +++ test/SemaCXX/MicrosoftCompatibility.cpp @@ -77,7 +77,7 @@ } } - + void exception_jump() { goto l2; // expected-error {{cannot jump}} try { // expected-note {{jump bypasses initialization of try block}} @@ -93,13 +93,13 @@ a0: return 0; } - + } namespace PR11826 { struct pair { pair(int v) { } - void operator=(pair&& rhs) { } + pair& operator=(pair&& rhs) { return *this; } }; void f() { pair p0(3); @@ -122,12 +122,12 @@ namespace ms_using_declaration_bug { class A { -public: - int f(); +public: + int f(); }; class B : public A { -private: +private: using A::f; void g() { f(); // no diagnostic @@ -134,8 +134,8 @@ } }; -class C : public B { -private: +class C : public B { +private: using B::f; // expected-warning {{using declaration referring to inaccessible member 'ms_using_declaration_bug::B::f' (which refers to accessible member 'ms_using_declaration_bug::A::f') is a Microsoft compatibility extension}} }; Index: test/SemaCXX/conditional-expr.cpp =================================================================== --- test/SemaCXX/conditional-expr.cpp +++ test/SemaCXX/conditional-expr.cpp @@ -8,9 +8,9 @@ struct B; struct A { - A(); + A(); A(const B&); // expected-note 2 {{candidate constructor}} -}; +}; struct B { operator A() const; }; // expected-note 2 {{candidate function}} struct I { operator int(); }; struct J { operator I(); }; @@ -197,8 +197,8 @@ (void)&(i1 ? flds.b1 : flds.i1); // expected-error {{address of bit-field requested}} (void)&(i1 ? flds.i1 : flds.b1); // expected-error {{address of bit-field requested}} - + unsigned long test0 = 5; test0 = test0 ? (long) test0 : test0; // expected-warning {{operand of ? changes signedness: 'long' to 'unsigned long'}} test0 = test0 ? (int) test0 : test0; // expected-warning {{operand of ? changes signedness: 'int' to 'unsigned long'}} @@ -263,7 +263,8 @@ struct Foo3 { Foo3(); - Foo3(Foo3&); // expected-note{{would lose const qualifier}} + Foo3(Foo3&); // expected-note{{would lose const qualifier}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct Bar { @@ -297,8 +298,9 @@ } namespace rdar7998817 { - class X { - X(X&); // expected-note{{declared private here}} + class X { + X(X&); // expected-note{{declared private here}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} struct ref { }; @@ -305,7 +307,7 @@ public: X(); X(ref); - + operator ref(); }; Index: test/SemaCXX/conversion-function.cpp =================================================================== --- test/SemaCXX/conversion-function.cpp +++ test/SemaCXX/conversion-function.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -verify %s -class X { +// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -Wbind-to-temporary-copy -Wno-non-idiomatic-copy-move -verify %s +class X { public: operator bool(); operator int() const; @@ -28,11 +28,11 @@ // expected-error{{conversion function cannot have any parameters}} operator bool(int a = 4, int b = 6) const; // expected-error{{conversion function cannot have any parameters}} - - + + operator float(...) const; // expected-error{{conversion function cannot be variadic}} - - + + operator func_type(); // expected-error{{conversion function cannot convert to a function type}} operator array_type(); // expected-error{{conversion function cannot convert to an array type}} }; @@ -41,10 +41,10 @@ typedef int INT; typedef INT* INT_PTR; -class Z { +class Z { operator int(); // expected-note {{previous declaration is here}} operator int**(); // expected-note {{previous declaration is here}} - + operator INT(); // expected-error{{conversion function cannot be redeclared}} operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}} }; @@ -82,12 +82,12 @@ } // Test. Conversion in base class is visible in derived class. -class XB { +class XB { public: operator int(); // expected-note {{candidate function}} }; -class Yb : public XB { +class Yb : public XB { public: operator char(); // expected-note {{candidate function}} }; @@ -103,11 +103,11 @@ class AutoPtr { AutoPtr(AutoPtr &); // expected-note{{declared private here}} - + public: AutoPtr(); AutoPtr(AutoPtrRef); - + operator AutoPtrRef(); }; @@ -115,11 +115,11 @@ AutoPtr test_auto_ptr(bool Cond) { AutoPtr p1( make_auto_ptr() ); - + AutoPtr p; if (Cond) return p; // expected-error{{calling a private constructor}} - + return AutoPtr(); } @@ -159,7 +159,7 @@ const A &caf2 = E(); } - // Check + // Check template struct E2 { operator T @@ -180,7 +180,7 @@ } namespace smart_ptr { - class Y { + class Y { class YRef { }; Y(Y&); @@ -210,7 +210,7 @@ }; struct Other { - Other(const Other &); + Other(const Other &); Other(); }; @@ -248,7 +248,7 @@ struct Y { Y(X); }; - + Y f2(foo()); } @@ -298,7 +298,7 @@ struct Derived2 : Base { }; - struct SuperDerived : Derived1, Derived2 { + struct SuperDerived : Derived1, Derived2 { using Derived1::operator int; }; @@ -318,7 +318,7 @@ operator int(); }; - struct Derived23 : Base2, Base3 { + struct Derived23 : Base2, Base3 { using Base2::operator int; }; @@ -363,7 +363,7 @@ { template operator Container() - { + { Container ar; T* i; ar[0]=*i; Index: test/SemaCXX/copy-assignment.cpp =================================================================== --- test/SemaCXX/copy-assignment.cpp +++ test/SemaCXX/copy-assignment.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s struct A { }; @@ -11,7 +11,8 @@ }; struct B { - B& operator=(B&); // expected-note 4 {{candidate function}} + B& operator=(B&); // expected-note 4 {{candidate function}} \ + // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; struct ConvertibleToB { Index: test/SemaCXX/copy-initialization.cpp =================================================================== --- test/SemaCXX/copy-initialization.cpp +++ test/SemaCXX/copy-initialization.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s @@ -31,7 +31,8 @@ namespace PR6757 { struct Foo { Foo(); - Foo(Foo&); // expected-note{{candidate constructor not viable}} + Foo(Foo&); // expected-note{{candidate constructor not viable}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct Bar { Index: test/SemaCXX/coroutines.cpp =================================================================== --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -135,7 +135,7 @@ co_return 0; // expected-error {{'co_return' cannot be used in a destructor}} } // FIXME: The spec says this is ill-formed. - void operator=(CtorDtor&) { + void operator=(CtorDtor&) { // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} co_yield 0; } }; Index: test/SemaCXX/cxx0x-cursory-default-delete.cpp =================================================================== --- test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wno-non-idiomatic-copy-move -verify %s struct non_copiable { non_copiable(const non_copiable&) = delete; // expected-note {{marked deleted here}} Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -175,7 +175,7 @@ template X(std::initializer_list, T); }; - + X x({}, 17); } @@ -216,7 +216,7 @@ struct X { X(int i) {} X(const X& x) = delete; // expected-note {{here}} - void operator=(const X& x) = delete; + X& operator=(const X& x) = delete; }; std::initializer_list x{1}; // expected-error {{invokes deleted constructor}} Index: test/SemaCXX/cxx98-compat-flags.cpp =================================================================== --- test/SemaCXX/cxx98-compat-flags.cpp +++ test/SemaCXX/cxx98-compat-flags.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Werror %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-non-idiomatic-copy-move -Werror %s template int TemplateFn(T) { return 0; } void LocalTemplateArg() { @@ -17,7 +17,8 @@ }; struct NoViable { NoViable(); - NoViable(NoViable&); // expected-note {{not viable}} + NoViable(NoViable&); // expected-note {{not viable}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct Ambiguous { Ambiguous(); Index: test/SemaCXX/cxx98-compat-pedantic.cpp =================================================================== --- test/SemaCXX/cxx98-compat-pedantic.cpp +++ test/SemaCXX/cxx98-compat-pedantic.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat-pedantic -verify %s -DCXX1Y2 -// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror %s -DCXX1Y2 +// RUN: %clang_cc1 -fsyntax-only -std=c++1y -DCXX1Y -Wc++98-compat -Werror -Wno-non-idiomatic-copy-move %s -DCXX1Y2 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat-pedantic -verify %s -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror %s -// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror %s -DCXX98 +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wc++98-compat -Werror -Wno-non-idiomatic-copy-move %s +// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Werror -Wno-non-idiomatic-copy-move %s -DCXX98 // RUN: %clang_cc1 -fsyntax-only -std=c++1y -Wc++98-compat-pedantic -verify %s -Wno-c++98-c++11-compat-pedantic -DCXX1Y2 @@ -60,7 +60,8 @@ }; struct NoViable { NoViable(); - NoViable(NoViable&); // expected-note {{not viable}} + NoViable(NoViable&); // expected-note {{not viable}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct Ambiguous { Ambiguous(); Index: test/SemaCXX/cxx98-compat.cpp =================================================================== --- test/SemaCXX/cxx98-compat.cpp +++ test/SemaCXX/cxx98-compat.cpp @@ -330,7 +330,7 @@ }; struct b { - void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}} + b& operator=(const b &it) { return *this; } // expected-note {{because type 'AssignOpUnion::b' has a user-provided copy assignment operator}} }; union test1 { Index: test/SemaCXX/default-assignment-operator.cpp =================================================================== --- test/SemaCXX/default-assignment-operator.cpp +++ test/SemaCXX/default-assignment-operator.cpp @@ -8,18 +8,18 @@ class X : Base { // // expected-error {{cannot define the implicit copy assignment operator for 'X', because non-static const member 'cint' cannot use copy assignment operator}} \ // expected-note{{assignment operator for 'Base' first required here}} -public: +public: X(); const int cint; // expected-note {{declared here}} -}; +}; -struct Y : X { +struct Y : X { Y(); Y& operator=(const Y&); Y& operator=(volatile Y&); Y& operator=(const volatile Y&); Y& operator=(Y&); -}; +}; class Z : Y {}; @@ -46,7 +46,7 @@ class V { public: V(); - V &operator = (V &b); + V &operator = (V &b); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; class W : V {}; @@ -61,7 +61,7 @@ class B1 { public: B1(); - B1 &operator = (B1 b); + B1 &operator = (B1 b); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} }; class D1 : B1 {}; @@ -77,7 +77,7 @@ public: const int a; // expected-note{{declared here}} - E1() : a(0) {} + E1() : a(0) {} }; @@ -106,7 +106,7 @@ } namespace MultiplePaths { - struct X0 { + struct X0 { X0 &operator=(const X0&); }; Index: test/SemaCXX/lambda-expressions.cpp =================================================================== --- test/SemaCXX/lambda-expressions.cpp +++ test/SemaCXX/lambda-expressions.cpp @@ -75,7 +75,8 @@ (void) ^{ return []() { return f[2]; }; }; // expected-error {{variable 'f' cannot be implicitly captured in a lambda with no capture-default specified}} \ // expected-note{{lambda expression begins here}} - struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}} + struct G { G(); G(G&); int a; }; // expected-note 6 {{not viable}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} G g; [=]() { const G* gg = &g; return gg->a; }; [=]() { return [=]{ const G* gg = &g; return gg->a; }(); }; // expected-error {{no matching constructor for initialization of 'G'}} @@ -269,16 +270,16 @@ template struct L { T t{}; - T t2 = ([](int a) { return [](int b) { return b; };})(t)(t); + T t2 = ([](int a) { return [](int b) { return b; };})(t)(t); }; - L l; - + L l; + namespace non_template { struct L { int t = 0; - int t2 = ([](int a) { return [](int b) { return b; };})(t)(t); + int t2 = ([](int a) { return [](int b) { return b; };})(t)(t); }; - L l; + L l; } } Index: test/SemaCXX/overload-call-copycon.cpp =================================================================== --- test/SemaCXX/overload-call-copycon.cpp +++ test/SemaCXX/overload-call-copycon.cpp @@ -20,7 +20,8 @@ class A { public: A(A&); // expected-note{{would lose const qualifier}} \ - // expected-note{{no known conversion}} + // expected-note{{no known conversion}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; class B : public A { }; // expected-note{{would lose const qualifier}} \ Index: test/SemaCXX/static-cast.cpp =================================================================== --- test/SemaCXX/static-cast.cpp +++ test/SemaCXX/static-cast.cpp @@ -157,9 +157,9 @@ struct X1 { X1(); - X1(X1&); + X1(const X1&); X1(const X0&); - + operator X0() const; }; @@ -178,11 +178,11 @@ struct X4 { typedef const X3 X3_typedef; - + void f() const { (void)static_cast(x2); } - + const X2 *x2; }; @@ -190,7 +190,7 @@ void PR5897() { (void)static_cast((const void*)0); } namespace PR6072 { - struct A { }; + struct A { }; struct B : A { void f(int); void f(); }; // expected-note 2{{candidate function}} struct C : B { }; struct D { }; Index: test/SemaCXX/type-traits.cpp =================================================================== --- test/SemaCXX/type-traits.cpp +++ test/SemaCXX/type-traits.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft -Wno-non-idiomatic-copy-move %s #define T(b) (b) ? 1 : -1 #define F(b) (b) ? -1 : 1 @@ -40,17 +40,17 @@ struct HasCons { HasCons(int); }; struct HasCopyAssign { HasCopyAssign operator =(const HasCopyAssign&); }; struct HasMoveAssign { HasMoveAssign operator =(const HasMoveAssign&&); }; -struct HasNoThrowMoveAssign { +struct HasNoThrowMoveAssign { HasNoThrowMoveAssign& operator=( const HasNoThrowMoveAssign&&) throw(); }; -struct HasNoExceptNoThrowMoveAssign { +struct HasNoExceptNoThrowMoveAssign { HasNoExceptNoThrowMoveAssign& operator=( - const HasNoExceptNoThrowMoveAssign&&) noexcept; + const HasNoExceptNoThrowMoveAssign&&) noexcept; }; -struct HasThrowMoveAssign { +struct HasThrowMoveAssign { HasThrowMoveAssign& operator=( const HasThrowMoveAssign&&) throw(POD); }; -struct HasNoExceptFalseMoveAssign { +struct HasNoExceptFalseMoveAssign { HasNoExceptFalseMoveAssign& operator=( const HasNoExceptFalseMoveAssign&&) noexcept(false); }; struct HasMoveCtor { HasMoveCtor(const HasMoveCtor&&); }; @@ -59,17 +59,17 @@ struct HasStaticMemberMoveCtor { static HasMoveCtor member; }; struct HasStaticMemberMoveAssign { static HasMoveAssign member; }; struct HasMemberThrowMoveAssign { HasThrowMoveAssign member; }; -struct HasMemberNoExceptFalseMoveAssign { +struct HasMemberNoExceptFalseMoveAssign { HasNoExceptFalseMoveAssign member; }; struct HasMemberNoThrowMoveAssign { HasNoThrowMoveAssign member; }; -struct HasMemberNoExceptNoThrowMoveAssign { +struct HasMemberNoExceptNoThrowMoveAssign { HasNoExceptNoThrowMoveAssign member; }; -struct HasDefaultTrivialCopyAssign { +struct HasDefaultTrivialCopyAssign { HasDefaultTrivialCopyAssign &operator=( - const HasDefaultTrivialCopyAssign&) = default; + const HasDefaultTrivialCopyAssign&) = default; }; -struct TrivialMoveButNotCopy { +struct TrivialMoveButNotCopy { TrivialMoveButNotCopy &operator=(TrivialMoveButNotCopy&&) = default; TrivialMoveButNotCopy &operator=(const TrivialMoveButNotCopy&); }; @@ -306,7 +306,7 @@ struct FinalClass final { }; -template +template struct PotentiallyFinal { }; template @@ -1329,7 +1329,7 @@ { int arr[T(__has_trivial_move_constructor(HasCons))]; } { int arr[T(__has_trivial_move_constructor(HasStaticMemberMoveCtor))]; } { int arr[T(__has_trivial_move_constructor(AllDeleted))]; } - + { int arr[F(__has_trivial_move_constructor(HasVirt))]; } { int arr[F(__has_trivial_move_constructor(DerivesVirt))]; } { int arr[F(__has_trivial_move_constructor(HasMoveCtor))]; } @@ -1762,7 +1762,7 @@ }; template -struct X0 { +struct X0 { template X0(const X0&); }; Index: test/SemaCXX/user-defined-conversions.cpp =================================================================== --- test/SemaCXX/user-defined-conversions.cpp +++ test/SemaCXX/user-defined-conversions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -verify %s struct X { operator bool(); }; @@ -39,7 +39,7 @@ // Test conversion followed by copy-construction struct FunkyDerived; -struct Base { +struct Base { Base(const FunkyDerived&); }; @@ -69,7 +69,8 @@ } struct X1 { - X1(X1&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} + X1(X1&); // expected-note{{candidate constructor not viable: expects an l-value for 1st argument}} \ + // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} }; struct X2 { Index: test/SemaCXX/warn-consumed-analysis.cpp =================================================================== --- test/SemaCXX/warn-consumed-analysis.cpp +++ test/SemaCXX/warn-consumed-analysis.cpp @@ -14,37 +14,37 @@ template class CONSUMABLE(unconsumed) ConsumableClass { T var; - + public: ConsumableClass(); ConsumableClass(nullptr_t p) RETURN_TYPESTATE(consumed); ConsumableClass(T val) RETURN_TYPESTATE(unconsumed); - ConsumableClass(ConsumableClass &other); + ConsumableClass(const ConsumableClass &other); ConsumableClass(ConsumableClass &&other); - - ConsumableClass& operator=(ConsumableClass &other); + + ConsumableClass& operator=(const ConsumableClass &other); ConsumableClass& operator=(ConsumableClass &&other); ConsumableClass& operator=(nullptr_t) SET_TYPESTATE(consumed); - + template ConsumableClass& operator=(ConsumableClass &other); - + template ConsumableClass& operator=(ConsumableClass &&other); - + void operator()(int a) SET_TYPESTATE(consumed); void operator*() const CALLABLE_WHEN("unconsumed"); void unconsumedCall() const CALLABLE_WHEN("unconsumed"); void callableWhenUnknown() const CALLABLE_WHEN("unconsumed", "unknown"); - + bool isValid() const TEST_TYPESTATE(unconsumed); operator bool() const TEST_TYPESTATE(unconsumed); bool operator!=(nullptr_t) const TEST_TYPESTATE(unconsumed); bool operator==(nullptr_t) const TEST_TYPESTATE(consumed); - + void constCall() const; void nonconstCall(); - + void consume() SET_TYPESTATE(consumed); void unconsume() SET_TYPESTATE(unconsumed); }; @@ -53,9 +53,9 @@ public: DestructorTester(); DestructorTester(int); - + void operator*() CALLABLE_WHEN("unconsumed"); - + ~DestructorTester() CALLABLE_WHEN("consumed"); }; @@ -94,14 +94,14 @@ var0 = ConsumableClass(42); *var0; - + var0 = var1; *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} - + if (var0.isValid()) { *var0; *var1; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} } @@ -109,13 +109,13 @@ void testDestruction() { DestructorTester D0(42), D1(42), D2; - + *D0; *D1; *D2; // expected-warning {{invalid invocation of method 'operator*' on object 'D2' while it is in the 'consumed' state}} - + D0.~DestructorTester(); // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} - + return; // expected-warning {{invalid invocation of method '~DestructorTester' on object 'D0' while it is in the 'unconsumed' state}} \ expected-warning {{invalid invocation of method '~DestructorTester' on object 'D1' while it is in the 'unconsumed' state}} } @@ -127,12 +127,12 @@ void testSimpleRValueRefs() { ConsumableClass var0; ConsumableClass var1(42); - + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; - + var0 = static_cast&&>(var1); - + *var0; *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } @@ -139,31 +139,31 @@ void testIfStmt() { ConsumableClass var; - + if (var.isValid()) { *var; } else { *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } - + if (!var.isValid()) { *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } else { *var; } - + if (var) { // Empty } else { *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } - + if (var != nullptr) { // Empty } else { *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } - + if (var == nullptr) { *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } else { @@ -173,90 +173,90 @@ void testComplexConditionals0() { ConsumableClass var0, var1, var2; - + if (var0 && var1) { *var0; *var1; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + if (var0 || var1) { *var0; *var1; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + if (var0 && !var1) { *var0; *var1; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + if (var0 || !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; *var1; } - + if (!var0 && !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; *var1; } - + if (!var0 || !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; *var1; } - + if (!(var0 && var1)) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; *var1; } - + if (!(var0 || var1)) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; *var1; } - + if (var0 && var1 && var2) { *var0; *var1; *var2; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'consumed' state}} } - + #if 0 // FIXME: Get this test to pass. if (var0 || var1 || var2) { @@ -263,7 +263,7 @@ *var0; *var1; *var2; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} @@ -274,95 +274,95 @@ void testComplexConditionals1() { ConsumableClass var0, var1, var2; - + // Coerce all variables into the unknown state. baf4(var0); baf4(var1); baf4(var2); - + if (var0 && var1) { *var0; *var1; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} } - + if (var0 || var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + if (var0 && !var1) { *var0; *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} } - + if (var0 || !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; } - + if (!var0 && !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} } - + if (!(var0 || var1)) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} } - + if (!var0 || !var1) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} - + } else { *var0; *var1; } - + if (!(var0 && var1)) { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} - + } else { *var0; *var1; } - + if (var0 && var1 && var2) { *var0; *var1; *var2; - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} } - + #if 0 // FIXME: Get this test to pass. if (var0 || var1 || var2) { @@ -369,7 +369,7 @@ *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'unknown' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'unknown' state}} *var2; // expected-warning {{invalid invocation of method 'operator*' on object 'var2' while it is in the 'unknown' state}} - + } else { *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} @@ -380,50 +380,50 @@ void testStateChangeInBranch() { ConsumableClass var; - + // Make var enter the 'unknown' state. baf4(var); - + if (!var) { var = ConsumableClass(42); } - + *var; } void testFunctionParam(ConsumableClass param) { - + if (param.isValid()) { *param; } else { *param; } - + param = nullptr; *param; // expected-warning {{invocation of method 'operator*' on object 'param' while it is in the 'consumed' state}} } void testParamReturnTypestateCallee(bool cond, ConsumableClass &Param RETURN_TYPESTATE(unconsumed)) { // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}} - + if (cond) { Param.consume(); return; // expected-warning {{parameter 'Param' not in expected state when the function returns: expected 'unconsumed', observed 'consumed'}} } - + Param.consume(); } void testParamReturnTypestateCaller() { ConsumableClass var; - + testParamReturnTypestateCallee(true, var); - + *var; } void testParamTypestateCallee(ConsumableClass Param0 PARAM_TYPESTATE(consumed), ConsumableClass &Param1 PARAM_TYPESTATE(consumed)) { - + *Param0; // expected-warning {{invalid invocation of method 'operator*' on object 'Param0' while it is in the 'consumed' state}} *Param1; // expected-warning {{invalid invocation of method 'operator*' on object 'Param1' while it is in the 'consumed' state}} } @@ -430,7 +430,7 @@ void testParamTypestateCaller() { ConsumableClass Var0, Var1(42); - + testParamTypestateCallee(Var0, Var1); // expected-warning {{argument not in expected state; expected 'consumed', observed 'unconsumed'}} } @@ -471,34 +471,34 @@ void testCallingConventions() { ConsumableClass var(42); - - baf0(var); + + baf0(var); *var; - - baf1(var); + + baf1(var); *var; - - baf2(&var); + + baf2(&var); *var; - - baf4(var); + + baf4(var); *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} - + var = ConsumableClass(42); - baf5(&var); + baf5(&var); *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'unknown' state}} - + var = ConsumableClass(42); - baf6(static_cast&&>(var)); + baf6(static_cast&&>(var)); *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } void testConstAndNonConstMemberFunctions() { ConsumableClass var(42); - + var.constCall(); *var; - + var.nonconstCall(); *var; } @@ -513,10 +513,10 @@ void testReturnStates() { ConsumableClass var; - + var = returnsUnconsumed(); *var; - + var = returnsConsumed(); *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } @@ -523,11 +523,11 @@ void testCallableWhen() { ConsumableClass var(42); - + *var; - + baf4(var); - + var.callableWhenUnknown(); } @@ -534,15 +534,15 @@ void testMoveAsignmentish() { ConsumableClass var0; ConsumableClass var1(42); - + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} *var1; - + var0 = static_cast&&>(var1); - + *var0; *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} - + var1 = ConsumableClass(42); var1 = nullptr; *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} @@ -550,60 +550,60 @@ void testConditionalMerge() { ConsumableClass var; - + if (var.isValid()) { // Empty } - + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} - + if (var.isValid()) { // Empty } else { // Empty } - + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } void testSetTypestate() { ConsumableClass var(42); - + *var; - + var.consume(); - + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} - + var.unconsume(); - + *var; } void testConsumes0() { ConsumableClass var(nullptr); - + *var; // expected-warning {{invalid invocation of method 'operator*' on object 'var' while it is in the 'consumed' state}} } void testConsumes1() { ConsumableClass var(42); - + var.unconsumedCall(); var(6); - + var.unconsumedCall(); // expected-warning {{invalid invocation of method 'unconsumedCall' on object 'var' while it is in the 'consumed' state}} } void testUnreachableBlock() { ConsumableClass var(42); - + if (var) { *var; } else { *var; } - + *var; } @@ -610,31 +610,31 @@ void testForLoop1() { ConsumableClass var0, var1(42); - + for (int i = 0; i < 10; ++i) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} - + *var1; var1.consume(); *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} } void testWhileLoop1() { int i = 10; - + ConsumableClass var0, var1(42); - + while (i-- > 0) { // expected-warning {{state of variable 'var1' must match at the entry and exit of loop}} *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} - + *var1; var1.consume(); *var1; // expected-warning {{invalid invocation of method 'operator*' on object 'var1' while it is in the 'consumed' state}} } - + *var0; // expected-warning {{invalid invocation of method 'operator*' on object 'var0' while it is in the 'consumed' state}} } @@ -801,7 +801,7 @@ void testTemporariesWithConditionals1() { int a; - + Status s = doSomething(); if (cond()) a = 0; else a = 1; @@ -810,7 +810,7 @@ void testTemporariesWithConditionals2() { int a; - + Status s = doSomething(); s.ignore(); if (cond()) a = 0; Index: test/SemaCXX/warn-non-idiomatic-copy-move.cpp =================================================================== --- test/SemaCXX/warn-non-idiomatic-copy-move.cpp +++ test/SemaCXX/warn-non-idiomatic-copy-move.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++14 -verify %s + +struct A1 { + A1(A1&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} + A1& operator=(A1&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} +}; + +struct A2 { + A2(volatile A2&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} + A2& operator=(volatile A2&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} +}; + +struct A3 { + A3(const volatile A3&); // expected-warning {{non-idiomatic copy constructor declaration; consider 'const T&' instead}} + A3& operator=(const volatile A3&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} +}; + +struct A4 { + A4(const A4&); // ok + A4& operator=(const A4&); // ok +}; + +struct A5 { + A5(const A5&&); // expected-warning {{non-idiomatic move constructor declaration; consider 'T&&' instead}} + A5& operator=(const A5&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider 'T&&' instead}} +}; + +struct A6 { + A6(volatile A6&&); // expected-warning {{non-idiomatic move constructor declaration; consider 'T&&' instead}} + A6& operator=(volatile A6&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider 'T&&' instead}} +}; + +struct A7 { + A7(const volatile A7&&); // expected-warning {{non-idiomatic move constructor declaration; consider 'T&&' instead}} + A7& operator=(const volatile A7&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider 'T&&' instead}} +}; + +struct A8 { + A8(A8&&); // ok + A8& operator=(A8&&); // ok +}; + +struct A9 { + A9& operator=(A9); // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} +}; + +struct B { + B&& operator=(const B&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} + B&& operator=(B&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider returning 'T&' instead}} +}; + +struct C { + C operator=(const C&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} + C operator=(C&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider returning 'T&' instead}} +}; + +struct D { + C& operator=(const D&); // expected-warning {{non-idiomatic copy assignment operator declaration; consider returning 'T&' instead}} + C& operator=(D&&); // expected-warning {{non-idiomatic move assignment operator declaration; consider returning 'T&' instead}} +}; + +struct E { + E& operator=(const E&) &; // expected-warning {{non-idiomatic copy assignment operator declaration; consider removing ref-qualifiers instead}} + E& operator=(E&&) &; // expected-warning {{non-idiomatic move assignment operator declaration; consider removing ref-qualifiers instead}} +}; + +struct F { + F& operator=(F&) = default; // expected-warning {{non-idiomatic copy assignment operator declaration; consider 'const T&' instead}} + F& operator=(const F&&) = delete; // expected-warning {{non-idiomatic move assignment operator declaration; consider 'T&&' instead}} +}; + +struct G { + // Do not diagnose if the declaration is invalid anyway. + auto operator=(const G&) = default; // expected-error {{must return 'G &'}} +}; + +struct H { + // Do not diagnose non-idiomatic copy/move operations in the presence of + // idiomatic ones. + H(H&); // ok + H(const H&); // ok + + H(const H&&); // ok + H(H&&); // ok + + H& operator=(H&) &; // ok + H& operator=(const H&); // ok + + H& operator=(const volatile H&&) &&; // ok + H& operator=(H&&); // ok +}; + +struct I { + // Do not diagnose things that are not copy or move operations, but are + // instead converting operations. + I(int); // ok + I(int&); // ok + I(int&&); // ok + I(H&); // ok + + I& operator=(int); // ok + I& operator=(int&); // ok + I& operator=(int&&); // ok + I& operator=(H&); // ok + I& operator=(H&&); // ok +}; + +struct K { + // Do not diagnose non-idiomatic operations in the presence of other non- + // idiomatic operations of the same type. + K(K&); // ok + K(volatile K&); // ok + + K(const K&&); // ok + K(volatile K&&); // ok + + K& operator=(const K&) &; // ok + K& operator=(K&); // ok + + K operator=(K&&); // ok + K& operator=(const K&&); // ok +}; + +struct L { + // Do not diagnose as non-idiomatic if the constructor uses default arguments; + // TODO: that should be diagnosed differently. + L(L&, int = 0); // ok + L(const L&&, int = 0); // ok +}; Index: test/SemaCXX/warn-unused-filescoped.cpp =================================================================== --- test/SemaCXX/warn-unused-filescoped.cpp +++ test/SemaCXX/warn-unused-filescoped.cpp @@ -55,7 +55,7 @@ void m2(); // expected-warning{{unused}} void m3(); S(const S&); - void operator=(const S&); + S& operator=(const S&); }; template @@ -67,11 +67,11 @@ template void tf() { } template <> void tf() { } // expected-warning{{unused}} - + struct VS { virtual void vm() { } }; - + struct SVS : public VS { void vm() { } }; @@ -88,7 +88,7 @@ namespace { int x2; // expected-warning{{unused}} - + struct S2 { static int x; // expected-warning{{unused}} }; Index: test/SemaObjCXX/property-synthesis-error.mm =================================================================== --- test/SemaObjCXX/property-synthesis-error.mm +++ test/SemaObjCXX/property-synthesis-error.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class -Wno-non-idiomatic-copy-move %s // rdar: //8550657 @interface NSArray @end Index: test/SemaTemplate/constructor-template.cpp =================================================================== --- test/SemaTemplate/constructor-template.cpp +++ test/SemaTemplate/constructor-template.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// RUN: %clang_cc1 -fsyntax-only -Wno-non-idiomatic-copy-move -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-non-idiomatic-copy-move -verify -std=c++98 %s +// RUN: %clang_cc1 -fsyntax-only -Wno-non-idiomatic-copy-move -verify -std=c++11 %s struct X0 { // expected-note {{candidate constructor (the implicit copy constructor) not viable}} #if __cplusplus >= 201103L // C++11 or later @@ -9,7 +9,7 @@ X0(int); // expected-note{{candidate}} template X0(T); // expected-note {{candidate}} template X0(T*, U*); // expected-note {{candidate}} - + // PR4761 template X0() : f0(T::foo) {} // expected-note {{candidate}} int f0; @@ -28,7 +28,7 @@ accept_X0(&f); X0 x0e(&i, &f); X0 x0f(&f, &i); - + X0 x0g(f, &i); // expected-error{{no matching constructor}} } @@ -41,9 +41,9 @@ template struct Outer { typedef X1 A; - + A alloc; - + explicit Outer(const A& a) : alloc(a) { } }; @@ -66,7 +66,7 @@ X2 test(bool Cond, X2 x2) { if (Cond) return x2; // okay, uses copy constructor - + return X2(); // expected-error{{no matching constructor}} } Index: test/SemaTemplate/instantiate-decl-init.cpp =================================================================== --- test/SemaTemplate/instantiate-decl-init.cpp +++ test/SemaTemplate/instantiate-decl-init.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wno-non-idiomatic-copy-move -verify %s // expected-no-diagnostics // PR5426 - the non-dependent obj would be fully processed and wrapped in a