summaryrefslogtreecommitdiff
path: root/clang-plugin
diff options
context:
space:
mode:
authorPhilip Withnall <philip.withnall@collabora.co.uk>2014-11-19 17:25:13 +0000
committerPhilip Withnall <philip.withnall@collabora.co.uk>2014-11-19 17:25:13 +0000
commit915a744037d93abfcaab8b35e98e281cf88bb132 (patch)
tree4cbf6ce0c09c023036f1314ad050e695c5fce49d /clang-plugin
parent684905e83683bf89fb41b196708afd0d0659db8f (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.cpp24
-rw-r--r--clang-plugin/gerror-checker.h2
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;