[clang] [Clang][Sema] fix crash of attribute transform (PR #78088)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 18 19:40:48 PST 2024


https://github.com/jcsxky updated https://github.com/llvm/llvm-project/pull/78088

>From b0fcd3b278cf625845c192301e0d9c37af09c239 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Sun, 14 Jan 2024 15:07:26 +0800
Subject: [PATCH] [Clang][Sema] fix crash of attribute transform

---
 clang/include/clang/AST/TypeLoc.h               |  4 ++++
 clang/lib/Sema/TreeTransform.h                  | 14 +++++++++-----
 clang/test/Sema/attr-lifetimebound-no-crash.cpp | 17 +++++++++++++++++
 3 files changed, 30 insertions(+), 5 deletions(-)
 create mode 100644 clang/test/Sema/attr-lifetimebound-no-crash.cpp

diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 471deb14aba51fc..04780fdeae3bc10 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -884,6 +884,10 @@ class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
     return getInnerTypeLoc();
   }
 
+  TypeLoc getEquivalentTypeLoc() const {
+    return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData());
+  }
+
   /// The type attribute.
   const Attr *getAttr() const {
     return getLocalData()->TypeAttr;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 1a1bc87d2b3203c..c8653017a034e71 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6124,7 +6124,11 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType(
       //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
       //   and the end of the function-definition, member-declarator, or
       //   declarator.
-      Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
+      auto *RD =
+          dyn_cast_or_null<CXXRecordDecl>(SemaRef.getCurLexicalContext());
+      Sema::CXXThisScopeRAII ThisScope(
+          SemaRef, ThisContext == nullptr && nullptr != RD ? RD : ThisContext,
+          ThisTypeQuals);
 
       ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
       if (ResultType.isNull())
@@ -7081,10 +7085,10 @@ QualType TreeTransform<Derived>::TransformAttributedType(
   // FIXME: dependent operand expressions?
   if (getDerived().AlwaysRebuild() ||
       modifiedType != oldType->getModifiedType()) {
-    // TODO: this is really lame; we should really be rebuilding the
-    // equivalent type from first principles.
-    QualType equivalentType
-      = getDerived().TransformType(oldType->getEquivalentType());
+    TypeLocBuilder AuxiliaryTLB;
+    AuxiliaryTLB.reserve(TL.getFullDataSize());
+    QualType equivalentType =
+        getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
     if (equivalentType.isNull())
       return QualType();
 
diff --git a/clang/test/Sema/attr-lifetimebound-no-crash.cpp b/clang/test/Sema/attr-lifetimebound-no-crash.cpp
new file mode 100644
index 000000000000000..e668a78790defd7
--- /dev/null
+++ b/clang/test/Sema/attr-lifetimebound-no-crash.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+// expected-no-diagnostics
+
+template<typename T>
+struct Bar {
+    int* data;
+
+    auto operator[](const int index) const [[clang::lifetimebound]] -> decltype(data[index]) {
+        return data[index];
+    }
+};
+
+int main() {
+    Bar<int> b;
+    (void)b[2];
+}



More information about the cfe-commits mailing list