зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1744604 - Part 1: Make CustomTypeAnnotation more flexible, r=andi
This allows CustomTypeAnnotation to customize the type traversal behaviour to allow things like opting library types out of static analysis easier. It will be used in parts 2 and 3 to improve the non-memmoveable and non-param trait analysis. Differential Revision: https://phabricator.services.mozilla.com/D132995
This commit is contained in:
Родитель
32999573e3
Коммит
ab7c298175
|
@ -75,13 +75,22 @@ void CustomTypeAnnotation::dumpAnnotationReason(BaseCheck &Check, QualType T,
|
|||
|
||||
CustomTypeAnnotation::AnnotationReason
|
||||
CustomTypeAnnotation::directAnnotationReason(QualType T) {
|
||||
VisitFlags ToVisit = VISIT_FIELDS | VISIT_BASES;
|
||||
|
||||
if (const TagDecl *D = T->getAsTagDecl()) {
|
||||
// Recurse into template arguments if the annotation
|
||||
// MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS is present
|
||||
if (hasCustomAttribute<moz_inherit_type_annotations_from_template_args>(
|
||||
D)) {
|
||||
ToVisit |= VISIT_TMPL_ARGS;
|
||||
}
|
||||
|
||||
if (hasCustomAttribute(D, Attribute)) {
|
||||
AnnotationReason Reason = {T, RK_Direct, nullptr, ""};
|
||||
return Reason;
|
||||
}
|
||||
|
||||
std::string ImplAnnotReason = getImplicitReason(D);
|
||||
std::string ImplAnnotReason = getImplicitReason(D, ToVisit);
|
||||
if (!ImplAnnotReason.empty()) {
|
||||
AnnotationReason Reason = {T, RK_Implicit, nullptr, ImplAnnotReason};
|
||||
return Reason;
|
||||
|
@ -98,8 +107,8 @@ CustomTypeAnnotation::directAnnotationReason(QualType T) {
|
|||
// Check if we have a type which we can recurse into
|
||||
if (const clang::ArrayType *Array = T->getAsArrayTypeUnsafe()) {
|
||||
if (hasEffectiveAnnotation(Array->getElementType())) {
|
||||
AnnotationReason Reason = {Array->getElementType(), RK_ArrayElement,
|
||||
nullptr, ""};
|
||||
AnnotationReason Reason{Array->getElementType(), RK_ArrayElement, nullptr,
|
||||
""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
}
|
||||
|
@ -110,27 +119,27 @@ CustomTypeAnnotation::directAnnotationReason(QualType T) {
|
|||
if (Declaration->hasDefinition()) {
|
||||
Declaration = Declaration->getDefinition();
|
||||
|
||||
for (const CXXBaseSpecifier &Base : Declaration->bases()) {
|
||||
if (hasEffectiveAnnotation(Base.getType())) {
|
||||
AnnotationReason Reason = {Base.getType(), RK_BaseClass, nullptr, ""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
if (ToVisit & VISIT_BASES) {
|
||||
for (const CXXBaseSpecifier &Base : Declaration->bases()) {
|
||||
if (hasEffectiveAnnotation(Base.getType())) {
|
||||
AnnotationReason Reason{Base.getType(), RK_BaseClass, nullptr, ""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse into members
|
||||
for (const FieldDecl *Field : Declaration->fields()) {
|
||||
if (hasEffectiveAnnotation(Field->getType())) {
|
||||
AnnotationReason Reason = {Field->getType(), RK_Field, Field, ""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
if (ToVisit & VISIT_FIELDS) {
|
||||
for (const FieldDecl *Field : Declaration->fields()) {
|
||||
if (hasEffectiveAnnotation(Field->getType())) {
|
||||
AnnotationReason Reason{Field->getType(), RK_Field, Field, ""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse into template arguments if the annotation
|
||||
// MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS is present
|
||||
if (hasCustomAttribute<moz_inherit_type_annotations_from_template_args>(
|
||||
Declaration)) {
|
||||
if (ToVisit & VISIT_TMPL_ARGS) {
|
||||
const ClassTemplateSpecializationDecl *Spec =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(Declaration);
|
||||
if (Spec) {
|
||||
|
@ -146,7 +155,7 @@ CustomTypeAnnotation::directAnnotationReason(QualType T) {
|
|||
}
|
||||
}
|
||||
|
||||
AnnotationReason Reason = {QualType(), RK_None, nullptr, ""};
|
||||
AnnotationReason Reason{QualType(), RK_None, nullptr, ""};
|
||||
Cache[Key] = Reason;
|
||||
return Reason;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include "CustomAttributes.h"
|
||||
#include "plugin.h"
|
||||
#include "llvm/ADT/BitmaskEnum.h"
|
||||
|
||||
class CustomTypeAnnotation {
|
||||
enum ReasonKind {
|
||||
|
@ -58,10 +59,26 @@ private:
|
|||
AnnotationReason tmplArgAnnotationReason(ArrayRef<TemplateArgument> Args);
|
||||
|
||||
protected:
|
||||
// Flags specifying which properties of the underlying type we want to visit.
|
||||
enum VisitFlags {
|
||||
VISIT_NONE = 0,
|
||||
VISIT_FIELDS = 1,
|
||||
VISIT_TMPL_ARGS = 2,
|
||||
VISIT_BASES = 4,
|
||||
LLVM_MARK_AS_BITMASK_ENUM(VISIT_BASES)
|
||||
};
|
||||
|
||||
// Allow subclasses to apply annotations for reasons other than a direct
|
||||
// annotation. A non-empty string return value means that the object D is
|
||||
// annotated, and should contain the reason why.
|
||||
virtual std::string getImplicitReason(const TagDecl *D) const { return ""; }
|
||||
//
|
||||
// The subclass may also modify `VisitFlags` to change what properties of the
|
||||
// type will be inspected to skip inspecting fields, force template arguments
|
||||
// to be inspected, etc.
|
||||
virtual std::string getImplicitReason(const TagDecl *D,
|
||||
VisitFlags &Flags) const {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
extern CustomTypeAnnotation StackClass;
|
||||
|
|
|
@ -19,7 +19,8 @@ public:
|
|||
virtual ~MemMoveAnnotation() {}
|
||||
|
||||
protected:
|
||||
std::string getImplicitReason(const TagDecl *D) const override {
|
||||
std::string getImplicitReason(const TagDecl *D,
|
||||
VisitFlags &ToVisit) const override {
|
||||
// Annotate everything in ::std, with a few exceptions; see bug
|
||||
// 1201314 for discussion.
|
||||
if (getDeclarationNamespace(D) == "std") {
|
||||
|
|
|
@ -14,7 +14,8 @@ protected:
|
|||
// MSVC limitations which prevent passing explcitly aligned types by value as
|
||||
// parameters. This overload of hasFakeAnnotation injects fake MOZ_NON_PARAM
|
||||
// annotations onto these types.
|
||||
std::string getImplicitReason(const TagDecl *D) const override {
|
||||
std::string getImplicitReason(const TagDecl *D,
|
||||
VisitFlags &ToVisit) const override {
|
||||
// Check if the decl itself has an AlignedAttr on it.
|
||||
for (const Attr *A : D->attrs()) {
|
||||
if (isa<AlignedAttr>(A)) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче