-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Clang][Sema] fix crash of attribute transform #78088
Conversation
@llvm/pr-subscribers-clang Author: Qizhi Hu (jcsxky) ChangesTry to fix issue
This patch tries to fix these issue above.
Full diff: https://github.com/llvm/llvm-project/pull/78088.diff 3 Files Affected:
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index 471deb14aba51f..04780fdeae3bc1 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 1a1bc87d2b3203..be5ba2000de197 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())
@@ -7083,8 +7087,9 @@ QualType TreeTransform<Derived>::TransformAttributedType(
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;
+ 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 00000000000000..32e015bab02918
--- /dev/null
+++ b/clang/test/Sema/attr-lifetimebound-no-crash.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only
+
+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];
+}
\ No newline at end of file
|
b5dfbd8
to
d040754
Compare
clang/lib/Sema/TreeTransform.h
Outdated
// TODO: this is really lame; we should really be rebuilding the | ||
// equivalent type from first principles. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment would no longer apply, would it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, it has been rebuilt using TypeLoc
like ModifiedType
.
int main() { | ||
Bar<int> b; | ||
(void)b[2]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing new line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
fb6aaee
to
55b433e
Compare
TypeLocBuilder AuxiliaryTLB; | ||
AuxiliaryTLB.reserve(TL.getFullDataSize()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an alternative might be to call
TLB.TypeWasModifiedSafely(result)
(after the call to getAttributedType
below).
I wonder if @AaronBallman has a better alternative
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think that's a better approach. Transforming the type should not have changed anything about type location information associated with the type. WDYT @erichkeane ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, yeah, the location shouldn't have changed, just the type itself. I think the suggestions above are the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your remind! Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to use AuxiliaryTLB
any longer, do we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I‘m afraid not. It will crash on TypeLocBuilder::pushImpl
with the new added test case since TLast == LastTy
assert failed if we reuse TLB
. Because current FunctionProtoType
can't be child of other type node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right, we do still need to do that dance it seems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cor3ntin @AaronBallman @erichkeane The test on windows platform failed with TLB.TypeWasModifiedSafely(result);
. Maybe we shouldn't change LastTy
of TLB
since we just transform EquivalentType
using AuxiliaryTLB
and haven't touched TLB
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested address-spaces.cpp
on linux and TLast == LastTy
assert also failed. Don't know why the test on linux platform passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking we didn't need to use AuxiliaryTLB
and could instead call TypeWasModifiedSafely
but it seems like we need the code as you originally had it (using AuxiliaryTLB
but not calling TypeWasModifiedSafely
). Sorry for the run-around!
55b433e
to
7632f63
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but please wait in case @erichkeane has final thoughts.
TypeLocBuilder AuxiliaryTLB; | ||
AuxiliaryTLB.reserve(TL.getFullDataSize()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, you're right, we do still need to do that dance it seems.
7632f63
to
b0fcd3b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please be sure to add a release note about the fix to clang/docs/ReleaseNotes.rst.
TypeLocBuilder AuxiliaryTLB; | ||
AuxiliaryTLB.reserve(TL.getFullDataSize()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I was thinking we didn't need to use AuxiliaryTLB
and could instead call TypeWasModifiedSafely
but it seems like we need the code as you originally had it (using AuxiliaryTLB
but not calling TypeWasModifiedSafely
). Sorry for the run-around!
clang/lib/Sema/TreeTransform.h
Outdated
auto *RD = | ||
dyn_cast_or_null<CXXRecordDecl>(SemaRef.getCurLexicalContext()); | ||
Sema::CXXThisScopeRAII ThisScope( | ||
SemaRef, ThisContext == nullptr && nullptr != RD ? RD : ThisContext, | ||
ThisTypeQuals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto *RD = | |
dyn_cast_or_null<CXXRecordDecl>(SemaRef.getCurLexicalContext()); | |
Sema::CXXThisScopeRAII ThisScope( | |
SemaRef, ThisContext == nullptr && nullptr != RD ? RD : ThisContext, | |
ThisTypeQuals); | |
auto *RD = | |
dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext()); | |
Sema::CXXThisScopeRAII ThisScope( | |
SemaRef, !ThisContext && RD ? RD : ThisContext, | |
ThisTypeQuals); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Fixed and release note has been added.
0e74e6c
to
2d6a39f
Compare
There seems to be an issue with the rebasing of the PR. |
I try to merge this PR and found |
2d6a39f
to
707c471
Compare
707c471
to
9e7ba80
Compare
Try to fix issue
FunctionProtoType
, ifThisContext
isnullptr
andCurrentContext
isClassTemplateSpecializationDecl
, Constructor ofCXXThisScopeRAII
andSema::getCurrentThisType
won't setCXXThisTypeOverride
of Sema. This will lead to buildingthis
inRebuildCXXThisExpr
with a invalid type(NULL type) and cause crash.modifiedType
of attribute type is changed,EquivalentType
need to be transformed. IfEquivalentType
isFunctionProtoType
, itsParamVarDecl
will not be copyed(but parameter num does) and will not be instanced inTransformFunctionTypeParams
sinceParamVarDecl
isnullptr
. This will lead to crash infindInstantiationOf
(can't find the instance ofParamVarDecl
).This patch tries to fix these issues above.
CurrentContext
isClassTemplateSpecializationDecl
, Use it.EquivalentTypeLoc
instead ofEquivalentType
since it has parameter info. But, if use currentTypeLocBuilder
, it will crash inTypeLocBuilder::push
sinceLastType
is mismatch. Use an auxiliaryTypeLocBuilder
instead and get transformedEquivalentType
.