diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 523054b2d848..35d72547cd3f 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -1222,6 +1222,10 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() { Tok.is(tok::kw_restrict) ) ConsumeToken(); + // ref-qualifier[opt] + if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) + ConsumeToken(); + // exception-specification if (Tok.is(tok::kw_throw)) { ConsumeToken(); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 70e997394653..fd12ccf0f28a 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1154,11 +1154,11 @@ DeduceTemplateArguments(Sema &S, const FunctionProtoType *FunctionProtoParam = cast(Param); - if (FunctionProtoParam->getTypeQuals() != - FunctionProtoArg->getTypeQuals()) - return Sema::TDK_NonDeducedMismatch; - - if (FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic()) + if (FunctionProtoParam->getTypeQuals() + != FunctionProtoArg->getTypeQuals() || + FunctionProtoParam->getRefQualifier() + != FunctionProtoArg->getRefQualifier() || + FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic()) return Sema::TDK_NonDeducedMismatch; // Check return types. diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp new file mode 100644 index 000000000000..a9173fd6be86 --- /dev/null +++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp @@ -0,0 +1,47 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// Deductions specific to C++0x. + +template +struct member_pointer_kind { + static const unsigned value = 0; +}; + +template +struct member_pointer_kind { + static const unsigned value = 1; +}; + +template +struct member_pointer_kind { + static const unsigned value = 2; +}; + +template +struct member_pointer_kind { + static const unsigned value = 3; +}; + +template +struct member_pointer_kind { + static const unsigned value = 4; +}; + +template +struct member_pointer_kind { + static const unsigned value = 5; +}; + +template +struct member_pointer_kind { + static const unsigned value = 6; +}; + +struct X { }; + +static_assert(member_pointer_kind::value == 1, ""); +static_assert(member_pointer_kind::value == 2, ""); +static_assert(member_pointer_kind::value == 3, ""); +static_assert(member_pointer_kind::value == 4, ""); +static_assert(member_pointer_kind::value == 5, ""); +static_assert(member_pointer_kind::value == 6, "");