diff options
author | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-11-19 17:25:13 +0000 |
---|---|---|
committer | Philip Withnall <philip.withnall@collabora.co.uk> | 2014-11-19 17:25:13 +0000 |
commit | 915a744037d93abfcaab8b35e98e281cf88bb132 (patch) | |
tree | 4cbf6ce0c09c023036f1314ad050e695c5fce49d /clang-plugin | |
parent | 684905e83683bf89fb41b196708afd0d0659db8f (diff) |
gerror: Fix crash when running on non-GLib code
If the GError checker was run on non-GLib code, the assertion about
having the typedef for the GError structure would fail and cause Clang
to abort. This was commonly being triggered when running the checker in
a configure script.
Fix that by gracefully and rapidly bailing out of the GError checker if
glib.h has not been included in this AST context.
Diffstat (limited to 'clang-plugin')
-rw-r--r-- | clang-plugin/gerror-checker.cpp | 24 | ||||
-rw-r--r-- | clang-plugin/gerror-checker.h | 2 |
2 files changed, 18 insertions, 8 deletions
diff --git a/clang-plugin/gerror-checker.cpp b/clang-plugin/gerror-checker.cpp index d627bb5..fbf92f5 100644 --- a/clang-plugin/gerror-checker.cpp +++ b/clang-plugin/gerror-checker.cpp @@ -462,7 +462,9 @@ GErrorChecker::checkPreCall (const CallEvent &call, } ASTContext &ast_context = context.getASTContext (); - this->_initialise_identifiers (ast_context); + if (!this->_initialise_identifiers (ast_context)) { + return; + } const IdentifierInfo *call_ident = call.getCalleeIdentifier (); @@ -506,7 +508,9 @@ GErrorChecker::evalCall (const CallExpr *call, } ASTContext &ast_context = context.getASTContext (); - this->_initialise_identifiers (ast_context); + if (!this->_initialise_identifiers (ast_context)) { + return false; + } const IdentifierInfo *call_ident = func_decl->getIdentifier (); @@ -557,7 +561,9 @@ GErrorChecker::checkBind (SVal loc, SVal val, const Stmt *stmt, } const ASTContext &ast_context = context.getASTContext (); - this->_initialise_identifiers (ast_context); + if (!this->_initialise_identifiers (ast_context)) { + return; + } QualType error_type = ast_context.getPointerType (this->_gerror_type); QualType value_type = region->getValueType (); @@ -674,7 +680,8 @@ GErrorChecker::_gerror_new (const Expr *call_expr, dyn_cast_or_null<SymbolicRegion> (allocated_region); if (symbolic_allocated_region != NULL) { - this->_initialise_identifiers (ast_context); + /* Should have been initialised on entry to the checker. */ + assert (this->_initialise_identifiers (ast_context)); DefinedOrUnknownSVal extent = symbolic_allocated_region->getExtent (sval_builder); @@ -1053,18 +1060,19 @@ GErrorChecker::_clear_gerror (SVal error_location, ErrorState::getClear (source_range)); } -void +/* Initialisation may fail if glib.h has not been included. + * Return true iff initialisation succeeded. */ +bool GErrorChecker::_initialise_identifiers (const ASTContext &context) const { if (!this->_gerror_type.isNull ()) { - return; + return true; } TypeManager manager = TypeManager (context); /* Types. */ this->_gerror_type = manager.find_type_by_name ("GError"); - assert (!this->_gerror_type.isNull ()); /* Functions. */ this->_identifier_g_set_error = @@ -1085,6 +1093,8 @@ GErrorChecker::_initialise_identifiers (const ASTContext &context) const &context.Idents.get ("g_propagate_error"); this->_identifier_g_propagate_prefixed_error = &context.Idents.get ("g_propagate_prefixed_error"); + + return (!this->_gerror_type.isNull ()); } void diff --git a/clang-plugin/gerror-checker.h b/clang-plugin/gerror-checker.h index 1f94dc5..5fdff0e 100644 --- a/clang-plugin/gerror-checker.h +++ b/clang-plugin/gerror-checker.h @@ -78,7 +78,7 @@ private: mutable IdentifierInfo *_identifier_g_propagate_error; mutable IdentifierInfo *_identifier_g_propagate_prefixed_error; - void _initialise_identifiers (const ASTContext &context) const; + bool _initialise_identifiers (const ASTContext &context) const; /* Cached bug reports. */ mutable std::unique_ptr<BuiltinBug> _overwrite_set; |