Skip to content

Commit d9d1ae6

Browse files
authored
[Clang][Sema] fix crash of attribute transform (#78088)
Try to fix [issue](#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 <[email protected]>
1 parent 6d0080b commit d9d1ae6

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ Bug Fixes to Attribute Support
113113
Bug Fixes to C++ Support
114114
^^^^^^^^^^^^^^^^^^^^^^^^
115115

116+
- Fix crash when using lifetimebound attribute in function with trailing return.
117+
Fixes (`#73619 <https://github.com/llvm/llvm-project/issues/73619>`_)
118+
116119
Bug Fixes to AST Handling
117120
^^^^^^^^^^^^^^^^^^^^^^^^^
118121

clang/include/clang/AST/TypeLoc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,10 @@ class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
884884
return getInnerTypeLoc();
885885
}
886886

887+
TypeLoc getEquivalentTypeLoc() const {
888+
return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData());
889+
}
890+
887891
/// The type attribute.
888892
const Attr *getAttr() const {
889893
return getLocalData()->TypeAttr;

clang/lib/Sema/TreeTransform.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6131,7 +6131,9 @@ QualType TreeTransform<Derived>::TransformFunctionProtoType(
61316131
// "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
61326132
// and the end of the function-definition, member-declarator, or
61336133
// declarator.
6134-
Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
6134+
auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6135+
Sema::CXXThisScopeRAII ThisScope(
6136+
SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
61356137

61366138
ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
61376139
if (ResultType.isNull())
@@ -7088,10 +7090,10 @@ QualType TreeTransform<Derived>::TransformAttributedType(
70887090
// FIXME: dependent operand expressions?
70897091
if (getDerived().AlwaysRebuild() ||
70907092
modifiedType != oldType->getModifiedType()) {
7091-
// TODO: this is really lame; we should really be rebuilding the
7092-
// equivalent type from first principles.
7093-
QualType equivalentType
7094-
= getDerived().TransformType(oldType->getEquivalentType());
7093+
TypeLocBuilder AuxiliaryTLB;
7094+
AuxiliaryTLB.reserve(TL.getFullDataSize());
7095+
QualType equivalentType =
7096+
getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
70957097
if (equivalentType.isNull())
70967098
return QualType();
70977099

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 %s -verify -fsyntax-only
2+
3+
// expected-no-diagnostics
4+
5+
template<typename T>
6+
struct Bar {
7+
int* data;
8+
9+
auto operator[](const int index) const [[clang::lifetimebound]] -> decltype(data[index]) {
10+
return data[index];
11+
}
12+
};
13+
14+
int main() {
15+
Bar<int> b;
16+
(void)b[2];
17+
}

0 commit comments

Comments
 (0)