forked from OSchip/llvm-project
Many of the built-in operator candidates introduced into overload
resolution require that the pointed-to type be an object type, but we weren't filtering out non-object types. Do so, fixing PR7851. llvm-svn: 122853
This commit is contained in:
parent
f8a7912633
commit
66990031e2
|
@ -1079,6 +1079,14 @@ public:
|
|||
bool isIncompleteOrObjectType() const {
|
||||
return !isFunctionType();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this type is an object type.
|
||||
bool isObjectType() const {
|
||||
// C++ [basic.types]p8:
|
||||
// An object type is a (possibly cv-qualified) type that is not a
|
||||
// function type, not a reference type, and not a void type.
|
||||
return !isReferenceType() && !isFunctionType() && !isVoidType();
|
||||
}
|
||||
|
||||
/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
|
||||
bool isPODType() const;
|
||||
|
|
|
@ -4821,7 +4821,7 @@ public:
|
|||
PtrEnd = CandidateTypes[0].pointer_end();
|
||||
Ptr != PtrEnd; ++Ptr) {
|
||||
// Skip pointer types that aren't pointers to object types.
|
||||
if (!(*Ptr)->getPointeeType()->isIncompleteOrObjectType())
|
||||
if (!(*Ptr)->getPointeeType()->isObjectType())
|
||||
continue;
|
||||
|
||||
addPlusPlusMinusMinusStyleOverloads(*Ptr,
|
||||
|
@ -4847,6 +4847,9 @@ public:
|
|||
Ptr != PtrEnd; ++Ptr) {
|
||||
QualType ParamTy = *Ptr;
|
||||
QualType PointeeTy = ParamTy->getPointeeType();
|
||||
if (!PointeeTy->isObjectType() && !PointeeTy->isFunctionType())
|
||||
continue;
|
||||
|
||||
S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy),
|
||||
&ParamTy, Args, 1, CandidateSet);
|
||||
}
|
||||
|
@ -5066,6 +5069,10 @@ public:
|
|||
Ptr = CandidateTypes[Arg].pointer_begin(),
|
||||
PtrEnd = CandidateTypes[Arg].pointer_end();
|
||||
Ptr != PtrEnd; ++Ptr) {
|
||||
QualType PointeeTy = (*Ptr)->getPointeeType();
|
||||
if (!PointeeTy->isObjectType())
|
||||
continue;
|
||||
|
||||
AsymetricParamTypes[Arg] = *Ptr;
|
||||
if (Arg == 0 || Op == OO_Plus) {
|
||||
// operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t)
|
||||
|
@ -5251,6 +5258,8 @@ public:
|
|||
// If this is operator=, keep track of the builtin candidates we added.
|
||||
if (isEqualOp)
|
||||
AddedTypes.insert(S.Context.getCanonicalType(*Ptr));
|
||||
else if (!(*Ptr)->getPointeeType()->isObjectType())
|
||||
continue;
|
||||
|
||||
// non-volatile version
|
||||
QualType ParamTypes[2] = {
|
||||
|
@ -5443,6 +5452,9 @@ public:
|
|||
Ptr != PtrEnd; ++Ptr) {
|
||||
QualType ParamTypes[2] = { *Ptr, S.Context.getPointerDiffType() };
|
||||
QualType PointeeType = (*Ptr)->getPointeeType();
|
||||
if (!PointeeType->isObjectType())
|
||||
continue;
|
||||
|
||||
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
|
||||
|
||||
// T& operator[](T*, ptrdiff_t)
|
||||
|
@ -5455,6 +5467,9 @@ public:
|
|||
Ptr != PtrEnd; ++Ptr) {
|
||||
QualType ParamTypes[2] = { S.Context.getPointerDiffType(), *Ptr };
|
||||
QualType PointeeType = (*Ptr)->getPointeeType();
|
||||
if (!PointeeType->isObjectType())
|
||||
continue;
|
||||
|
||||
QualType ResultTy = S.Context.getLValueReferenceType(PointeeType);
|
||||
|
||||
// T& operator[](ptrdiff_t, T*)
|
||||
|
|
|
@ -1515,10 +1515,8 @@ FinishTemplateArgumentDeduction(Sema &S,
|
|||
= ClassTemplate->getTemplateParameters();
|
||||
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
|
||||
TemplateArgument InstArg = ConvertedInstArgs.data()[I];
|
||||
Decl *Param = TemplateParams->getParam(I);
|
||||
|
||||
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg)) {
|
||||
Info.Param = makeTemplateParameter(Param);
|
||||
Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
|
||||
Info.FirstArg = TemplateArgs[I];
|
||||
Info.SecondArg = InstArg;
|
||||
return Sema::TDK_NonDeducedMismatch;
|
||||
|
|
|
@ -220,3 +220,20 @@ namespace PR8477 {
|
|||
return foo[zero] == zero;
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR7851 {
|
||||
struct X {
|
||||
operator const void *() const;
|
||||
operator void *();
|
||||
|
||||
operator const unsigned *() const;
|
||||
operator unsigned *();
|
||||
};
|
||||
|
||||
void f() {
|
||||
X x;
|
||||
x[0] = 1;
|
||||
*x = 0;
|
||||
(void)(x - x);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue