[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@qq.com>
This commit is contained in:
parent
6d0080b5de
commit
d9d1ae6400
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
@ -884,6 +884,10 @@ public:
|
||||
return getInnerTypeLoc();
|
||||
}
|
||||
|
||||
TypeLoc getEquivalentTypeLoc() const {
|
||||
return TypeLoc(getTypePtr()->getEquivalentType(), getNonLocalData());
|
||||
}
|
||||
|
||||
/// The type attribute.
|
||||
const Attr *getAttr() const {
|
||||
return getLocalData()->TypeAttr;
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
17
clang/test/Sema/attr-lifetimebound-no-crash.cpp
Normal file
17
clang/test/Sema/attr-lifetimebound-no-crash.cpp
Normal file
@ -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];
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user