Bug 1114267 - Part 1: Add an analysis to force some classes to have trivial ctors and dtors; r=jrmuizel

This commit is contained in:
Ehsan Akhgari 2014-12-22 18:15:42 -05:00
parent 66d94da660
commit 5ea2e0a605
3 changed files with 87 additions and 0 deletions

View File

@ -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 {

View File

@ -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;
};

View File

@ -12,6 +12,7 @@ SOURCES += [
'TestNoArithmeticExprInArgument.cpp',
'TestNonHeapClass.cpp',
'TestStackClass.cpp',
'TestTrivialCtorDtor.cpp',
]
DISABLE_STL_WRAPPING = True