diff options
author | Nathan Sidwell <nathan@acm.org> | 2015-01-16 15:20:14 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2015-01-16 15:20:14 +0000 |
commit | 9609002b4a12e8e475db5d012df10e35dfd7f8b0 (patch) | |
tree | 8d32530111569502d5fc2a7f81bb37d3a5f559da /clang/lib | |
parent | ae47bc6ab9f636a1abed6310a18f8dba6c2151da (diff) | |
download | bcm5719-llvm-9609002b4a12e8e475db5d012df10e35dfd7f8b0.tar.gz bcm5719-llvm-9609002b4a12e8e475db5d012df10e35dfd7f8b0.zip |
restore fix for 18645, buildbot apparently gave a false positive.
Correct logic concerning 'T &&' deduction against lvalues.
llvm-svn: 226278
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 47 |
1 files changed, 17 insertions, 30 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index dd2a4d26979..90384f0b0a9 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3136,34 +3136,16 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, // are ignored for type deduction. if (ParamType.hasQualifiers()) ParamType = ParamType.getUnqualifiedType(); - const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>(); - if (ParamRefType) { - QualType PointeeType = ParamRefType->getPointeeType(); - - // If the argument has incomplete array type, try to complete its type. - if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) - ArgType = Arg->getType(); - - // [C++0x] If P is an rvalue reference to a cv-unqualified - // template parameter and the argument is an lvalue, the type - // "lvalue reference to A" is used in place of A for type - // deduction. - if (isa<RValueReferenceType>(ParamType)) { - if (!PointeeType.getQualifiers() && - isa<TemplateTypeParmType>(PointeeType) && - Arg->Classify(S.Context).isLValue() && - Arg->getType() != S.Context.OverloadTy && - Arg->getType() != S.Context.BoundMemberTy) - ArgType = S.Context.getLValueReferenceType(ArgType); - } - // [...] If P is a reference type, the type referred to by P is used - // for type deduction. - ParamType = PointeeType; - } + // [...] If P is a reference type, the type referred to by P is + // used for type deduction. + const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>(); + if (ParamRefType) + ParamType = ParamRefType->getPointeeType(); - // Overload sets usually make this parameter an undeduced - // context, but there are sometimes special circumstances. + // Overload sets usually make this parameter an undeduced context, + // but there are sometimes special circumstances. Typically + // involving a template-id-expr. if (ArgType == S.Context.OverloadTy) { ArgType = ResolveOverloadForDeduction(S, TemplateParams, Arg, ParamType, @@ -3173,12 +3155,17 @@ static bool AdjustFunctionParmAndArgTypesForDeduction(Sema &S, } if (ParamRefType) { + // If the argument has incomplete array type, try to complete its type. + if (ArgType->isIncompleteArrayType() && !S.RequireCompleteExprType(Arg, 0)) + ArgType = Arg->getType(); + // C++0x [temp.deduct.call]p3: - // [...] If P is of the form T&&, where T is a template parameter, and - // the argument is an lvalue, the type A& is used in place of A for - // type deduction. + // If P is an rvalue reference to a cv-unqualified template + // parameter and the argument is an lvalue, the type "lvalue + // reference to A" is used in place of A for type deduction. if (ParamRefType->isRValueReferenceType() && - ParamRefType->getAs<TemplateTypeParmType>() && + !ParamType.getQualifiers() && + isa<TemplateTypeParmType>(ParamType) && Arg->isLValue()) ArgType = S.Context.getLValueReferenceType(ArgType); } else { |