[clang] a0130fc - [clang] Correct calculation of MemberExpr's dependence

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 10 03:00:54 PDT 2023


Author: Mariya Podchishchaeva
Date: 2023-07-10T06:00:11-04:00
New Revision: a0130fc51cbc0b0bbeca378a27430eba5136f142

URL: https://github.com/llvm/llvm-project/commit/a0130fc51cbc0b0bbeca378a27430eba5136f142
DIFF: https://github.com/llvm/llvm-project/commit/a0130fc51cbc0b0bbeca378a27430eba5136f142.diff

LOG: [clang] Correct calculation of MemberExpr's dependence

Due to incorrect calculation false positive diagnostics were emitted.

Fixes https://github.com/llvm/llvm-project/issues/48731

Reviewed By: shafik, cor3ntin

Differential Revision: https://reviews.llvm.org/D154689

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/ComputeDependence.cpp
    clang/lib/AST/Expr.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1ae7b8377e3e4e..ae88de6a4aa7e6 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -573,6 +573,9 @@ Bug Fixes in This Version
 - Stop evaluating a constant expression if the condition expression which in
   switch statement contains errors.
   (`#63453 <https://github.com/llvm/llvm-project/issues/63453>_`)
+- Fixed false positive error diagnostic when pack expansion appears in template
+  parameters of a member expression.
+  (`#48731 <https://github.com/llvm/llvm-project/issues/48731>`_)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index 829a2e750f254e..632f38f711fb1b 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -611,9 +611,24 @@ ExprDependence clang::computeDependence(OffsetOfExpr *E) {
   return D;
 }
 
+static inline ExprDependence getDependenceInExpr(DeclarationNameInfo Name) {
+  auto D = ExprDependence::None;
+  if (Name.isInstantiationDependent())
+    D |= ExprDependence::Instantiation;
+  if (Name.containsUnexpandedParameterPack())
+    D |= ExprDependence::UnexpandedPack;
+  return D;
+}
+
 ExprDependence clang::computeDependence(MemberExpr *E) {
-  auto *MemberDecl = E->getMemberDecl();
   auto D = E->getBase()->getDependence();
+  D |= getDependenceInExpr(E->getMemberNameInfo());
+
+  if (auto *NNS = E->getQualifier())
+    D |= toExprDependence(NNS->getDependence() &
+                          ~NestedNameSpecifierDependence::Dependent);
+
+  auto *MemberDecl = E->getMemberDecl();
   if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
     DeclContext *DC = MemberDecl->getDeclContext();
     // dyn_cast_or_null is used to handle objC variables which do not
@@ -723,15 +738,6 @@ ExprDependence clang::computeDependence(CXXPseudoDestructorExpr *E) {
   return D;
 }
 
-static inline ExprDependence getDependenceInExpr(DeclarationNameInfo Name) {
-  auto D = ExprDependence::None;
-  if (Name.isInstantiationDependent())
-    D |= ExprDependence::Instantiation;
-  if (Name.containsUnexpandedParameterPack())
-    D |= ExprDependence::UnexpandedPack;
-  return D;
-}
-
 ExprDependence
 clang::computeDependence(OverloadExpr *E, bool KnownDependent,
                          bool KnownInstantiationDependent,

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index dc5f193d37f0a5..25d3535e5dac43 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1759,16 +1759,7 @@ MemberExpr *MemberExpr::Create(
   MemberExpr *E = new (Mem) MemberExpr(Base, IsArrow, OperatorLoc, MemberDecl,
                                        NameInfo, T, VK, OK, NOUR);
 
-  // FIXME: remove remaining dependence computation to computeDependence().
-  auto Deps = E->getDependence();
   if (HasQualOrFound) {
-    // FIXME: Wrong. We should be looking at the member declaration we found.
-    if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent())
-      Deps |= ExprDependence::TypeValueInstantiation;
-    else if (QualifierLoc &&
-             QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())
-      Deps |= ExprDependence::Instantiation;
-
     E->MemberExprBits.HasQualifierOrFoundDecl = true;
 
     MemberExprNameQualifier *NQ =
@@ -1780,13 +1771,16 @@ MemberExpr *MemberExpr::Create(
   E->MemberExprBits.HasTemplateKWAndArgsInfo =
       TemplateArgs || TemplateKWLoc.isValid();
 
+  // FIXME: remove remaining dependence computation to computeDependence().
+  auto Deps = E->getDependence();
   if (TemplateArgs) {
     auto TemplateArgDeps = TemplateArgumentDependence::None;
     E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc, *TemplateArgs,
         E->getTrailingObjects<TemplateArgumentLoc>(), TemplateArgDeps);
-    if (TemplateArgDeps & TemplateArgumentDependence::Instantiation)
-      Deps |= ExprDependence::Instantiation;
+    for (const TemplateArgumentLoc &ArgLoc : TemplateArgs->arguments()) {
+      Deps |= toExprDependence(ArgLoc.getArgument().getDependence());
+    }
   } else if (TemplateKWLoc.isValid()) {
     E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom(
         TemplateKWLoc);

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
index 8e5743790682be..9f9aad604d5f11 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
@@ -306,3 +306,22 @@ namespace DependentCTAD {
     f<B>(A<B(0)>()); // OK
   }
 }
+
+namespace GH48731 {
+template <int> using N = int;
+struct X { template<typename T> void f(); };
+template<int ...Is> decltype((X().f<N<Is>>(), ...)) x;
+template<int ...Is> decltype(((new X())->f<N<Is>>(), ...)) y;
+
+struct A {};
+template<int> using Tfoo = A;
+template<int ...Ns> void foo(A a) {
+  (a.~Tfoo<Ns>(), ...);
+}
+
+struct B { operator int(); };
+template<int> using Tbar = int;
+template<int ...Ns> void bar(B b) {
+  (b.operator Tbar<Ns>(), ...);
+}
+}


        


More information about the cfe-commits mailing list