forked from OSchip/llvm-project
PR14995: Allow a dependent type as the second parameter of operator++ and
operator--, since it might instantiate as 'int' (or, if it's a pack, it might instantiate as an empty pack). llvm-svn: 200496
This commit is contained in:
parent
0b6c94909e
commit
538b52a2fc
|
@ -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<BuiltinType>())
|
||||
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);
|
||||
|
|
|
@ -452,3 +452,58 @@ namespace PR7681 {
|
|||
Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR14995 {
|
||||
struct B {};
|
||||
template<typename ...T> void operator++(B, T...) {}
|
||||
|
||||
void f() {
|
||||
B b;
|
||||
b++; // ok
|
||||
++b; // ok
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
struct C {
|
||||
void operator-- (T...) {}
|
||||
};
|
||||
|
||||
void g() {
|
||||
C<int> postfix;
|
||||
C<> prefix;
|
||||
postfix--; // ok
|
||||
--prefix; // ok
|
||||
}
|
||||
|
||||
struct D {};
|
||||
template<typename T> void operator++(D, T) {}
|
||||
|
||||
void h() {
|
||||
D d;
|
||||
d++; // ok
|
||||
++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
|
||||
}
|
||||
|
||||
template<typename...T> struct E {
|
||||
void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
|
||||
};
|
||||
|
||||
E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
|
||||
|
||||
struct F {
|
||||
template<typename... T>
|
||||
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++<int, int>' 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++<char>' requested here}}
|
||||
// expected-error@-7 {{no matching member function for call to 'operator++'}}
|
||||
// expected-note@-12 {{candidate template ignored: substitution failure}}
|
||||
} // namespace PR14995
|
||||
|
||||
|
|
Loading…
Reference in New Issue