diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index c4c257d47a0a4..c441baf2d7416 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 `_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 471deb14aba51..04780fdeae3bc 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -884,6 +884,10 @@ class AttributedTypeLoc : public ConcreteTypeLocgetEquivalentType(), 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 e55e752b9cc35..40028544e23c8 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -6131,7 +6131,9 @@ QualType TreeTransform::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(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::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 0000000000000..e668a78790def --- /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 +struct Bar { + int* data; + + auto operator[](const int index) const [[clang::lifetimebound]] -> decltype(data[index]) { + return data[index]; + } +}; + +int main() { + Bar b; + (void)b[2]; +}