diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index f573744083a4..1fd616a08669 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1049,6 +1049,10 @@ TemplateSpecializationType:: anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) { for (unsigned Idx = 0; Idx < NumArgs; ++Idx) { switch (Args[Idx].getKind()) { + case TemplateArgument::Null: + assert(false && "Should not have a NULL template argument"); + break; + case TemplateArgument::Type: if (Args[Idx].getAsType()->isDependentType()) return true; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index a55dadd932b7..c98913239165 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -66,15 +66,42 @@ static bool DeduceTemplateArguments(ASTContext &Context, QualType Param, if (Param.getCVRQualifiers() != Arg.getCVRQualifiers()) return false; - if (const PointerType *PointerParam = Param->getAsPointerType()) { - const PointerType *PointerArg = Arg->getAsPointerType(); - if (!PointerArg) - return false; + switch (Param->getTypeClass()) { + case Type::Pointer: { + const PointerType *PointerArg = Arg->getAsPointerType(); + if (!PointerArg) + return false; + + return DeduceTemplateArguments(Context, + cast(Param)->getPointeeType(), + PointerArg->getPointeeType(), + Deduced); + } + + case Type::LValueReference: { + const LValueReferenceType *ReferenceArg = Arg->getAsLValueReferenceType(); + if (!ReferenceArg) + return false; + + return DeduceTemplateArguments(Context, + cast(Param)->getPointeeType(), + ReferenceArg->getPointeeType(), + Deduced); + } - return DeduceTemplateArguments(Context, - PointerParam->getPointeeType(), - PointerArg->getPointeeType(), - Deduced); + case Type::RValueReference: { + const RValueReferenceType *ReferenceArg = Arg->getAsRValueReferenceType(); + if (!ReferenceArg) + return false; + + return DeduceTemplateArguments(Context, + cast(Param)->getPointeeType(), + ReferenceArg->getPointeeType(), + Deduced); + } + + default: + break; } // FIXME: Many more cases to go (to go). diff --git a/clang/test/SemaTemplate/temp_class_spec.cpp b/clang/test/SemaTemplate/temp_class_spec.cpp index 1efb364a1b27..710fa4ada55e 100644 --- a/clang/test/SemaTemplate/temp_class_spec.cpp +++ b/clang/test/SemaTemplate/temp_class_spec.cpp @@ -19,6 +19,19 @@ int array1[is_pointer::value? 1 : -1]; int array2[is_pointer::value? 1 : -1]; // expected-error{{partial ordering}} \ // expected-error{{negative}} +template +struct is_lvalue_reference { + static const bool value = false; +}; + +template +struct is_lvalue_reference { + static const bool value = true; +}; + +int lvalue_ref0[is_lvalue_reference::value? -1 : 1]; +int lvalue_ref1[is_lvalue_reference::value? 1 : -1]; + template struct is_same { static const bool value = false;