https://github.com/Sirraide created https://github.com/llvm/llvm-project/pull/83187
When resolving the type of `this` inside a member function, we were attaching all qualifiers present on the member function to the class type and then making it a pointer; however, `__restrict`, unlike `const` and `volatile`, needs to be attached to the pointer type rather than the pointee type. This fixes #82941. >From e9df22166fd5768e11273446cb9e52953e55cd5d Mon Sep 17 00:00:00 2001 From: Sirraide <aeternalm...@gmail.com> Date: Tue, 27 Feb 2024 22:07:23 +0100 Subject: [PATCH 1/3] [Clang] [Sema] Handle __restrict-qualified member functions properly --- clang/lib/AST/DeclCXX.cpp | 15 ++++++-- clang/lib/Sema/SemaExprCXX.cpp | 2 +- clang/test/SemaCXX/restrict-this.cpp | 51 ++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 clang/test/SemaCXX/restrict-this.cpp diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 117e802dae2d9d..b4f2327d9c560a 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2543,8 +2543,19 @@ QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT, const CXXRecordDecl *Decl) { ASTContext &C = Decl->getASTContext(); QualType ObjectTy = ::getThisObjectType(C, FPT, Decl); - return C.getLangOpts().HLSL ? C.getLValueReferenceType(ObjectTy) - : C.getPointerType(ObjectTy); + + // Unlike 'const' and 'volatile', a '__restrict' qualifier must be + // attached to the pointer type, not the pointee. + bool Restrict = FPT->getMethodQuals().hasRestrict(); + if (Restrict) + ObjectTy.removeLocalRestrict(); + + ObjectTy = C.getLangOpts().HLSL ? C.getLValueReferenceType(ObjectTy) + : C.getPointerType(ObjectTy); + + if (Restrict) + ObjectTy.addRestrict(); + return ObjectTy; } QualType CXXMethodDecl::getThisType() const { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 59758d3bd6d1a3..c4750ce78fa9c1 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1220,7 +1220,7 @@ static QualType adjustCVQualifiersForCXXThisWithinLambda( : nullptr; } } - return ASTCtx.getPointerType(ClassType); + return ThisTy; } QualType Sema::getCurrentThisType() { diff --git a/clang/test/SemaCXX/restrict-this.cpp b/clang/test/SemaCXX/restrict-this.cpp new file mode 100644 index 00000000000000..79c6081f904275 --- /dev/null +++ b/clang/test/SemaCXX/restrict-this.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s +// expected-no-diagnostics + +struct C { + void f() __restrict { + static_assert(__is_same(decltype(this), C *__restrict)); + (void) [this]() { + static_assert(__is_same(decltype(this), C *__restrict)); + (void) [this]() { static_assert(__is_same(decltype(this), C *__restrict)); }; + + // By-value capture means 'this' is now a different object; do not + // make it __restrict. + (void) [*this]() { static_assert(__is_same(decltype(this), const C *)); }; + (void) [*this]() mutable { static_assert(__is_same(decltype(this), C *)); }; + }; + } +}; + +template <typename T> struct TC { + void f() __restrict { + static_assert(__is_same(decltype(this), TC<int> *__restrict)); + (void) [this]() { + static_assert(__is_same(decltype(this), TC<int> *__restrict)); + (void) [this]() { static_assert(__is_same(decltype(this), TC<int> *__restrict)); }; + + // By-value capture means 'this' is now a different object; do not + // make it __restrict. + (void) [*this]() { static_assert(__is_same(decltype(this), const TC<int> *)); }; + (void) [*this]() mutable { static_assert(__is_same(decltype(this), TC<int> *)); }; + }; + } +}; + +void f() { + TC<int>{}.f(); +} + +namespace gh82941 { +void f(int& x) { + (void)x; +} + +class C { + int x; + void g() __restrict; +}; + +void C::g() __restrict { + f(this->x); +} +} \ No newline at end of file >From c3031a9699582391e25e1bccd58fad59fbec379b Mon Sep 17 00:00:00 2001 From: Sirraide <aeternalm...@gmail.com> Date: Tue, 27 Feb 2024 22:13:09 +0100 Subject: [PATCH 2/3] [Clang] Update release notes --- clang/docs/ReleaseNotes.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7e16b9f0c67dbd..d420f572a84487 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -290,6 +290,9 @@ Bug Fixes to C++ Support lookup searches the bases of an incomplete class. - Fix a crash when an unresolved overload set is encountered on the RHS of a ``.*`` operator. (`#53815 <https://github.com/llvm/llvm-project/issues/53815>`_) +- In ``__restrict``-qualified member functions, attach ``__restrict`` to the pointer type of + ``this`` rather than the pointee type. + Fixes (`#82941 <https://github.com/llvm/llvm-project/issues/82941>`_). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ >From 073be09acf2b20bc20b15615c81b5ae89e490786 Mon Sep 17 00:00:00 2001 From: Sirraide <aeternalm...@gmail.com> Date: Tue, 27 Feb 2024 22:16:43 +0100 Subject: [PATCH 3/3] [NFC] Add newline at end of file --- clang/test/SemaCXX/restrict-this.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/restrict-this.cpp b/clang/test/SemaCXX/restrict-this.cpp index 79c6081f904275..8cd89f0f36a76c 100644 --- a/clang/test/SemaCXX/restrict-this.cpp +++ b/clang/test/SemaCXX/restrict-this.cpp @@ -48,4 +48,4 @@ class C { void C::g() __restrict { f(this->x); } -} \ No newline at end of file +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits