aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorKrystian Stasiowski <sdkrystian@gmail.com>2024-04-10 08:38:49 -0400
committerGitHub <noreply@github.com>2024-04-10 08:38:49 -0400
commitb47e439559ad03a1b32614f573aad66f145a634d (patch)
tree76f09335a914751e15fa30bf6d18da4f6ac0f76f /clang/lib/Sema
parenta2bdbc6f0da2a9d0cecb23c64bd20423b3fd0340 (diff)
downloadllvm-b47e439559ad03a1b32614f573aad66f145a634d.zip
llvm-b47e439559ad03a1b32614f573aad66f145a634d.tar.gz
llvm-b47e439559ad03a1b32614f573aad66f145a634d.tar.bz2
Revert "[Clang][Sema] Fix crash when 'this' is used in a dependent class scope function template specialization that instantiates to a static member function" (#88264)
Reverts llvm/llvm-project#87541
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp5
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp44
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp42
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp8
-rw-r--r--clang/lib/Sema/TreeTransform.h7
5 files changed, 31 insertions, 75 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 45acbf1..594c117 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3442,11 +3442,10 @@ static bool ShouldLookupResultBeMultiVersionOverload(const LookupResult &R) {
ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R, bool NeedsADL,
- bool AcceptInvalidDecl,
- bool NeedUnresolved) {
+ bool AcceptInvalidDecl) {
// If this is a single, fully-resolved result and we don't need ADL,
// just build an ordinary singleton decl ref.
- if (!NeedUnresolved && !NeedsADL && R.isSingleResult() &&
+ if (!NeedsADL && R.isSingleResult() &&
!R.getAsSingle<FunctionTemplateDecl>() &&
!ShouldLookupResultBeMultiVersionOverload(R))
return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), R.getFoundDecl(),
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 9822477..7b9b8f1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1415,42 +1415,26 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc, const bool Explicit,
}
ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
- // C++20 [expr.prim.this]p1:
- // The keyword this names a pointer to the object for which an
- // implicit object member function is invoked or a non-static
- // data member's initializer is evaluated.
+ /// C++ 9.3.2: In the body of a non-static member function, the keyword this
+ /// is a non-lvalue expression whose value is the address of the object for
+ /// which the function is called.
QualType ThisTy = getCurrentThisType();
- if (CheckCXXThisType(Loc, ThisTy))
- return ExprError();
+ if (ThisTy.isNull()) {
+ DeclContext *DC = getFunctionLevelDeclContext();
- return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
-}
+ if (const auto *Method = dyn_cast<CXXMethodDecl>(DC);
+ Method && Method->isExplicitObjectMemberFunction()) {
+ return Diag(Loc, diag::err_invalid_this_use) << 1;
+ }
-bool Sema::CheckCXXThisType(SourceLocation Loc, QualType Type) {
- if (!Type.isNull())
- return false;
+ if (isLambdaCallWithExplicitObjectParameter(CurContext))
+ return Diag(Loc, diag::err_invalid_this_use) << 1;
- // C++20 [expr.prim.this]p3:
- // If a declaration declares a member function or member function template
- // of a class X, the expression this is a prvalue of type
- // "pointer to cv-qualifier-seq X" wherever X is the current class between
- // the optional cv-qualifier-seq and the end of the function-definition,
- // member-declarator, or declarator. It shall not appear within the
- // declaration of either a static member function or an explicit object
- // member function of the current class (although its type and value
- // category are defined within such member functions as they are within
- // an implicit object member function).
- DeclContext *DC = getFunctionLevelDeclContext();
- if (const auto *Method = dyn_cast<CXXMethodDecl>(DC);
- Method && Method->isExplicitObjectMemberFunction()) {
- Diag(Loc, diag::err_invalid_this_use) << 1;
- } else if (isLambdaCallWithExplicitObjectParameter(CurContext)) {
- Diag(Loc, diag::err_invalid_this_use) << 1;
- } else {
- Diag(Loc, diag::err_invalid_this_use) << 0;
+ return Diag(Loc, diag::err_invalid_this_use) << 0;
}
- return true;
+
+ return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
}
Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 8cd2288..32998ae 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -61,10 +61,6 @@ 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,
@@ -95,18 +91,10 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
DeclContext *DC = SemaRef.getFunctionLevelDeclContext();
- 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();
- }
- }
+ bool isStaticOrExplicitContext =
+ SemaRef.CXXThisTypeOverride.isNull() &&
+ (!isa<CXXMethodDecl>(DC) || cast<CXXMethodDecl>(DC)->isStatic() ||
+ cast<CXXMethodDecl>(DC)->isExplicitObjectMemberFunction());
if (R.isUnresolvableResult())
return isStaticOrExplicitContext ? IMA_Unresolved_StaticOrExplicitContext
@@ -135,9 +123,6 @@ 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:
@@ -283,30 +268,27 @@ ExprResult Sema::BuildPossibleImplicitMemberExpr(
const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs, const Scope *S,
UnresolvedLookupExpr *AsULE) {
- switch (IMAKind Classification = ClassifyImplicitMemberAccess(*this, R)) {
+ switch (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,
- /*IsKnownInstance=*/Classification == IMA_Instance, S);
+ return BuildImplicitMemberExpr(SS, TemplateKWLoc, R, TemplateArgs, false,
+ 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, /*RequiresADL=*/false,
- TemplateArgs);
- return AsULE ? AsULE
- : BuildDeclarationNameExpr(
- SS, R, /*NeedsADL=*/false, /*AcceptInvalidDecl=*/false,
- /*NeedUnresolved=*/Classification == IMA_Dependent);
+ return BuildTemplateIdExpr(SS, TemplateKWLoc, R, false, TemplateArgs);
+ return AsULE ? AsULE : BuildDeclarationNameExpr(SS, R, false);
case IMA_Error_StaticOrExplicitContext:
case IMA_Error_Unrelated:
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8248b10..127a432 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -5093,14 +5093,6 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
EnterExpressionEvaluationContext EvalContext(
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
- Qualifiers ThisTypeQuals;
- CXXRecordDecl *ThisContext = nullptr;
- if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
- ThisContext = Method->getParent();
- ThisTypeQuals = Method->getMethodQualifiers();
- }
- CXXThisScopeRAII ThisScope(*this, ThisContext, ThisTypeQuals);
-
// Introduce a new scope where local variable instantiations will be
// recorded, unless we're actually a member function within a local
// class, in which case we need to merge our results with the parent
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 13d7b00..d4d2fa6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -3307,13 +3307,12 @@ public:
/// Build a new C++ "this" expression.
///
- /// By default, performs semantic analysis to build a new "this" expression.
- /// Subclasses may override this routine to provide different behavior.
+ /// By default, builds a new "this" expression without performing any
+ /// semantic analysis. Subclasses may override this routine to provide
+ /// different behavior.
ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
QualType ThisType,
bool isImplicit) {
- if (getSema().CheckCXXThisType(ThisLoc, ThisType))
- return ExprError();
return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
}