-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[cxx-interop] Remove annotationOnly flag from Escapability request #85643
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5493,12 +5493,18 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator, | |
|
|
||
| // Escapability inference rules: | ||
| // - array and vector types have the same escapability as their element type | ||
| // - pointer and reference types are currently imported as escapable | ||
| // - pointer and reference types are currently imported as unknown | ||
| // (importing them as non-escapable broke backward compatibility) | ||
| // - a record type is escapable or non-escapable if it is explicitly annotated | ||
| // as such | ||
| // - a record type is escapable if it is annotated with SWIFT_ESCAPABLE_IF() | ||
| // and none of the annotation arguments are non-escapable | ||
| // - an aggregate or non-cxx record is escapable if none of their fields or | ||
| // bases are non-escapable (as long as they have a definition) | ||
| // * we only infer escapability for simple types, with no user-declared | ||
| // constructors, virtual bases or virtual member functions | ||
| // * for more complex CxxRecordDecls, we rely solely on escapability | ||
| // annotations | ||
| // - in all other cases, the record has unknown escapability (e.g. no | ||
| // escapability annotations, malformed escapability annotations) | ||
|
|
||
|
|
@@ -5554,14 +5560,8 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator, | |
|
|
||
| continue; | ||
| } | ||
| // The `annotationOnly` flag used to control which types we infered | ||
| // escapability for. Currently, this flag is always set to true, meaning | ||
| // that any type without an annotation (CxxRecordDecls, aggregates, decls | ||
| // lacking definition, etc.) will raise `hasUnknown`. | ||
| if (desc.annotationOnly) { | ||
| hasUnknown = true; | ||
| continue; | ||
| } | ||
| // Only try to infer escapability if the record doesn't have any | ||
| // escapability annotations | ||
| auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(recordDecl); | ||
| if (recordDecl->getDefinition() && | ||
| (!cxxRecordDecl || cxxRecordDecl->isAggregate())) { | ||
|
|
@@ -5571,7 +5571,11 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator, | |
| } | ||
| for (auto field : recordDecl->fields()) | ||
| maybePushToStack(field->getType()->getUnqualifiedDesugaredType()); | ||
| continue; | ||
| } else { | ||
| // We only infer escapability for simple types, such as aggregates and | ||
| // RecordDecls that are not CxxRecordDecls. For more complex | ||
| // CxxRecordDecls, we rely solely on escapability annotations. | ||
| hasUnknown = true; | ||
| } | ||
| } else if (type->isArrayType()) { | ||
| auto elemTy = cast<clang::ArrayType>(type) | ||
|
|
@@ -5582,10 +5586,9 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator, | |
| maybePushToStack(vecTy->getElementType()->getUnqualifiedDesugaredType()); | ||
| } else if (type->isAnyPointerType() || type->isBlockPointerType() || | ||
| type->isMemberPointerType() || type->isReferenceType()) { | ||
| if (desc.annotationOnly) | ||
| hasUnknown = true; | ||
| else | ||
| return CxxEscapability::NonEscapable; | ||
| // pointer and reference types are currently imported as unknown | ||
| // (importing them as non-escapable broke backward compatibility) | ||
| hasUnknown = true; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with this for now, to preserve the current behavior, but assuming pointers have unknown escapability seems like it could be problematic. My understanding is that, semantically, pointers should be treated as non-escapable. Do we have a plan for how to correctly analyze these types while maintaining backwards compat? An idea I had was making the analysis depend on whether strict memory safety is turned on or off, essentially using/abusing it as a feature flag. But that may not be a good idea for reasons that I haven't fully thought through yet.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I do not think we can maintain backward compatibility and be precise at the same time. And we do not want strict memory safety to influence the behavior of the code. Making a type suddenly non-escapable when strict memory safety is on would result in some code not compiling. Especially when one is using an API that is owned by someone else this compilation error might be impossible to resolve. |
||
| } | ||
| } | ||
| return hasUnknown ? CxxEscapability::Unknown : CxxEscapability::Escapable; | ||
|
|
||
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.
In C++ language mode, Clang makes all
RecordDecls intoCXXRecordDecls. Could this cause source compatibility issues with Obj-C interop? e.g. if someone enables C++ interop for the first time, would some types have different escapability?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'd expect those record decls to be aggregates in C++, so we should handle them the same way.
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.
Makes sense, thanks!