When perform exact-qualifier-match template argument deduction,

properly account for the possibility that certain opaque types
might be more qualified than they appear.  Fixes PR7708.

llvm-svn: 112390
This commit is contained in:
John McCall 2010-08-28 22:14:41 +00:00
parent 64be20e5a4
commit 0856906b1e
2 changed files with 37 additions and 1 deletions

View File

@ -350,6 +350,29 @@ DeduceTemplateArguments(Sema &S,
return Sema::TDK_Success;
}
/// \brief Determines whether the given type is an opaque type that
/// might be more qualified when instantiated.
static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
switch (T->getTypeClass()) {
case Type::TypeOfExpr:
case Type::TypeOf:
case Type::DependentName:
case Type::Decltype:
case Type::UnresolvedUsing:
return true;
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::DependentSizedArray:
return IsPossiblyOpaquelyQualifiedType(
cast<ArrayType>(T)->getElementType());
default:
return false;
}
}
/// \brief Deduce the template arguments by comparing the parameter type and
/// the argument type (C++ [temp.deduct.type]).
///
@ -474,7 +497,7 @@ DeduceTemplateArguments(Sema &S,
if (TDF & TDF_ParamWithReferenceType) {
if (Param.isMoreQualifiedThan(Arg))
return Sema::TDK_NonDeducedMismatch;
} else {
} else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
return Sema::TDK_NonDeducedMismatch;
}

View File

@ -121,3 +121,16 @@ namespace test1 {
foo(a);
}
}
// PR7708
namespace test2 {
template<typename T> struct Const { typedef void const type; };
template<typename T> void f(T, typename Const<T>::type*);
template<typename T> void f(T, void const *);
void test() {
void *p = 0;
f(0, p);
}
}