зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1114267 - Part 1: Add an analysis to force some classes to have trivial ctors and dtors; r=jrmuizel
This commit is contained in:
Родитель
d945a5c5ae
Коммит
3b65f212d1
|
@ -64,10 +64,16 @@ private:
|
|||
virtual void run(const MatchFinder::MatchResult &Result);
|
||||
};
|
||||
|
||||
class TrivialCtorDtorChecker : public MatchFinder::MatchCallback {
|
||||
public:
|
||||
virtual void run(const MatchFinder::MatchResult &Result);
|
||||
};
|
||||
|
||||
ScopeChecker stackClassChecker;
|
||||
ScopeChecker globalClassChecker;
|
||||
NonHeapClassChecker nonheapClassChecker;
|
||||
ArithmeticArgChecker arithmeticArgChecker;
|
||||
TrivialCtorDtorChecker trivialCtorDtorChecker;
|
||||
MatchFinder astMatcher;
|
||||
};
|
||||
|
||||
|
@ -368,6 +374,12 @@ AST_MATCHER(Decl, noArithmeticExprInArgs) {
|
|||
return MozChecker::hasCustomAnnotation(&Node, "moz_no_arith_expr_in_arg");
|
||||
}
|
||||
|
||||
/// This matcher will match any C++ class that is marked as having a trivial
|
||||
/// constructor and destructor.
|
||||
AST_MATCHER(CXXRecordDecl, hasTrivialCtorDtor) {
|
||||
return MozChecker::hasCustomAnnotation(&Node, "moz_trivial_ctor_dtor");
|
||||
}
|
||||
|
||||
/// This matcher will match all arithmetic binary operators.
|
||||
AST_MATCHER(BinaryOperator, binaryArithmeticOperator) {
|
||||
BinaryOperatorKind opcode = Node.getOpcode();
|
||||
|
@ -484,6 +496,9 @@ DiagnosticsMatcher::DiagnosticsMatcher()
|
|||
)
|
||||
)).bind("call"),
|
||||
&arithmeticArgChecker);
|
||||
|
||||
astMatcher.addMatcher(recordDecl(hasTrivialCtorDtor()).bind("node"),
|
||||
&trivialCtorDtorChecker);
|
||||
}
|
||||
|
||||
void DiagnosticsMatcher::ScopeChecker::run(
|
||||
|
@ -620,6 +635,19 @@ void DiagnosticsMatcher::ArithmeticArgChecker::run(
|
|||
}
|
||||
}
|
||||
|
||||
void DiagnosticsMatcher::TrivialCtorDtorChecker::run(
|
||||
const MatchFinder::MatchResult &Result) {
|
||||
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
|
||||
unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Error, "class %0 must have trivial constructors and destructors");
|
||||
const CXXRecordDecl *node = Result.Nodes.getNodeAs<CXXRecordDecl>("node");
|
||||
|
||||
bool badCtor = !node->hasTrivialDefaultConstructor();
|
||||
bool badDtor = !node->hasTrivialDestructor();
|
||||
if (badCtor || badDtor)
|
||||
Diag.Report(node->getLocStart(), errorID) << node;
|
||||
}
|
||||
|
||||
class MozCheckAction : public PluginASTAction {
|
||||
public:
|
||||
ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, StringRef fileName) override {
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
#define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor")))
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR EmptyClass{};
|
||||
|
||||
template <class T>
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR TemplateEmptyClass{};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadUserDefinedCtor { // expected-error {{class 'BadUserDefinedCtor' must have trivial constructors and destructors}}
|
||||
BadUserDefinedCtor() {}
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadUserDefinedDtor { // expected-error {{class 'BadUserDefinedDtor' must have trivial constructors and destructors}}
|
||||
~BadUserDefinedDtor() {}
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadVirtualDtor { // expected-error {{class 'BadVirtualDtor' must have trivial constructors and destructors}}
|
||||
virtual ~BadVirtualDtor() {}
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadVirtualMember { // expected-error {{class 'BadVirtualMember' must have trivial constructors and destructors}}
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
void foo();
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadNonEmptyCtorDtor { // expected-error {{class 'BadNonEmptyCtorDtor' must have trivial constructors and destructors}}
|
||||
BadNonEmptyCtorDtor() { foo(); }
|
||||
~BadNonEmptyCtorDtor() { foo(); }
|
||||
};
|
||||
|
||||
struct NonTrivialCtor {
|
||||
NonTrivialCtor() { foo(); }
|
||||
};
|
||||
|
||||
struct NonTrivialDtor {
|
||||
~NonTrivialDtor() { foo(); }
|
||||
};
|
||||
|
||||
struct VirtualMember {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadNonTrivialCtorInBase : NonTrivialCtor { // expected-error {{class 'BadNonTrivialCtorInBase' must have trivial constructors and destructors}}
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadNonTrivialDtorInBase : NonTrivialDtor { // expected-error {{class 'BadNonTrivialDtorInBase' must have trivial constructors and destructors}}
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadNonTrivialCtorInMember { // expected-error {{class 'BadNonTrivialCtorInMember' must have trivial constructors and destructors}}
|
||||
NonTrivialCtor m;
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadNonTrivialDtorInMember { // expected-error {{class 'BadNonTrivialDtorInMember' must have trivial constructors and destructors}}
|
||||
NonTrivialDtor m;
|
||||
};
|
||||
|
||||
struct MOZ_TRIVIAL_CTOR_DTOR BadVirtualMemberInMember { // expected-error {{class 'BadVirtualMemberInMember' must have trivial constructors and destructors}}
|
||||
VirtualMember m;
|
||||
};
|
|
@ -12,6 +12,7 @@ SOURCES += [
|
|||
'TestNoArithmeticExprInArgument.cpp',
|
||||
'TestNonHeapClass.cpp',
|
||||
'TestStackClass.cpp',
|
||||
'TestTrivialCtorDtor.cpp',
|
||||
]
|
||||
|
||||
DISABLE_STL_WRAPPING = True
|
||||
|
|
Загрузка…
Ссылка в новой задаче