diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13323,10 +13323,22 @@ ArrayRef ArgsArray(Args, NumArgs); if (Input->isTypeDependent()) { - if (Fns.empty()) - return UnaryOperator::Create(Context, Input, Opc, Context.DependentTy, - VK_PRValue, OK_Ordinary, OpLoc, false, + if (Fns.empty()) { + QualType ResultTy = Context.DependentTy; + ExprValueKind ResultKind = VK_PRValue; + if (getLangOpts().CPlusPlus && (Opc == UO_Deref) && + Input->getType()->isPointerType()) { + // In c++, a deref of a `T*` always has type `T&` (16.6.8). There is no + // way for other overloads to be selected since overloads of `operator*` + // always have class or enum parameters. + ResultTy = cast(Input->getType().getCanonicalType()) + ->getPointeeType(); + ResultKind = VK_LValue; + } + return UnaryOperator::Create(Context, Input, Opc, ResultTy, ResultKind, + OK_Ordinary, OpLoc, false, CurFPFeatureOverrides()); + } CXXRecordDecl *NamingClass = nullptr; // lookup ignores member operators ExprResult Fn = CreateUnresolvedLookupExpr( diff --git a/clang/test/SemaTemplate/dependent-type-identity.cpp b/clang/test/SemaTemplate/dependent-type-identity.cpp --- a/clang/test/SemaTemplate/dependent-type-identity.cpp +++ b/clang/test/SemaTemplate/dependent-type-identity.cpp @@ -69,6 +69,16 @@ void f8(typename N::X2::template apply *); void f8(typename N::X2::template apply *); void f8(typename ::Nalias::X2::template apply *); // expected-error{{redeclar}} + + // (17.4.2): If an expression e is type-dependent (17.6.2.2), decltype(e) + // denotes a unique dependent type. Two such decltype-specifiers refer to the + // same type only if their expressions are equivalent (17.5.6.1) + T* a; + T* b; + using V = decltype(*a); + void f9(decltype(*a)); // expected-note{{previous}} + void f9(decltype(*b)); + void f9(V); // expected-error{{redeclar}} }; namespace PR6851 {