Bug 1339537 - Part 1: Update the MOZ_NON_PARAM analysis to implicitly apply to alignas(_) types, r=ehsan

MozReview-Commit-ID: 2VDJRxxkVjV
This commit is contained in:
Michael Layzell 2017-02-14 16:56:49 -05:00
Родитель 4ffa062ade
Коммит 31c407bf72
4 изменённых файлов: 49 добавлений и 3 удалений

Просмотреть файл

@ -15,8 +15,6 @@ CustomTypeAnnotation HeapClass =
CustomTypeAnnotation("moz_heap_class", "heap");
CustomTypeAnnotation NonTemporaryClass =
CustomTypeAnnotation("moz_non_temporary_class", "non-temporary");
CustomTypeAnnotation NonParam =
CustomTypeAnnotation("moz_non_param", "non-param");
void CustomTypeAnnotation::dumpAnnotationReason(BaseCheck &Check,
QualType T,

Просмотреть файл

@ -67,6 +67,5 @@ extern CustomTypeAnnotation GlobalClass;
extern CustomTypeAnnotation NonHeapClass;
extern CustomTypeAnnotation HeapClass;
extern CustomTypeAnnotation NonTemporaryClass;
extern CustomTypeAnnotation NonParam;
#endif

Просмотреть файл

@ -5,6 +5,45 @@
#include "NonParamInsideFunctionDeclChecker.h"
#include "CustomMatchers.h"
class NonParamAnnotation : public CustomTypeAnnotation
{
public:
NonParamAnnotation() : CustomTypeAnnotation("moz_non_param", "non-param") {};
protected:
// Adding alignas(_) on a struct implicitly marks it as MOZ_NON_PARAM, due to
// 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.
bool hasFakeAnnotation(const TagDecl *D) const override {
// Check if the decl itself has an AlignedAttr on it.
for (const Attr *A : D->attrs()) {
if (isa<AlignedAttr>(A)) {
D->dump();
return true;
}
}
// Check if any of the decl's fields have an AlignedAttr on them.
if (auto RD = dyn_cast<RecordDecl>(D)) {
for (auto F : RD->fields()) {
for (auto A : F->attrs()) {
if (isa<AlignedAttr>(A)) {
D->dump();
return true;
}
}
}
}
// We don't need to check the types of fields, as the CustomTypeAnnotation
// infrastructure will handle that for us.
return false;
}
};
NonParamAnnotation NonParam;
void NonParamInsideFunctionDeclChecker::registerMatchers(MatchFinder* AstMatcher) {
AstMatcher->addMatcher(
functionDecl(anyOf(allOf(isDefinition(),

Просмотреть файл

@ -177,3 +177,13 @@ void testLambda()
(void)[](HasNonParamUnion x) -> void {}; //expected-error {{Type 'HasNonParamUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
(void)[](HasNonParamStructUnion x) -> void {}; //expected-error {{Type 'HasNonParamStructUnion' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
}
// Check that alignas() implies the MOZ_NON_PARAM attribute.
struct alignas(8) AlignasStruct { char a; };
void takesAlignasStruct(AlignasStruct x) { } // expected-error {{Type 'AlignasStruct' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
void takesAlignasStructByRef(const AlignasStruct& x) { }
struct AlignasMember { alignas(8) char a; };
void takesAlignasMember(AlignasMember x) { } // expected-error {{Type 'AlignasMember' must not be used as parameter}} expected-note {{Please consider passing a const reference instead}}
void takesAlignasMemberByRef(const AlignasMember& x) { }