diff options
author | Krystian Stasiowski <sdkrystian@gmail.com> | 2024-05-13 12:24:46 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-13 12:24:46 -0400 |
commit | 596a9c1f9b3179b3c77cbde1e96619292ce2a10a (patch) | |
tree | 7d17ff5df8cdc49a77a8459d105aae5d75d6ed90 /clang/lib/Sema/SemaExprMember.cpp | |
parent | 89a080cb79972abae240c226090af9a3094e2269 (diff) | |
download | llvm-596a9c1f9b3179b3c77cbde1e96619292ce2a10a.zip llvm-596a9c1f9b3179b3c77cbde1e96619292ce2a10a.tar.gz llvm-596a9c1f9b3179b3c77cbde1e96619292ce2a10a.tar.bz2 |
[Clang][Sema] Fix bug where operator-> typo corrects in the current instantiation (#91972)
#90152 introduced a bug that occurs when typo-correction attempts to fix a reference to a
non-existent member of the current instantiation (even though
`operator->` may return a different type than the object type). This
patch fixes it by simply considering the object expression to be of type
`ASTContext::DependentTy` when the arrow operator is used with a
dependent non-pointer non-function operand (after any implicit
conversions).
Diffstat (limited to 'clang/lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp index 9fa69da..244488a 100644 --- a/clang/lib/Sema/SemaExprMember.cpp +++ b/clang/lib/Sema/SemaExprMember.cpp @@ -995,8 +995,6 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, // arrow operator was used with a dependent non-pointer object expression, // build a CXXDependentScopeMemberExpr. if (R.wasNotFoundInCurrentInstantiation() || - (IsArrow && !BaseExprType->isPointerType() && - BaseExprType->isDependentType()) || (R.getLookupName().getCXXOverloadedOperator() == OO_Equal && (SS.isSet() ? SS.getScopeRep()->isDependent() : BaseExprType->isDependentType()))) @@ -1322,28 +1320,28 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, else if (const ObjCObjectPointerType *Ptr = BaseType->getAs<ObjCObjectPointerType>()) BaseType = Ptr->getPointeeType(); - else if (!BaseType->isDependentType()) { - if (BaseType->isRecordType()) { - // Recover from arrow accesses to records, e.g.: - // struct MyRecord foo; - // foo->bar - // This is actually well-formed in C++ if MyRecord has an - // overloaded operator->, but that should have been dealt with - // by now--or a diagnostic message already issued if a problem - // was encountered while looking for the overloaded operator->. - if (!S.getLangOpts().CPlusPlus) { - S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) - << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() - << FixItHint::CreateReplacement(OpLoc, "."); - } - IsArrow = false; - } else if (BaseType->isFunctionType()) { - goto fail; - } else { - S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) - << BaseType << BaseExpr.get()->getSourceRange(); - return ExprError(); + else if (BaseType->isFunctionType()) + goto fail; + else if (BaseType->isDependentType()) + BaseType = S.Context.DependentTy; + else if (BaseType->isRecordType()) { + // Recover from arrow accesses to records, e.g.: + // struct MyRecord foo; + // foo->bar + // This is actually well-formed in C++ if MyRecord has an + // overloaded operator->, but that should have been dealt with + // by now--or a diagnostic message already issued if a problem + // was encountered while looking for the overloaded operator->. + if (!S.getLangOpts().CPlusPlus) { + S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion) + << BaseType << int(IsArrow) << BaseExpr.get()->getSourceRange() + << FixItHint::CreateReplacement(OpLoc, "."); } + IsArrow = false; + } else { + S.Diag(MemberLoc, diag::err_typecheck_member_reference_arrow) + << BaseType << BaseExpr.get()->getSourceRange(); + return ExprError(); } } @@ -1363,7 +1361,7 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, } // Handle field access to simple records. - if (BaseType->getAsRecordDecl() || BaseType->isDependentType()) { + if (BaseType->getAsRecordDecl()) { TypoExpr *TE = nullptr; if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow, SS, HasTemplateArgs, TemplateKWLoc, TE)) @@ -1374,6 +1372,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, // failed, the lookup result will have been cleared--that combined with the // valid-but-null ExprResult will trigger the appropriate diagnostics. return ExprResult(TE); + } else if (BaseType->isDependentType()) { + R.setNotFoundInCurrentInstantiation(); + return ExprEmpty(); } // Handle ivar access to Objective-C objects. |