[clang] [Clang][Sema] Diagnose class member access expressions naming non-existent members of the current instantiation prior to instantiation in the absence of dependent base classes (PR #84050)

via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 5 10:01:29 PST 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff a642eb89bdaf10c6b4994fc1187de27b441236ed 5fc710a43e7799d2721e56dd53d5828e55090a0d -- clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp clang/lib/AST/Expr.cpp clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaExprMember.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/TreeTransform.h clang/test/CodeGenCXX/mangle.cpp clang/test/Index/annotate-nested-name-specifier.cpp clang/test/SemaTemplate/instantiate-function-1.cpp clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e071c3e580..22216dc9e0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -666,10 +666,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
   // expressions of certain types in C++.
   if (getLangOpts().CPlusPlus &&
       (E->getType() == Context.OverloadTy ||
-      // FIXME: This is a hack! We want the lvalue-to-rvalue conversion applied
-      // to pointer types even if the pointee type is dependent.
-      (T->isDependentType() && !T->isPointerType()) ||
-       T->isRecordType()))
+       // FIXME: This is a hack! We want the lvalue-to-rvalue conversion applied
+       // to pointer types even if the pointee type is dependent.
+       (T->isDependentType() && !T->isPointerType()) || T->isRecordType()))
     return E;
 
   // The C standard is actually really unclear on this point, and
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index eb87e0edda..da32ea251a 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -670,8 +670,7 @@ private:
 }
 
 static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
-                                     Expr *BaseExpr,
-                                     QualType RTy,
+                                     Expr *BaseExpr, QualType RTy,
                                      SourceLocation OpLoc, bool IsArrow,
                                      CXXScopeSpec &SS, bool HasTemplateArgs,
                                      SourceLocation TemplateKWLoc,
@@ -695,9 +694,8 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
   SourceRange BaseRange = BaseExpr ? BaseExpr->getSourceRange() : SourceRange();
   if (!RTy->isDependentType() &&
       !SemaRef.isThisOutsideMemberFunctionBody(RTy) &&
-      SemaRef.RequireCompleteType(OpLoc, RTy,
-                                  diag::err_typecheck_incomplete_tag,
-                                  BaseRange))
+      SemaRef.RequireCompleteType(
+          OpLoc, RTy, diag::err_typecheck_incomplete_tag, BaseRange))
     return true;
 
   if (HasTemplateArgs || TemplateKWLoc.isValid()) {
@@ -792,16 +790,12 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
                                    Decl *ObjCImpDecl, bool HasTemplateArgs,
                                    SourceLocation TemplateKWLoc);
 
-ExprResult
-Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
-                               SourceLocation OpLoc, bool IsArrow,
-                               CXXScopeSpec &SS,
-                               SourceLocation TemplateKWLoc,
-                               NamedDecl *FirstQualifierInScope,
-                               const DeclarationNameInfo &NameInfo,
-                               const TemplateArgumentListInfo *TemplateArgs,
-                               const Scope *S,
-                               ActOnMemberAccessExtraArgs *ExtraArgs) {
+ExprResult Sema::BuildMemberReferenceExpr(
+    Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow,
+    CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+    NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo,
+    const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
+    ActOnMemberAccessExtraArgs *ExtraArgs) {
   LookupResult R(*this, NameInfo, LookupMemberName);
 
   // Implicit member accesses.
@@ -809,9 +803,9 @@ Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
     TypoExpr *TE = nullptr;
     QualType RecordTy = BaseType;
     if (IsArrow) RecordTy = RecordTy->castAs<PointerType>()->getPointeeType();
-    if (LookupMemberExprInRecord(
-            *this, R, nullptr, RecordTy, OpLoc, IsArrow,
-            SS, TemplateArgs != nullptr, TemplateKWLoc, TE))
+    if (LookupMemberExprInRecord(*this, R, nullptr, RecordTy, OpLoc, IsArrow,
+                                 SS, TemplateArgs != nullptr, TemplateKWLoc,
+                                 TE))
       return ExprError();
     if (TE)
       return TE;
@@ -1006,9 +1000,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
 
   if (R.wasNotFoundInCurrentInstantiation() ||
       (SS.isValid() && !computeDeclContext(SS, false))) {
-    return ActOnDependentMemberExpr(BaseExpr, BaseExprType,
-                                    IsArrow, OpLoc,
-                                    SS, TemplateKWLoc, FirstQualifierInScope,
+    return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
+                                    TemplateKWLoc, FirstQualifierInScope,
                                     R.getLookupNameInfo(), TemplateArgs);
   }
 
@@ -1048,9 +1041,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
 
   if (R.empty()) {
     // Rederive where we looked up.
-    DeclContext *DC = (SS.isSet()
-                       ? computeDeclContext(SS, false)
-                       : BaseType->getAsRecordDecl());
+    DeclContext *DC = (SS.isSet() ? computeDeclContext(SS, false)
+                                  : BaseType->getAsRecordDecl());
 
     if (ExtraArgs) {
       ExprResult RetryExpr;
@@ -1077,7 +1069,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
       }
     }
 
-    if(DC) {
+    if (DC) {
       Diag(R.getNameLoc(), diag::err_no_member)
           << MemberName << DC
           << (BaseExpr ? BaseExpr->getSourceRange() : SourceRange());
@@ -1317,9 +1309,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
 
   QualType BaseType = BaseExpr.get()->getType();
 
-  #if 0
+#if 0
   assert(!BaseType->isDependentType());
-  #endif
+#endif
 
   DeclarationName MemberName = R.getLookupName();
   SourceLocation MemberLoc = R.getNameLoc();
@@ -1332,12 +1324,12 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
     if (const PointerType *Ptr = BaseType->getAs<PointerType>())
       BaseType = Ptr->getPointeeType();
     else if (!BaseType->isDependentType()) {
-      if (const ObjCObjectPointerType *Ptr
-               = BaseType->getAs<ObjCObjectPointerType>())
-      BaseType = Ptr->getPointeeType();
+      if (const ObjCObjectPointerType *Ptr =
+              BaseType->getAs<ObjCObjectPointerType>())
+        BaseType = Ptr->getPointeeType();
       else if (BaseType->isRecordType()) {
         // Recover from arrow accesses to records, e.g.:
-         //   struct MyRecord foo;
+        //   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
@@ -1356,7 +1348,6 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
             << BaseType << BaseExpr.get()->getSourceRange();
         return ExprError();
       }
-
     }
   }
 
@@ -1378,8 +1369,8 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R,
   // Handle field access to simple records.
   if (BaseType->getAsRecordDecl() || BaseType->isDependentType()) {
     TypoExpr *TE = nullptr;
-    if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow, SS,
-                                 HasTemplateArgs, TemplateKWLoc, TE))
+    if (LookupMemberExprInRecord(S, R, BaseExpr.get(), BaseType, OpLoc, IsArrow,
+                                 SS, HasTemplateArgs, TemplateKWLoc, TE))
       return ExprError();
 
     // Returning valid-but-null is how we indicate to the caller that
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 7218553bcd..27de404531 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5744,10 +5744,10 @@ static ImplicitConversionSequence TryObjectArgumentInitialization(
     return ICS;
   }
 
-  // FIXME: Should this check getAsRecordDecl instead?
-  #if 0
+// FIXME: Should this check getAsRecordDecl instead?
+#if 0
   assert(FromType->isRecordType());
-  #endif
+#endif
 
   QualType ClassType = S.Context.getTypeDeclType(ActingContext);
   // C++98 [class.dtor]p2:
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 27d3588aaa..585f4f11af 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -12939,14 +12939,14 @@ bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
     if (R.empty()) {
       // If a 'template' keyword was used, a lookup that finds only non-template
       // names is an error.
-      getSema().Diag(R.getNameLoc(), diag::err_template_kw_refers_to_non_template)
-          << R.getLookupName()
-          << Old->getQualifierLoc().getSourceRange()
-          << Old->hasTemplateKeyword()
-          << Old->getTemplateKeywordLoc();
-      getSema().Diag(FoundDecl->getLocation(), diag::note_template_kw_refers_to_non_template)
+      getSema().Diag(R.getNameLoc(),
+                     diag::err_template_kw_refers_to_non_template)
+          << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
+          << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
+      getSema().Diag(FoundDecl->getLocation(),
+                     diag::note_template_kw_refers_to_non_template)
           << R.getLookupName();
-        return true;
+      return true;
     }
   }
 
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 3af67671aa..16b18b80f2 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1569,8 +1569,9 @@ TEST_P(ASTMatchersTest, IsArrow_MatchesMemberVariablesViaArrow) {
       matches("class Y { void x() { y; } int y; };", memberExpr(isArrow())));
   EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };",
                          memberExpr(isArrow())));
-  EXPECT_TRUE(matches("template <class T> class Y { void x() { this->m; } int m; };",
-                         memberExpr(isArrow())));
+  EXPECT_TRUE(
+      matches("template <class T> class Y { void x() { this->m; } int m; };",
+              memberExpr(isArrow())));
   EXPECT_TRUE(
       notMatches("template <class T> class Y { void x() { (*this).m; } };",
                  cxxDependentScopeMemberExpr(isArrow())));

``````````

</details>


https://github.com/llvm/llvm-project/pull/84050


More information about the cfe-commits mailing list