https://github.com/sdkrystian updated
https://github.com/llvm/llvm-project/pull/87541
>From 6ad6b5e698c3ae6fd8e881582fcfa4c8bb231da4 Mon Sep 17 00:00:00 2001
From: Krystian Stasiowski
Date: Wed, 3 Apr 2024 14:33:27 -0400
Subject: [PATCH 1/4] [Clang][Sema] Fix crash when 'this' is used in a
dependent class scope function template specialization that instantiates to a
static member function
---
clang/include/clang/Sema/Sema.h | 8 +++-
clang/lib/Sema/SemaExpr.cpp | 5 ++-
clang/lib/Sema/SemaExprCXX.cpp| 44 +--
clang/lib/Sema/SemaExprMember.cpp | 44 ++-
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 8
clang/lib/Sema/TreeTransform.h| 7 +--
...ms-function-specialization-class-scope.cpp | 38 ++--
7 files changed, 118 insertions(+), 36 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 56d66a4486e0e74..57117963d84f1d2 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -5428,7 +5428,8 @@ class Sema final : public SemaBase {
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R,
bool NeedsADL,
- bool AcceptInvalidDecl = false);
+ bool AcceptInvalidDecl = false,
+ bool NeedUnresolved = false);
ExprResult BuildDeclarationNameExpr(
const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, NamedDecl
*D,
NamedDecl *FoundD = nullptr,
@@ -6580,7 +6581,10 @@ class Sema final : public SemaBase {
SourceLocation RParenLoc);
ActOnCXXThis - Parse 'this' pointer.
- ExprResult ActOnCXXThis(SourceLocation loc);
+ ExprResult ActOnCXXThis(SourceLocation Loc);
+
+ /// Check whether the type of 'this' is valid in the current context.
+ bool CheckCXXThisType(SourceLocation Loc, QualType Type);
/// Build a CXXThisExpr and mark it referenced in the current context.
Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8db4fffeecfe35f..7b91bbe0b2054d3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3442,10 +3442,11 @@ static bool
ShouldLookupResultBeMultiVersionOverload(const LookupResult &R) {
ExprResult Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R, bool NeedsADL,
- bool AcceptInvalidDecl) {
+ bool AcceptInvalidDecl,
+ bool NeedUnresolved) {
// If this is a single, fully-resolved result and we don't need ADL,
// just build an ordinary singleton decl ref.
- if (!NeedsADL && R.isSingleResult() &&
+ if (!NeedUnresolved && !NeedsADL && R.isSingleResult() &&
!R.getAsSingle() &&
!ShouldLookupResultBeMultiVersionOverload(R))
return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
R.getFoundDecl(),
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index cfb5c6b6f283373..d84c66e5969f74a 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1415,26 +1415,42 @@ bool Sema::CheckCXXThisCapture(SourceLocation Loc,
const bool Explicit,
}
ExprResult Sema::ActOnCXXThis(SourceLocation Loc) {
- /// 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.
+ // 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.
QualType ThisTy = getCurrentThisType();
- if (ThisTy.isNull()) {
-DeclContext *DC = getFunctionLevelDeclContext();
+ if (CheckCXXThisType(Loc, ThisTy))
+return ExprError();
-if (const auto *Method = dyn_cast(DC);
-Method && Method->isExplicitObjectMemberFunction()) {
- return Diag(Loc, diag::err_invalid_this_use) << 1;
-}
+ return BuildCXXThisExpr(Loc, ThisTy, /*IsImplicit=*/false);
+}
-if (isLambdaCallWithExplicitObjectParameter(CurContext))
- return Diag(Loc, diag::err_invalid_this_use) << 1;
+bool Sema::CheckCXXThisType(SourceLocation Loc, QualType Type) {
+ if (!Type.isNull())
+return false;
-return Diag(Loc, diag::err_invalid_this_use) << 0;
+ // 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-qualif