[Sema] Fix built-in decrement operator overload resolution
C++ [over.built] p4: "For every pair (T, VQ), where T is an arithmetic type other than bool, and VQ is either volatile or empty, there exist candidate operator functions of the form VQ T& operator--(VQ T&); T operator--(VQ T&, int); " The bool type is in position LastPromotedIntegralType in BuiltinOperatorOverloadBuilder::getArithmeticType::ArithmeticTypes, but addPlusPlusMinusMinusArithmeticOverloads() was expecting it at position 0. Differential Revision: https://reviews.llvm.org/D44988 rdar://problem/34255516 llvm-svn: 329804
This commit is contained in:
parent
a70512a958
commit
d74ebe22db
|
@ -7796,10 +7796,12 @@ public:
|
|||
if (!HasArithmeticOrEnumeralCandidateType)
|
||||
return;
|
||||
|
||||
for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
|
||||
Arith < NumArithmeticTypes; ++Arith) {
|
||||
for (unsigned Arith = 0; Arith < NumArithmeticTypes; ++Arith) {
|
||||
const auto TypeOfT = ArithmeticTypes[Arith];
|
||||
if (Op == OO_MinusMinus && TypeOfT == S.Context.BoolTy)
|
||||
continue;
|
||||
addPlusPlusMinusMinusStyleOverloads(
|
||||
ArithmeticTypes[Arith],
|
||||
TypeOfT,
|
||||
VisibleTypeConversionsQuals.hasVolatile(),
|
||||
VisibleTypeConversionsQuals.hasRestrict());
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
|
|||
// FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
|
||||
}
|
||||
|
||||
struct BoolRef {
|
||||
operator bool&();
|
||||
};
|
||||
|
||||
struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator) not viable}}
|
||||
#if __cplusplus >= 201103L // C++11 or later
|
||||
// expected-note@-2 {{candidate function (the implicit move assignment operator) not viable}}
|
||||
|
@ -73,6 +77,10 @@ struct LongRef {
|
|||
operator volatile long&();
|
||||
};
|
||||
|
||||
struct FloatRef {
|
||||
operator float&();
|
||||
};
|
||||
|
||||
struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator) not viable}}
|
||||
#if __cplusplus >= 201103L // C++11 or later
|
||||
// expected-note@-2 {{candidate function (the implicit move assignment operator) not viable}}
|
||||
|
@ -84,13 +92,19 @@ struct E2Ref {
|
|||
operator E2&();
|
||||
};
|
||||
|
||||
void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
|
||||
void g(BoolRef br, ShortRef sr, LongRef lr, FloatRef fr, E2Ref e2_ref, XpmfRef pmf_ref) {
|
||||
// C++ [over.built]p3
|
||||
short s1 = sr++;
|
||||
|
||||
// C++ [over.built]p3
|
||||
// C++ [over.built]p4
|
||||
long l1 = lr--;
|
||||
|
||||
// C++ [over.built]p4
|
||||
float f1 = fr--;
|
||||
|
||||
// C++ [over.built]p4
|
||||
bool b2 = br--; // expected-error{{cannot decrement value of type 'BoolRef'}}
|
||||
|
||||
// C++ [over.built]p18
|
||||
short& sr1 = (sr *= lr);
|
||||
volatile long& lr1 = (lr *= sr);
|
||||
|
|
Loading…
Reference in New Issue