[PATCH] D112453: [Sema] When dereferencing a pointer of dependent type, infer the result type.
Clement Courbet via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 25 07:24:44 PDT 2021
courbet created this revision.
courbet added reviewers: rsmith, aaron.ballman.
courbet requested review of this revision.
Herald added a project: clang.
Example:
template <typename T> auto f(T* t) {
return *t;
}
Before that change, the `UnaryOperator` for `*t` has type `<dependent type>`.
After the change, its type is a `T` lvalue.
I've added simple tests to verify that giving knowledge of the type to clang
does not yields false positives in contexts where c++ does not allow it to use
that knowledge.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D112453
Files:
clang/lib/Sema/SemaOverload.cpp
clang/test/SemaTemplate/dependent-type-identity.cpp
Index: clang/test/SemaTemplate/dependent-type-identity.cpp
===================================================================
--- clang/test/SemaTemplate/dependent-type-identity.cpp
+++ clang/test/SemaTemplate/dependent-type-identity.cpp
@@ -69,6 +69,16 @@
void f8(typename N::X2<U>::template apply<U> *);
void f8(typename N::X2<U>::template apply<T> *);
void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // 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 {
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -13323,10 +13323,22 @@
ArrayRef<Expr *> 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<PointerType>(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(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D112453.381987.patch
Type: text/x-patch
Size: 2286 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211025/ce45a5b9/attachment.bin>
More information about the cfe-commits
mailing list