зеркало из https://github.com/microsoft/clang-1.git
More fixes to the handling of CVR-comparisons on array types. Adds a method to
QualType to get CVR-qualifiers through array types, and switches the primary comparison methods to use it. This may allow simplifying some of the callers of getUnqualifiedArrayType. Also fix the normalizing of CV-qualification during template deduction to normalize through arrays and allow a more qualified deduced array type. This fixes PR5911. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92289 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
beb8019429
Коммит
e724246b9f
|
@ -532,6 +532,11 @@ public:
|
|||
/// applied to this type.
|
||||
unsigned getCVRQualifiers() const;
|
||||
|
||||
/// \brief Retrieve the set of CVR (const-volatile-restrict) qualifiers
|
||||
/// applied to this type, looking through any number of unqualified array
|
||||
/// types to their element types' qualifiers.
|
||||
unsigned getCVRQualifiersThroughArrayTypes() const;
|
||||
|
||||
bool isConstant(ASTContext& Ctx) const {
|
||||
return QualType::isConstant(*this, Ctx);
|
||||
}
|
||||
|
@ -2687,6 +2692,19 @@ inline unsigned QualType::getCVRQualifiers() const {
|
|||
getTypePtr()->getCanonicalTypeInternal().getLocalCVRQualifiers();
|
||||
}
|
||||
|
||||
/// getCVRQualifiersThroughArrayTypes - If there are CVR qualifiers for this
|
||||
/// type, returns them. Otherwise, if this is an array type, recurses
|
||||
/// on the element type until some qualifiers have been found or a non-array
|
||||
/// type reached.
|
||||
inline unsigned QualType::getCVRQualifiersThroughArrayTypes() const {
|
||||
if (unsigned Quals = getCVRQualifiers())
|
||||
return Quals;
|
||||
QualType CT = getTypePtr()->getCanonicalTypeInternal();
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
|
||||
return AT->getElementType().getCVRQualifiersThroughArrayTypes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void QualType::removeConst() {
|
||||
removeFastQualifiers(Qualifiers::Const);
|
||||
}
|
||||
|
@ -2786,8 +2804,8 @@ inline bool QualType::getNoReturnAttr() const {
|
|||
/// int".
|
||||
inline bool QualType::isMoreQualifiedThan(QualType Other) const {
|
||||
// FIXME: work on arbitrary qualifiers
|
||||
unsigned MyQuals = this->getCVRQualifiers();
|
||||
unsigned OtherQuals = Other.getCVRQualifiers();
|
||||
unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
|
||||
unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
|
||||
if (getAddressSpace() != Other.getAddressSpace())
|
||||
return false;
|
||||
return MyQuals != OtherQuals && (MyQuals | OtherQuals) == MyQuals;
|
||||
|
@ -2799,8 +2817,8 @@ inline bool QualType::isMoreQualifiedThan(QualType Other) const {
|
|||
/// "int", and "const volatile int".
|
||||
inline bool QualType::isAtLeastAsQualifiedAs(QualType Other) const {
|
||||
// FIXME: work on arbitrary qualifiers
|
||||
unsigned MyQuals = this->getCVRQualifiers();
|
||||
unsigned OtherQuals = Other.getCVRQualifiers();
|
||||
unsigned MyQuals = this->getCVRQualifiersThroughArrayTypes();
|
||||
unsigned OtherQuals = Other.getCVRQualifiersThroughArrayTypes();
|
||||
if (getAddressSpace() != Other.getAddressSpace())
|
||||
return false;
|
||||
return (MyQuals | OtherQuals) == MyQuals;
|
||||
|
|
|
@ -375,9 +375,11 @@ DeduceTemplateArguments(ASTContext &Context,
|
|||
// referred to by the reference) can be more cv-qualified than the
|
||||
// transformed A.
|
||||
if (TDF & TDF_ParamWithReferenceType) {
|
||||
Qualifiers Quals = Param.getQualifiers();
|
||||
Quals.setCVRQualifiers(Quals.getCVRQualifiers() & Arg.getCVRQualifiers());
|
||||
Param = Context.getQualifiedType(Param.getUnqualifiedType(), Quals);
|
||||
Qualifiers Quals;
|
||||
QualType UnqualParam = Context.getUnqualifiedArrayType(Param, Quals);
|
||||
Quals.setCVRQualifiers(Quals.getCVRQualifiers() &
|
||||
Arg.getCVRQualifiersThroughArrayTypes());
|
||||
Param = Context.getQualifiedType(UnqualParam, Quals);
|
||||
}
|
||||
|
||||
// If the parameter type is not dependent, there is nothing to deduce.
|
||||
|
|
|
@ -81,3 +81,8 @@ int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -
|
|||
int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
|
||||
int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
|
||||
int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
|
||||
|
||||
// PR5911
|
||||
template <typename T, int N> void f(const T (&a)[N]);
|
||||
int iarr[] = { 1 };
|
||||
void test_PR5911() { f(iarr); }
|
||||
|
|
Загрузка…
Ссылка в новой задаче