aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaExprMember.cpp
diff options
context:
space:
mode:
authorKrystian Stasiowski <sdkrystian@gmail.com>2024-04-11 16:19:29 -0400
committerGitHub <noreply@github.com>2024-04-11 16:19:29 -0400
commitaa80f3ec48419a73aafcc2ff947c6dd1e3734481 (patch)
treeace44cd2ed84c8225506192c9eacc95d3d12ff30 /clang/lib/Sema/SemaExprMember.cpp
parent20ed5b1f45871612570d3bd447121ac43e083c6a (diff)
downloadllvm-aa80f3ec48419a73aafcc2ff947c6dd1e3734481.zip
llvm-aa80f3ec48419a73aafcc2ff947c6dd1e3734481.tar.gz
llvm-aa80f3ec48419a73aafcc2ff947c6dd1e3734481.tar.bz2
Reapply "[Clang][Sema] Fix crash when 'this' is used in a dependent class scope function template specialization that instantiates to a static member function (#87541)" (#88311)
Reapplies #87541 and addresses the bug which caused expressions naming overload sets to be incorrectly rebuilt.
Diffstat (limited to 'clang/lib/Sema/SemaExprMember.cpp')
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp63
1 files changed, 49 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 32998ae..eeac753 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -61,6 +61,10 @@ enum IMAKind {
/// The reference is a contextually-permitted abstract member reference.
IMA_Abstract,
+ /// Whether the context is static is dependent on the enclosing template (i.e.
+ /// in a dependent class scope explicit specialization).
+ IMA_Dependent,
+
/// The reference may be to an unresolved using declaration and the
/// context is not an instance method.
IMA_Unresolved_StaticOrExplicitContext,
@@ -91,10 +95,18 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
- bool isStaticOrExplicitContext =
- SemaRef.CXXThisTypeOverride.isNull() &&
- (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic() ||
- cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction());
+ bool couldInstantiateToStatic = false;
+ bool isStaticOrExplicitContext = SemaRef.CXXThisTypeOverride.isNull();
+
+ if (auto *MD = dyn_cast<CXXMethodDecl>(DC)) {
+ if (MD->isImplicitObjectMemberFunction()) {
+ isStaticOrExplicitContext = false;
+ // A dependent class scope function template explicit specialization
+ // that is neither declared 'static' nor with an explicit object
+ // parameter could instantiate to a static or non-static member function.
+ couldInstantiateToStatic = MD->getDependentSpecializationInfo();
+ }
+ }
if (R.isUnresolvableResult())
return isStaticOrExplicitContext ? IMA_Unresolved_StaticOrExplicitContext
@@ -123,6 +135,9 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
if (Classes.empty())
return IMA_Static;
+ if (couldInstantiateToStatic)
+ return IMA_Dependent;
+
// C++11 [expr.prim.general]p12:
// An id-expression that denotes a non-static data member or non-static
// member function of a class can only be used:
@@ -263,32 +278,52 @@ static void diagnoseInstanceReference(Sema &SemaRef,
}
}
+bool Sema::isPotentialImplicitMemberAccess(const CXXScopeSpec &SS,
+ LookupResult &R,
+ bool IsAddressOfOperand) {
+ if (!getLangOpts().CPlusPlus)
+ return false;
+ else if (R.empty() || !R.begin()->isCXXClassMember())
+ return false;
+ else if (!IsAddressOfOperand)
+ return true;
+ else if (!SS.isEmpty())
+ return false;
+ else if (R.isOverloadedResult())
+ return false;
+ else if (R.isUnresolvableResult())
+ return true;
+ else
+ return isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(R.getFoundDecl());
+}
+
/// Builds an expression which might be an implicit member expression.
ExprResult Sema::BuildPossibleImplicitMemberExpr(
const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R,
- const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
- UnresolvedLookupExpr *AsULE) {
- switch (ClassifyImplicitMemberAccess(*this, R)) {
+ const TemplateArgumentListInfo *TemplateArgs, const Scope *S) {
+ switch (IMAKind Classification = ClassifyImplicitMemberAccess(*this, R)) {
case IMA_Instance:
- return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, true, S);
-
case IMA_Mixed:
case IMA_Mixed_Unrelated:
case IMA_Unresolved:
- return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
- S);
-
+ return BuildImplicitMemberExpr(
+ SS, TemplateKWLoc, R, TemplateArgs,
+ /*IsKnownInstance=*/Classification == IMA_Instance, S);
case IMA_Field_Uneval_Context:
Diag(R.getNameLoc(), diag::warn_cxx98_compat_non_static_member_use)
<< R.getLookupNameInfo().getName();
[[fallthrough]];
case IMA_Static:
case IMA_Abstract:
+ case IMA_Dependent:
case IMA_Mixed_StaticOrExplicitContext:
case IMA_Unresolved_StaticOrExplicitContext:
if (TemplateArgs || TemplateKWLoc.isValid())
- return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
- return AsULE ? AsULE : BuildDeclarationNameExpr(SS, R, false);
+ return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*RequiresADL=*/false,
+ TemplateArgs);
+ return BuildDeclarationNameExpr(
+ SS, R, /*NeedsADL=*/false, /*AcceptInvalidDecl=*/false,
+ /*NeedUnresolved=*/Classification == IMA_Dependent);
case IMA_Error_StaticOrExplicitContext:
case IMA_Error_Unrelated: