[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