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

via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 25 22:26:57 PST 2024


Author: Qizhi Hu
Date: 2024-01-26T14:26:53+08:00
New Revision: d9d1ae6400a7f8a12068bdd37ecda62f07e52bce

URL: https://github.com/llvm/llvm-project/commit/d9d1ae6400a7f8a12068bdd37ecda62f07e52bce
DIFF: https://github.com/llvm/llvm-project/commit/d9d1ae6400a7f8a12068bdd37ecda62f07e52bce.diff

LOG: [Clang][Sema] fix crash of attribute transform (#78088)

Try to fix [issue](https://github.com/llvm/llvm-project/issues/73619)

1. During transforming `FunctionProtoType`, if `ThisContext` is
`nullptr` and `CurrentContext` is `ClassTemplateSpecializationDecl`,
Constructor of `CXXThisScopeRAII` and `Sema::getCurrentThisType` won't
set `CXXThisTypeOverride` of Sema. This will lead to building `this` in
`RebuildCXXThisExpr` with a invalid type(NULL type) and cause crash.
2. During transforming attribute type, if `modifiedType` of attribute
type is changed, `EquivalentType` need to be transformed. If
`EquivalentType` is `FunctionProtoType`, its `ParamVarDecl` will not be
copyed(but parameter num does) and will not be instanced in
`TransformFunctionTypeParams` since `ParamVarDecl` is `nullptr`. This
will lead to crash in `findInstantiationOf`(can't find the instance of
`ParamVarDecl`).

This patch tries to fix these issues above.

1. If `CurrentContext` is `ClassTemplateSpecializationDecl`, Use it.
2. Use `EquivalentTypeLoc` instead of `EquivalentType` since it has
parameter info. But, if use current `TypeLocBuilder`, it will crash in
`TypeLocBuilder::push` since `LastType` is mismatch. Use an auxiliary
`TypeLocBuilder` instead and get transformed `EquivalentType`.

Co-authored-by: huqizhi <836744285 at qq.com>

Added: 
    clang/test/Sema/attr-lifetimebound-no-crash.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/AST/TypeLoc.h
    clang/lib/Sema/TreeTransform.h

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c4c257d47a0a4bd..c441baf2d741623 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -113,6 +113,9 @@ Bug Fixes to Attribute Support
 Bug Fixes to C++ Support
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
+- Fix crash when using lifetimebound attribute in function with trailing return.
+  Fixes (`#73619 <https://github.com/llvm/llvm-project/issues/73619>`_)
+
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 

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 e55e752b9cc354c..40028544e23c8e1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -6131,7 +6131,9 @@ 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<CXXRecordDecl>(SemaRef.getCurLexicalContext());
+      Sema::CXXThisScopeRAII ThisScope(
+          SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
 
       ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
       if (ResultType.isNull())
@@ -7088,10 +7090,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