зеркало из https://github.com/microsoft/clang.git
Clean up the handling of non-CVR qualifiers in template argument
deduction. The good news is that address spaces are a lot less broken in this regard than I'd expected. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130346 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
20c0da7787
Коммит
a459cc26f6
|
@ -949,7 +949,6 @@ DeduceTemplateArguments(Sema &S,
|
|||
|
||||
// If the argument type is an array type, move the qualifiers up to the
|
||||
// top level, so they can be matched with the qualifiers on the parameter.
|
||||
// FIXME: address spaces, ObjC GC qualifiers
|
||||
if (isa<ArrayType>(Arg)) {
|
||||
Qualifiers Quals;
|
||||
Arg = S.Context.getUnqualifiedArrayType(Arg, Quals);
|
||||
|
@ -2455,8 +2454,8 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
|
|||
// C++0x [temp.deduct.call]p3:
|
||||
// If P is a cv-qualified type, the top level cv-qualifiers of P's type
|
||||
// are ignored for type deduction.
|
||||
if (ParamType.getCVRQualifiers())
|
||||
ParamType = ParamType.getLocalUnqualifiedType();
|
||||
if (ParamType.hasQualifiers())
|
||||
ParamType = ParamType.getUnqualifiedType();
|
||||
const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>();
|
||||
if (ParamRefType) {
|
||||
QualType PointeeType = ParamRefType->getPointeeType();
|
||||
|
@ -2512,8 +2511,7 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S,
|
|||
else {
|
||||
// - If A is a cv-qualified type, the top level cv-qualifiers of A's
|
||||
// type are ignored for type deduction.
|
||||
if (ArgType.getCVRQualifiers())
|
||||
ArgType = ArgType.getUnqualifiedType();
|
||||
ArgType = ArgType.getUnqualifiedType();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
template<typename T, typename U>
|
||||
struct is_same {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_same<T, T> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
typedef int __attribute__((address_space(1))) int_1;;
|
||||
typedef int __attribute__((address_space(2))) int_2;;
|
||||
typedef int __attribute__((address_space(1))) *int_1_ptr;
|
||||
typedef int_2 *int_2_ptr;
|
||||
|
||||
// Check that we maintain address spaces through template argument
|
||||
// deduction from a type.
|
||||
template<typename T>
|
||||
struct remove_pointer {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_pointer<T *> {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
int check_remove0[is_same<remove_pointer<int_1_ptr>::type, int_1>::value? 1 : -1];
|
||||
int check_remove1[is_same<remove_pointer<int_2_ptr>::type, int_2>::value? 1 : -1];
|
||||
int check_remove2[is_same<remove_pointer<int_2_ptr>::type, int>::value? -1 : 1];
|
||||
int check_remove3[is_same<remove_pointer<int_2_ptr>::type, int_1>::value? -1 : 1];
|
||||
|
||||
// Check that we maintain address spaces through template argument
|
||||
// deduction for a call.
|
||||
template<typename T>
|
||||
void accept_any_pointer(T*) {
|
||||
T *x = 1; // expected-error{{cannot initialize a variable of type '__attribute__((address_space(1))) int *' with an rvalue of type 'int'}} \
|
||||
// expected-error{{cannot initialize a variable of type '__attribute__((address_space(3))) int *' with an rvalue of type 'int'}}
|
||||
}
|
||||
|
||||
void test_accept_any_pointer(int_1_ptr ip1, int_2_ptr ip2) {
|
||||
static __attribute__((address_space(3))) int array[17];
|
||||
accept_any_pointer(ip1); // expected-note{{in instantiation of}}
|
||||
accept_any_pointer(array); // expected-note{{in instantiation of}}
|
||||
}
|
||||
|
Загрузка…
Ссылка в новой задаче