diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index cde6d9dc7524..9b6407b0b28c 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -10909,11 +10909,10 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) { // increment operator ++ for objects of that type. if ((Op == OO_PlusPlus || Op == OO_MinusMinus) && NumParams == 2) { ParmVarDecl *LastParam = FnDecl->getParamDecl(FnDecl->getNumParams() - 1); - bool ParamIsInt = false; - if (const BuiltinType *BT = LastParam->getType()->getAs()) - ParamIsInt = BT->getKind() == BuiltinType::Int; + QualType ParamType = LastParam->getType(); - if (!ParamIsInt) + if (!ParamType->isSpecificBuiltinType(BuiltinType::Int) && + !ParamType->isDependentType()) return Diag(LastParam->getLocation(), diag::err_operator_overload_post_incdec_must_be_int) << LastParam->getType() << (Op == OO_MinusMinus); diff --git a/clang/test/SemaCXX/overloaded-operator.cpp b/clang/test/SemaCXX/overloaded-operator.cpp index 99105cb5b60b..cd2b2d3e7ae2 100644 --- a/clang/test/SemaCXX/overloaded-operator.cpp +++ b/clang/test/SemaCXX/overloaded-operator.cpp @@ -452,3 +452,58 @@ namespace PR7681 { Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion' is incomplete}} } } + +namespace PR14995 { + struct B {}; + template void operator++(B, T...) {} + + void f() { + B b; + b++; // ok + ++b; // ok + } + + template + struct C { + void operator-- (T...) {} + }; + + void g() { + C postfix; + C<> prefix; + postfix--; // ok + --prefix; // ok + } + + struct D {}; + template void operator++(D, T) {} + + void h() { + D d; + d++; // ok + ++d; // expected-error{{cannot increment value of type 'PR14995::D'}} + } + + template struct E { + void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}} + }; + + E e; // expected-note {{in instantiation of template class 'PR14995::E' requested here}} + + struct F { + template + int operator++ (T...) {} + }; + + int k1 = F().operator++(0, 0); + int k2 = F().operator++('0'); + // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}} + // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++' requested here}} + // expected-error@-4 {{no matching member function for call to 'operator++'}} + // expected-note@-8 {{candidate template ignored: substitution failure}} + // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}} + // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++' requested here}} + // expected-error@-7 {{no matching member function for call to 'operator++'}} + // expected-note@-12 {{candidate template ignored: substitution failure}} +} // namespace PR14995 +