From 74fc5baca229922b244ad66d5819d6d765e2d9da Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksandermj@chromium.org>
Date: Wed, 24 Aug 2022 12:31:47 +0000
Subject: [PATCH] core: port GRegex/GMatchInfo to use autoptr()

The behavior of GRegex changed in 2.73.2 once it was ported from pcre1
to pcre2. In some cases it was made more strict, which is fine, in
other cases it exposed some change in how it behaves on certain
matches that is not extremely clear whether it's ok or not.

See https://gitlab.gnome.org/GNOME/glib/-/issues/2729
See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/601
See https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/621

Either way, one thing that was assumed was that initializing all
GRegex/GMatchInfo variables to NULL and making sure they're NULL
before they're initialized by glib (especially the GMatchInfo) was a
good and safer approach.

So, whenever possible, g_autoptr() is used to cleanup the allocated
GMatchInfo/GRegex variables, and otherwise, g_clear_pointer() is used
to ensure that no free/unref is attempted unless the given variable is
not NULL, and also so that the variable is reseted to NULL after being
disposed.
---
 libmm-glib/mm-location-gps-nmea.c             |  10 +-
 libmm-glib/mm-location-gps-raw.c              |   4 +-
 plugins/anydata/mm-broadband-modem-anydata.c  |  82 ++-
 .../cinterion/mm-modem-helpers-cinterion.c    |  62 +-
 .../tests/test-modem-helpers-cinterion.c      |  42 +-
 plugins/huawei/mm-broadband-modem-huawei.c    |  19 +-
 plugins/huawei/mm-modem-helpers-huawei.c      | 329 +++++------
 plugins/icera/mm-broadband-modem-icera.c      |  32 +-
 plugins/mbm/mm-modem-helpers-mbm.c            |  37 +-
 plugins/mtk/mm-broadband-modem-mtk.c          | 104 ++--
 plugins/novatel/mm-broadband-modem-novatel.c  |  45 +-
 plugins/option/mm-broadband-modem-option.c    |  42 +-
 plugins/quectel/mm-shared-quectel.c           |   3 +-
 plugins/sierra/mm-broadband-modem-sierra.c    |  41 +-
 plugins/sierra/mm-common-sierra.c             |   4 +-
 plugins/sierra/mm-modem-helpers-sierra.c      |  16 +-
 .../tests/test-modem-helpers-simtech.c        |  75 +--
 plugins/telit/mm-broadband-modem-telit.c      |   9 +-
 plugins/telit/mm-common-telit.c               |  16 +-
 plugins/telit/mm-modem-helpers-telit.c        |  13 +-
 plugins/ublox/mm-broadband-modem-ublox.c      |  11 +-
 plugins/ublox/mm-modem-helpers-ublox.c        | 152 ++---
 plugins/via/mm-broadband-modem-via.c          |  22 +-
 plugins/wavecom/mm-broadband-modem-wavecom.c  |   7 +-
 plugins/x22x/mm-broadband-modem-x22x.c        |  17 +-
 plugins/xmm/mm-modem-helpers-xmm.c            |  51 +-
 plugins/zte/mm-broadband-modem-zte.c          |  28 +-
 src/mm-broadband-modem.c                      | 187 ++----
 src/mm-modem-helpers.c                        | 538 +++++++-----------
 src/mm-port-serial-at.c                       |  11 +-
 src/mm-port-serial-gps.c                      |  14 +-
 src/mm-serial-parsers.c                       |  21 +-
 src/tests/test-modem-helpers.c                |  72 +--
 33 files changed, 849 insertions(+), 1267 deletions(-)

diff --git a/libmm-glib/mm-location-gps-nmea.c b/libmm-glib/mm-location-gps-nmea.c
index d23bc1462..b2ef69511 100644
--- a/libmm-glib/mm-location-gps-nmea.c
+++ b/libmm-glib/mm-location-gps-nmea.c
@@ -54,9 +54,7 @@ static gboolean
 check_append_or_replace (MMLocationGpsNmea *self,
                          const gchar *trace)
 {
-    /* By default, replace */
-    gboolean append_or_replace = FALSE;
-    GMatchInfo *match_info = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     if (G_UNLIKELY (!self->priv->sequence_regex))
         self->priv->sequence_regex = g_regex_new ("\\$..(?:ALM|GSV|RTE|SFI),(\\d),(\\d).*",
@@ -69,11 +67,11 @@ check_append_or_replace (MMLocationGpsNmea *self,
 
         /* If we don't have the first element of a sequence, append */
         if (mm_get_uint_from_match_info (match_info, 2, &index) && index != 1)
-            append_or_replace = TRUE;
+            return TRUE;
     }
-    g_match_info_free (match_info);
 
-    return append_or_replace;
+    /* By default, replace */
+    return FALSE;
 }
 
 static gboolean
diff --git a/libmm-glib/mm-location-gps-raw.c b/libmm-glib/mm-location-gps-raw.c
index fddc5629b..d776d1ca6 100644
--- a/libmm-glib/mm-location-gps-raw.c
+++ b/libmm-glib/mm-location-gps-raw.c
@@ -190,7 +190,7 @@ gboolean
 mm_location_gps_raw_add_trace (MMLocationGpsRaw *self,
                                const gchar *trace)
 {
-    GMatchInfo *match_info = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     /* Current implementation works only with $GPGGA and $GNGGA traces */
     do {
@@ -268,8 +268,6 @@ mm_location_gps_raw_add_trace (MMLocationGpsRaw *self,
         mm_get_double_from_match_info (match_info, 9, &self->priv->altitude);
     }
 
-    g_match_info_free (match_info);
-
     return TRUE;
 }
 
diff --git a/plugins/anydata/mm-broadband-modem-anydata.c b/plugins/anydata/mm-broadband-modem-anydata.c
index 95f8cbd27..36d72e56c 100644
--- a/plugins/anydata/mm-broadband-modem-anydata.c
+++ b/plugins/anydata/mm-broadband-modem-anydata.c
@@ -72,10 +72,10 @@ hstate_ready (MMIfaceModemCdma *self,
               GTask *task)
 {
     DetailedRegistrationStateResults *results;
-    GError *error = NULL;
-    const gchar *response;
-    GRegex *r;
-    GMatchInfo *match_info;
+    GError                           *error = NULL;
+    const gchar                      *response;
+    g_autoptr(GRegex)                 r = NULL;
+    g_autoptr(GMatchInfo)             match_info = NULL;
 
     results = g_task_get_task_data (task);
 
@@ -129,9 +129,6 @@ hstate_ready (MMIfaceModemCdma *self,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     g_task_return_pointer (task, g_memdup (results, sizeof (*results)), g_free);
     g_object_unref (task);
 }
@@ -142,10 +139,10 @@ state_ready (MMIfaceModemCdma *self,
              GTask *task)
 {
     DetailedRegistrationStateResults *results;
-    GError *error = NULL;
-    const gchar *response;
-    GRegex *r;
-    GMatchInfo *match_info;
+    GError                           *error = NULL;
+    const gchar                      *response;
+    g_autoptr(GRegex)                 r = NULL;
+    g_autoptr(GMatchInfo)             match_info = NULL;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
@@ -194,9 +191,6 @@ state_ready (MMIfaceModemCdma *self,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     /* Try for EVDO state too */
     mm_base_modem_at_command (MM_BASE_MODEM (self),
                               "*HSTATE?",
@@ -261,9 +255,14 @@ reset (MMIfaceModem *self,
 static void
 setup_ports (MMBroadbandModem *self)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *regex;
-    guint i;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  active_regex = NULL;
+    g_autoptr(GRegex)  inactive_regex = NULL;
+    g_autoptr(GRegex)  dormant_regex = NULL;
+    g_autoptr(GRegex)  offline_regex = NULL;
+    g_autoptr(GRegex)  regreq_regex = NULL;
+    g_autoptr(GRegex)  authreq_regex = NULL;
+    guint              i;
 
     /* Call parent's setup ports first always */
     MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_anydata_parent_class)->setup_ports (self);
@@ -271,48 +270,37 @@ setup_ports (MMBroadbandModem *self)
     ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
     ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
 
+    /* Data call has connected */
+    active_regex = g_regex_new ("\\r\\n\\*ACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+    /* Data call disconnected */
+    inactive_regex = g_regex_new ("\\r\\n\\*INACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+    /* Modem is now dormant */
+    dormant_regex = g_regex_new ("\\r\\n\\*DORMANT:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+    /* Network acquisition fail */
+    offline_regex = g_regex_new ("\\r\\n\\*OFFLINE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+    /* Registration fail */
+    regreq_regex = g_regex_new ("\\r\\n\\*REGREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+    /* Authentication fail */
+    authreq_regex = g_regex_new ("\\r\\n\\*AUTHREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
+
     /* Now reset the unsolicited messages  */
     for (i = 0; i < G_N_ELEMENTS (ports); i++) {
         if (!ports[i])
             continue;
 
         /* Data state notifications */
-
-        /* Data call has connected */
-        regex = g_regex_new ("\\r\\n\\*ACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
-
-        /* Data call disconnected */
-        regex = g_regex_new ("\\r\\n\\*INACTIVE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
-
-        /* Modem is now dormant */
-        regex = g_regex_new ("\\r\\n\\*DORMANT:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), active_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), inactive_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), dormant_regex, NULL, NULL, NULL);
 
         /* Abnormal state notifications
          *
          * FIXME: set 1X/EVDO registration state to UNKNOWN when these
          * notifications are received?
          */
-
-        /* Network acquisition fail */
-        regex = g_regex_new ("\\r\\n\\*OFFLINE:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
-
-        /* Registration fail */
-        regex = g_regex_new ("\\r\\n\\*REGREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
-
-        /* Authentication fail */
-        regex = g_regex_new ("\\r\\n\\*AUTHREQ:(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regex, NULL, NULL, NULL);
-        g_regex_unref (regex);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), offline_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), regreq_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), authreq_regex, NULL, NULL, NULL);
     }
 }
 
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
index a75eb5304..0bf3a0782 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
@@ -554,14 +554,14 @@ mm_cinterion_parse_cnmi_test (const gchar *response,
                               GArray **supported_bfr,
                               GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    GArray *tmp_supported_mode = NULL;
-    GArray *tmp_supported_mt = NULL;
-    GArray *tmp_supported_bm = NULL;
-    GArray *tmp_supported_ds = NULL;
-    GArray *tmp_supported_bfr = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GArray                *tmp_supported_mode = NULL;
+    GArray                *tmp_supported_mt = NULL;
+    GArray                *tmp_supported_bm = NULL;
+    GArray                *tmp_supported_ds = NULL;
+    GArray                *tmp_supported_bfr = NULL;
 
     if (!response) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response");
@@ -576,57 +576,48 @@ mm_cinterion_parse_cnmi_test (const gchar *response,
     g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
     if (!inner_error && g_match_info_matches (match_info)) {
         if (supported_mode) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_get_string_unquoted_from_match_info (match_info, 1);
             tmp_supported_mode = mm_parse_uint_list (str, &inner_error);
-            g_free (str);
             if (inner_error)
                 goto out;
         }
         if (supported_mt) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_get_string_unquoted_from_match_info (match_info, 2);
             tmp_supported_mt = mm_parse_uint_list (str, &inner_error);
-            g_free (str);
             if (inner_error)
                 goto out;
         }
         if (supported_bm) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_get_string_unquoted_from_match_info (match_info, 3);
             tmp_supported_bm = mm_parse_uint_list (str, &inner_error);
-            g_free (str);
             if (inner_error)
                 goto out;
         }
         if (supported_ds) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_get_string_unquoted_from_match_info (match_info, 4);
             tmp_supported_ds = mm_parse_uint_list (str, &inner_error);
-            g_free (str);
             if (inner_error)
                 goto out;
         }
         if (supported_bfr) {
-            gchar *str;
+            g_autofree gchar *str = NULL;
 
             str = mm_get_string_unquoted_from_match_info (match_info, 5);
             tmp_supported_bfr = mm_parse_uint_list (str, &inner_error);
-            g_free (str);
             if (inner_error)
                 goto out;
         }
     }
 
 out:
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_clear_pointer (&tmp_supported_mode, g_array_unref);
         g_clear_pointer (&tmp_supported_mt,   g_array_unref);
@@ -763,9 +754,9 @@ mm_cinterion_parse_sind_response (const gchar *response,
                                   guint *value,
                                   GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    guint errors = 0;
+    g_autoptr(GRegex)     r = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
+    guint                 errors = 0;
 
     if (!response) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response");
@@ -788,9 +779,6 @@ mm_cinterion_parse_sind_response (const gchar *response,
     } else
         errors++;
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (errors > 0) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Failed parsing ^SIND response");
         return FALSE;
@@ -836,8 +824,8 @@ mm_cinterion_parse_swwan_response (const gchar  *response,
                                    gpointer      log_object,
                                    GError      **error)
 {
-    GRegex                   *r;
-    GMatchInfo               *match_info;
+    g_autoptr(GRegex)         r = NULL;
+    g_autoptr(GMatchInfo)     match_info = NULL;
     GError                   *inner_error = NULL;
     MMBearerConnectionStatus  status;
 
@@ -883,9 +871,6 @@ mm_cinterion_parse_swwan_response (const gchar  *response,
         g_match_info_next (match_info, &inner_error);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN)
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "No state returned for CID %u", cid);
@@ -1078,10 +1063,10 @@ mm_cinterion_parse_slcc_list (const gchar *str,
                               GList      **out_list,
                               GError     **error)
 {
-    GRegex     *r;
-    GList      *list = NULL;
-    GError     *inner_error = NULL;
-    GMatchInfo *match_info  = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GList                 *list = NULL;
+    GError                *inner_error = NULL;
 
     static const MMCallDirection cinterion_call_direction[] = {
         [0] = MM_CALL_DIRECTION_OUTGOING,
@@ -1158,9 +1143,6 @@ mm_cinterion_parse_slcc_list (const gchar *str,
     }
 
 out:
-    g_clear_pointer (&match_info, g_match_info_free);
-    g_regex_unref (r);
-
     if (inner_error) {
         mm_cinterion_call_info_list_free (list);
         g_propagate_error (error, inner_error);
diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
index c3e7e9e5f..8332700b5 100644
--- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c
+++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
@@ -1192,18 +1192,17 @@ test_smong_response_no_match (void)
 /* Test ^SLCC URCs */
 
 static void
-common_test_slcc_urc (const gchar               *urc,
+common_test_slcc_urc (const gchar      *urc,
                       const MMCallInfo *expected_call_info_list,
-                      guint                      expected_call_info_list_size)
+                      guint             expected_call_info_list_size)
 {
-    GError     *error = NULL;
-    GRegex     *slcc_regex = NULL;
-    gboolean    result;
-    GMatchInfo *match_info = NULL;
-    gchar      *str;
-    GList      *call_info_list = NULL;
-    GList      *l;
-
+    g_autoptr(GRegex)      slcc_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *str = NULL;
+    GError                *error = NULL;
+    GList                 *call_info_list = NULL;
+    GList                 *l;
+    gboolean               result;
 
     slcc_regex = mm_cinterion_get_slcc_regex ();
 
@@ -1230,8 +1229,8 @@ common_test_slcc_urc (const gchar               *urc,
 
     for (l = call_info_list; l; l = g_list_next (l)) {
         const MMCallInfo *call_info = (const MMCallInfo *)(l->data);
-        gboolean                   found = FALSE;
-        guint                      i;
+        gboolean          found = FALSE;
+        guint             i;
 
         g_debug ("call at index %u: direction %s, state %s, number %s",
                  call_info->index,
@@ -1248,10 +1247,6 @@ common_test_slcc_urc (const gchar               *urc,
         g_assert (found);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (slcc_regex);
-    g_free (str);
-
     mm_cinterion_call_info_list_free (call_info_list);
 }
 
@@ -1322,12 +1317,12 @@ common_test_ctzu_urc (const gchar *urc,
                       gint         expected_offset,
                       gint         expected_dst_offset)
 {
-    GError            *error = NULL;
-    GRegex            *ctzu_regex = NULL;
-    gboolean           result;
-    GMatchInfo        *match_info = NULL;
-    gchar             *iso8601;
-    MMNetworkTimezone *tz = NULL;
+    g_autoptr(GRegex)      ctzu_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *iso8601 = NULL;
+    GError                *error = NULL;
+    gboolean               result;
+    MMNetworkTimezone     *tz = NULL;
 
     ctzu_regex = mm_cinterion_get_ctzu_regex ();
 
@@ -1342,7 +1337,6 @@ common_test_ctzu_urc (const gchar *urc,
 
     g_assert (iso8601);
     g_assert_cmpstr (expected_iso8601, ==, iso8601);
-    g_free (iso8601);
 
     g_assert (tz);
     g_assert_cmpint (expected_offset, ==, mm_network_timezone_get_offset (tz));
@@ -1351,8 +1345,6 @@ common_test_ctzu_urc (const gchar *urc,
         g_assert_cmpuint ((guint)expected_dst_offset, ==, mm_network_timezone_get_dst_offset (tz));
 
     g_object_unref (tz);
-    g_match_info_free (match_info);
-    g_regex_unref (ctzu_regex);
 }
 
 static void
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c
index 866707d63..c7c68b9f3 100644
--- a/plugins/huawei/mm-broadband-modem-huawei.c
+++ b/plugins/huawei/mm-broadband-modem-huawei.c
@@ -627,12 +627,13 @@ load_unlock_retries_finish (MMIfaceModem *self,
                             GAsyncResult *res,
                             GError **error)
 {
-    MMUnlockRetries *unlock_retries;
-    const gchar *result;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint i;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    MMUnlockRetries       *unlock_retries;
+    const gchar           *result;
+    GError                *match_error = NULL;
+    guint                  i;
+
     MMModemLock locks[4] = {
         MM_MODEM_LOCK_SIM_PUK,
         MM_MODEM_LOCK_SIM_PIN,
@@ -657,9 +658,6 @@ load_unlock_retries_finish (MMIfaceModem *self,
                          MM_CORE_ERROR_FAILED,
                          "Could not parse ^CPIN results: Response didn't match (%s)",
                          result);
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return NULL;
     }
 
@@ -683,9 +681,6 @@ load_unlock_retries_finish (MMIfaceModem *self,
         mm_unlock_retries_set (unlock_retries, locks[i], num);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     return unlock_retries;
 }
 
diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c
index 3ded62379..67bb7089b 100644
--- a/plugins/huawei/mm-modem-helpers-huawei.c
+++ b/plugins/huawei/mm-modem-helpers-huawei.c
@@ -39,8 +39,6 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response,
                                       gboolean *ipv6_connected,
                                       GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
     GError *inner_error = NULL;
 
     if (!response ||
@@ -71,6 +69,9 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response,
 
     /* If multiple fields available, try first parsing method */
     if (strchr (response, ',')) {
+        g_autoptr(GRegex)     r = NULL;
+        g_autoptr(GMatchInfo) match_info = NULL;
+
         r = g_regex_new ("\\^NDISSTAT(?:QRY)?(?:Qry)?:\\s*(\\d),([^,]*),([^,]*),([^,\\r\\n]*)(?:\\r\\n)?"
                          "(?:\\^NDISSTAT:|\\^NDISSTATQRY:)?\\s*,?(\\d)?,?([^,]*)?,?([^,]*)?,?([^,\\r\\n]*)?(?:\\r\\n)?",
                          G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
@@ -108,12 +109,12 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response,
                 ip_type_field += 4;
             }
         }
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
     }
     /* No separate IPv4/IPv6 info given just connected/not connected */
     else {
+        g_autoptr(GRegex)     r = NULL;
+        g_autoptr(GMatchInfo) match_info = NULL;
+
         r = g_regex_new ("\\^NDISSTAT(?:QRY)?(?:Qry)?:\\s*(\\d)(?:\\r\\n)?",
                          G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
                          0, NULL);
@@ -134,9 +135,6 @@ mm_huawei_parse_ndisstatqry_response (const gchar *response,
                 *ipv4_connected = (gboolean)connected;
             }
         }
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
     }
 
     if (!ipv4_available && !ipv6_available) {
@@ -208,10 +206,10 @@ mm_huawei_parse_dhcp_response (const char *reply,
                                guint *out_dns2,
                                GError **error)
 {
-    gboolean matched;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gboolean               matched;
+    GError                *match_error = NULL;
 
     g_assert (reply != NULL);
     g_assert (out_address != NULL);
@@ -257,8 +255,6 @@ mm_huawei_parse_dhcp_response (const char *reply,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return matched;
 }
 
@@ -276,10 +272,10 @@ mm_huawei_parse_sysinfo_response (const char *reply,
                                   guint *out_sys_submode,
                                   GError **error)
 {
-    gboolean matched;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gboolean               matched;
+    GError                *match_error = NULL;
 
     g_assert (out_srv_status != NULL);
     g_assert (out_srv_domain != NULL);
@@ -323,8 +319,6 @@ mm_huawei_parse_sysinfo_response (const char *reply,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return matched;
 }
 
@@ -341,10 +335,10 @@ mm_huawei_parse_sysinfoex_response (const char *reply,
                                     guint *out_sys_submode,
                                     GError **error)
 {
-    gboolean matched;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gboolean               matched;
+    GError                *match_error = NULL;
 
     g_assert (out_srv_status != NULL);
     g_assert (out_srv_domain != NULL);
@@ -387,8 +381,6 @@ mm_huawei_parse_sysinfoex_response (const char *reply,
         mm_get_uint_from_match_info (match_info, 8, out_sys_submode);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return matched;
 }
 
@@ -1189,17 +1181,23 @@ mm_huawei_parse_syscfgex_response (const gchar *response,
 /*****************************************************************************/
 /* ^NWTIME response parser */
 
-gboolean mm_huawei_parse_nwtime_response (const gchar *response,
-                                          gchar **iso8601p,
-                                          MMNetworkTimezone **tzp,
-                                          GError **error)
+gboolean
+mm_huawei_parse_nwtime_response (const gchar        *response,
+                                 gchar             **iso8601p,
+                                 MMNetworkTimezone **tzp,
+                                 GError            **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dt = 0;
-    gint tz = 0;
-    gboolean ret = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  year = 0;
+    guint                  month = 0;
+    guint                  day = 0;
+    guint                  hour = 0;
+    guint                  minute = 0;
+    guint                  second = 0;
+    guint                  dt = 0;
+    gint                   tz = 0;
 
     g_assert (iso8601p || tzp); /* at least one */
 
@@ -1211,75 +1209,72 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response,
             g_propagate_error (error, match_error);
             g_prefix_error (error, "Could not parse ^NWTIME results: ");
         } else {
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
+            g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                  "Couldn't match ^NWTIME reply");
         }
-    } else {
-        /* Remember that g_match_info_get_match_count() includes match #0 */
-        g_assert (g_match_info_get_match_count (match_info) >= 9);
-
-        if (mm_get_uint_from_match_info (match_info, 1, &year) &&
-            mm_get_uint_from_match_info (match_info, 2, &month) &&
-            mm_get_uint_from_match_info (match_info, 3, &day) &&
-            mm_get_uint_from_match_info (match_info, 4, &hour) &&
-            mm_get_uint_from_match_info (match_info, 5, &minute) &&
-            mm_get_uint_from_match_info (match_info, 6, &second) &&
-            mm_get_int_from_match_info  (match_info, 7, &tz) &&
-            mm_get_uint_from_match_info (match_info, 8, &dt)) {
-
-            ret = TRUE;
-
-            /* adjust year */
-            if (year < 100)
-                year += 2000;
-            /*
-             * tz = timezone offset in 15 minute intervals
-             * dt = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours
-             *      other values are marked reserved.
-             */
-            if (iso8601p) {
-                /* Return ISO-8601 format date/time string */
-                *iso8601p = mm_new_iso8601_time (year, month, day, hour,
-                                                 minute, second,
-                                                 TRUE, (tz * 15) + (dt * 60),
-                                                 error);
-                ret = (*iso8601p != NULL);
-            }
-            if (tzp) {
-                *tzp = mm_network_timezone_new ();
-                mm_network_timezone_set_offset (*tzp, tz * 15);
-                mm_network_timezone_set_dst_offset (*tzp, dt * 60);
-            }
+        return FALSE;
+    }
 
-        } else {
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
-                                 "Failed to parse ^NWTIME reply");
+    /* Remember that g_match_info_get_match_count() includes match #0 */
+    g_assert (g_match_info_get_match_count (match_info) >= 9);
+
+    if (mm_get_uint_from_match_info (match_info, 1, &year) &&
+        mm_get_uint_from_match_info (match_info, 2, &month) &&
+        mm_get_uint_from_match_info (match_info, 3, &day) &&
+        mm_get_uint_from_match_info (match_info, 4, &hour) &&
+        mm_get_uint_from_match_info (match_info, 5, &minute) &&
+        mm_get_uint_from_match_info (match_info, 6, &second) &&
+        mm_get_int_from_match_info  (match_info, 7, &tz) &&
+        mm_get_uint_from_match_info (match_info, 8, &dt)) {
+
+        /* adjust year */
+        if (year < 100)
+            year += 2000;
+        /*
+         * tz = timezone offset in 15 minute intervals
+         * dt = daylight adjustment, 0 = none, 1 = 1 hour, 2 = 2 hours
+         *      other values are marked reserved.
+         */
+        if (tzp) {
+            *tzp = mm_network_timezone_new ();
+            mm_network_timezone_set_offset (*tzp, tz * 15);
+            mm_network_timezone_set_dst_offset (*tzp, dt * 60);
+        }
+        if (iso8601p) {
+            /* Return ISO-8601 format date/time string */
+            *iso8601p = mm_new_iso8601_time (year, month, day, hour,
+                                             minute, second,
+                                             TRUE, (tz * 15) + (dt * 60),
+                                             error);
+            return (*iso8601p != NULL);
         }
-    }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
+        return TRUE;
+    }
 
-    return ret;
+    g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                         "Failed to parse ^NWTIME reply");
+    return FALSE;
 }
 
 /*****************************************************************************/
 /* ^TIME response parser */
 
-gboolean mm_huawei_parse_time_response (const gchar *response,
-                                        gchar **iso8601p,
-                                        MMNetworkTimezone **tzp,
-                                        GError **error)
+gboolean
+mm_huawei_parse_time_response (const gchar        *response,
+                               gchar             **iso8601p,
+                               MMNetworkTimezone **tzp,
+                               GError            **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint year, month, day, hour, minute, second;
-    gboolean ret = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  year = 0;
+    guint                  month = 0;
+    guint                  day = 0;
+    guint                  hour = 0;
+    guint                  minute = 0;
+    guint                  second = 0;
 
     g_assert (iso8601p || tzp); /* at least one */
 
@@ -1306,41 +1301,35 @@ gboolean mm_huawei_parse_time_response (const gchar *response,
                                  MM_CORE_ERROR_FAILED,
                                  "Couldn't match ^TIME reply");
         }
-    } else {
-        /* Remember that g_match_info_get_match_count() includes match #0 */
-        g_assert (g_match_info_get_match_count (match_info) >= 7);
-
-        if (mm_get_uint_from_match_info (match_info, 1, &year) &&
-            mm_get_uint_from_match_info (match_info, 2, &month) &&
-            mm_get_uint_from_match_info (match_info, 3, &day) &&
-            mm_get_uint_from_match_info (match_info, 4, &hour) &&
-            mm_get_uint_from_match_info (match_info, 5, &minute) &&
-            mm_get_uint_from_match_info (match_info, 6, &second)) {
-            ret = TRUE;
-
-            /* adjust year */
-            if (year < 100)
-                year += 2000;
+        return FALSE;
+    }
 
-            /* Return ISO-8601 format date/time string */
-            if (iso8601p) {
-                *iso8601p = mm_new_iso8601_time (year, month, day, hour,
-                                                 minute, second, FALSE, 0,
-                                                 error);
-                ret = (*iso8601p != NULL);
-            }
-        } else {
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
-                                 "Failed to parse ^TIME reply");
+    /* Remember that g_match_info_get_match_count() includes match #0 */
+    g_assert (g_match_info_get_match_count (match_info) >= 7);
+
+    if (mm_get_uint_from_match_info (match_info, 1, &year) &&
+        mm_get_uint_from_match_info (match_info, 2, &month) &&
+        mm_get_uint_from_match_info (match_info, 3, &day) &&
+        mm_get_uint_from_match_info (match_info, 4, &hour) &&
+        mm_get_uint_from_match_info (match_info, 5, &minute) &&
+        mm_get_uint_from_match_info (match_info, 6, &second)) {
+        /* adjust year */
+        if (year < 100)
+            year += 2000;
+
+        /* Return ISO-8601 format date/time string */
+        if (iso8601p) {
+            *iso8601p = mm_new_iso8601_time (year, month, day, hour,
+                                             minute, second, FALSE, 0,
+                                             error);
+            return (*iso8601p != NULL);
         }
+        return TRUE;
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    return ret;
+    g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                         "Failed to parse ^TIME reply");
+    return FALSE;
 }
 
 /*****************************************************************************/
@@ -1356,11 +1345,9 @@ mm_huawei_parse_hcsq_response (const gchar *response,
                                guint *out_value5,
                                GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    gboolean ret = FALSE;
-    char *s;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
 
     r = g_regex_new ("\\^HCSQ:\\s*\"?([a-zA-Z]*)\"?,(\\d+),?(\\d+)?,?(\\d+)?,?(\\d+)?,?(\\d+)?$", 0, 0, NULL);
     g_assert (r != NULL);
@@ -1370,27 +1357,24 @@ mm_huawei_parse_hcsq_response (const gchar *response,
             g_propagate_error (error, match_error);
             g_prefix_error (error, "Could not parse ^HCSQ results: ");
         } else {
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
+            g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                  "Couldn't match ^HCSQ reply");
         }
-        goto done;
+        return FALSE;
     }
 
     /* Remember that g_match_info_get_match_count() includes match #0 */
     if (g_match_info_get_match_count (match_info) < 3) {
-        g_set_error_literal (error,
-                             MM_CORE_ERROR,
-                             MM_CORE_ERROR_FAILED,
+        g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                              "Not enough elements in ^HCSQ reply");
-        goto done;
+        return FALSE;
     }
 
     if (out_act) {
+        g_autofree gchar *s = NULL;
+
         s = g_match_info_fetch (match_info, 1);
         *out_act = mm_string_to_access_tech (s);
-        g_free (s);
     }
 
     if (out_value1)
@@ -1404,13 +1388,7 @@ mm_huawei_parse_hcsq_response (const gchar *response,
     if (out_value5)
         mm_get_uint_from_match_info (match_info, 6, out_value5);
 
-    ret = TRUE;
-
-done:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    return ret;
+    return TRUE;
 }
 
 /*****************************************************************************/
@@ -1422,11 +1400,12 @@ mm_huawei_parse_cvoice_response (const gchar  *response,
                                  guint        *out_bits,
                                  GError      **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint supported = 0, hz = 0, bits = 0;
-    gboolean ret = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  supported = 0;
+    guint                  hz = 0;
+    guint                  bits = 0;
 
     /* ^CVOICE: <0=supported,1=unsupported>,<hz>,<bits>,<unknown> */
     r = g_regex_new ("\\^CVOICE:\\s*(\\d)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)$", 0, 0, NULL);
@@ -1442,37 +1421,31 @@ mm_huawei_parse_cvoice_response (const gchar  *response,
                                  MM_CORE_ERROR_FAILED,
                                  "Couldn't match ^CVOICE reply");
         }
-    } else {
-        /* Remember that g_match_info_get_match_count() includes match #0 */
-        g_assert (g_match_info_get_match_count (match_info) >= 5);
-
-        if (mm_get_uint_from_match_info (match_info, 1, &supported) &&
-            mm_get_uint_from_match_info (match_info, 2, &hz) &&
-            mm_get_uint_from_match_info (match_info, 3, &bits)) {
-            if (supported == 0) {
-                if (out_hz)
-                    *out_hz = hz;
-                if (out_bits)
-                    *out_bits = bits;
-                ret = TRUE;
-            } else {
-                g_set_error_literal (error,
-                                     MM_CORE_ERROR,
-                                     MM_CORE_ERROR_UNSUPPORTED,
-                                     "^CVOICE not supported by this device");
-            }
-        } else {
-            g_set_error_literal (error,
-                                 MM_CORE_ERROR,
-                                 MM_CORE_ERROR_FAILED,
-                                 "Failed to parse ^CVOICE reply");
-        }
+        return FALSE;
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
+    /* Remember that g_match_info_get_match_count() includes match #0 */
+    g_assert (g_match_info_get_match_count (match_info) >= 5);
+
+    if (mm_get_uint_from_match_info (match_info, 1, &supported) &&
+        mm_get_uint_from_match_info (match_info, 2, &hz) &&
+        mm_get_uint_from_match_info (match_info, 3, &bits)) {
+        if (supported == 0) {
+            if (out_hz)
+                *out_hz = hz;
+            if (out_bits)
+                *out_bits = bits;
+            return TRUE;
+        }
+
+        g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+                             "^CVOICE not supported by this device");
+        return FALSE;
+    }
 
-    return ret;
+    g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                         "Failed to parse ^CVOICE reply");
+    return FALSE;
 }
 
 /*****************************************************************************/
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
index 897d25626..759985e00 100644
--- a/plugins/icera/mm-broadband-modem-icera.c
+++ b/plugins/icera/mm-broadband-modem-icera.c
@@ -123,12 +123,12 @@ load_supported_modes_finish (MMIfaceModem *self,
                              GAsyncResult *res,
                              GError **error)
 {
-    GArray *combinations = NULL;
-    const gchar *response;
-    gchar **split = NULL;
-    GMatchInfo *match_info;
-    GRegex *r;
-    guint i;
+    GArray                 *combinations = NULL;
+    const gchar            *response;
+    gchar                 **split = NULL;
+    g_autoptr(GMatchInfo)   match_info = NULL;
+    g_autoptr(GRegex)       r = NULL;
+    guint                   i;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
     if (!response)
@@ -145,18 +145,13 @@ load_supported_modes_finish (MMIfaceModem *self,
 
     g_regex_match (r, response, 0, &match_info);
     if (g_match_info_matches (match_info)) {
-        gchar *aux;
+        g_autofree gchar *aux = NULL;
 
         aux = mm_get_string_unquoted_from_match_info (match_info, 1);
-        if (aux) {
+        if (aux)
             split = g_strsplit (aux, ",", -1);
-            g_free (aux);
-        }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (!split) {
         g_set_error (error,
                      MM_CORE_ERROR,
@@ -1122,11 +1117,12 @@ icera_band_to_mm (const char *icera)
 }
 
 static GSList *
-parse_bands (const gchar *response, guint32 *out_len)
+parse_bands (const gchar *response,
+             guint32     *out_len)
 {
-    GRegex *r;
-    GMatchInfo *info;
-    GSList *bands = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  info = NULL;
+    GSList                *bands = NULL;
 
     g_return_val_if_fail (out_len != NULL, NULL);
 
@@ -1163,8 +1159,6 @@ parse_bands (const gchar *response, guint32 *out_len)
         g_free (enabled);
         g_match_info_next (info, NULL);
     }
-    g_match_info_free (info);
-    g_regex_unref (r);
 
     return bands;
 }
diff --git a/plugins/mbm/mm-modem-helpers-mbm.c b/plugins/mbm/mm-modem-helpers-mbm.c
index 31fbb3763..846cc4d66 100644
--- a/plugins/mbm/mm-modem-helpers-mbm.c
+++ b/plugins/mbm/mm-modem-helpers-mbm.c
@@ -55,15 +55,17 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response,
                                MMBearerIpConfig **out_ip6_config,
                                GError **error)
 {
-    MMBearerIpConfig **ip_config = NULL;
-    gboolean got_address = FALSE, got_gw = FALSE, got_dns = FALSE;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    gchar *dns[3] = { 0 };
-    guint dns_idx = 0;
-    int family = AF_INET;
-    MMBearerIpMethod method = MM_BEARER_IP_METHOD_STATIC;
+    MMBearerIpConfig     **ip_config = NULL;
+    gboolean               got_address = FALSE;
+    gboolean               got_gw = FALSE;
+    gboolean               got_dns = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    gchar                 *dns[3] = { 0 };
+    guint                  dns_idx = 0;
+    int                    family = AF_INET;
+    MMBearerIpMethod       method = MM_BEARER_IP_METHOD_STATIC;
 
     g_return_val_if_fail (out_ip4_config, FALSE);
     g_return_val_if_fail (out_ip6_config, FALSE);
@@ -108,14 +110,17 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response,
                                  MM_CORE_ERROR_FAILED,
                                  "Couldn't match " E2IPCFG_TAG " reply");
         }
-        goto done;
+        return FALSE;
     }
 
     *ip_config = mm_bearer_ip_config_new ();
     mm_bearer_ip_config_set_method (*ip_config, method);
     while (g_match_info_matches (match_info)) {
-        char *id = g_match_info_fetch (match_info, 1);
-        char *str = g_match_info_fetch (match_info, 2);
+        g_autofree gchar *id = NULL;
+        g_autofree gchar *str = NULL;
+
+        id = g_match_info_fetch (match_info, 1);
+        str = g_match_info_fetch (match_info, 2);
 
         switch (atoi (id)) {
         case 1:
@@ -140,8 +145,6 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response,
         default:
             break;
         }
-        g_free (id);
-        g_free (str);
         g_match_info_next (match_info, NULL);
     }
 
@@ -156,12 +159,10 @@ mm_mbm_parse_e2ipcfg_response (const gchar *response,
         *ip_config = NULL;
         g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                              "Got incomplete IP configuration from " E2IPCFG_TAG);
+        return FALSE;
     }
 
-done:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-    return !!*ip_config;
+    return TRUE;
 }
 
 /*****************************************************************************/
diff --git a/plugins/mtk/mm-broadband-modem-mtk.c b/plugins/mtk/mm-broadband-modem-mtk.c
index 0ceca795f..869784f30 100644
--- a/plugins/mtk/mm-broadband-modem-mtk.c
+++ b/plugins/mtk/mm-broadband-modem-mtk.c
@@ -67,13 +67,16 @@ load_unlock_retries_ready (MMBaseModem *self,
                            GAsyncResult *res,
                            GTask *task)
 {
-    const gchar *response;
-    GError *error = NULL;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    GRegex *r = NULL;
-    gint pin1, puk1, pin2, puk2;
-    MMUnlockRetries *retries;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    const gchar           *response;
+    GError                *error = NULL;
+    GError                *match_error = NULL;
+    gint                   pin1;
+    gint                   puk1;
+    gint                   pin2;
+    gint                   puk2;
+    MMUnlockRetries       *retries;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
@@ -91,14 +94,11 @@ load_unlock_retries_ready (MMBaseModem *self,
     g_assert (r != NULL);
 
     if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)){
-        if (match_error) {
-            g_propagate_error (&error, match_error);
-        } else {
-            g_set_error (&error,
-                         MM_CORE_ERROR,
-                         MM_CORE_ERROR_FAILED,
-                         "Failed to match EPINC response: %s", response);
-        }
+        if (match_error)
+            g_task_return_error (task, match_error);
+        else
+            g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+                                     "Failed to match EPINC response: %s", response);
         g_task_return_error (task, error);
     } else if (!mm_get_int_from_match_info (match_info, 1, &pin1) ||
                !mm_get_int_from_match_info (match_info, 2, &pin2) ||
@@ -120,9 +120,6 @@ load_unlock_retries_ready (MMBaseModem *self,
         g_task_return_pointer (task, retries, g_object_unref);
     }
     g_object_unref (task);
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 }
 
 static void
@@ -178,14 +175,14 @@ get_supported_modes_ready (MMBaseModem *self,
                            GTask *task)
 
 {
-    const gchar *response;
-    GError *error = NULL;
-    GMatchInfo *match_info = NULL;
-    MMModemModeCombination mode;
-    GArray *combinations;
-    GRegex *r;
-    GError *match_error = NULL;
-    gint device_type;
+    g_autoptr(GMatchInfo)   match_info = NULL;
+    g_autoptr(GRegex)       r = NULL;
+    const gchar            *response;
+    GError                 *error = NULL;
+    MMModemModeCombination  mode;
+    GArray                 *combinations;
+    GError                 *match_error = NULL;
+    gint                    device_type;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
@@ -205,9 +202,6 @@ get_supported_modes_ready (MMBaseModem *self,
             g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                                      "Failed to match EGMR response: %s", response);
         g_object_unref (task);
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return;
     }
 
@@ -216,9 +210,6 @@ get_supported_modes_ready (MMBaseModem *self,
                                  "Failed to parse the allowed mode response: '%s'",
                                  response);
         g_object_unref (task);
-
-        g_regex_unref (r);
-        g_match_info_free (match_info);
         return;
     }
 
@@ -271,9 +262,6 @@ get_supported_modes_ready (MMBaseModem *self,
     */
     g_task_return_pointer (task, combinations, (GDestroyNotify)g_array_unref);
     g_object_unref (task);
-
-    g_regex_unref (r);
-    g_match_info_free (match_info);
 }
 
 static void
@@ -307,17 +295,16 @@ load_current_modes_finish (MMIfaceModem *self,
                            MMModemMode *preferred,
                            GError **error)
 {
-    const gchar *response;
-    GMatchInfo *match_info = NULL;
-    GRegex *r;
-    gint erat_mode = -1;
-    gint erat_pref = -1;
-    GError *match_error = NULL;
-    gboolean result = FALSE;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    const gchar           *response;
+    gint                   erat_mode = -1;
+    gint                   erat_pref = -1;
+    GError                *match_error = NULL;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
     if (!response)
-        return result;
+        return FALSE;
 
     r = g_regex_new (
                 "\\+ERAT:\\s*[0-9]+,\\s*[0-9]+,\\s*([0-9]+),\\s*([0-9]+)",
@@ -329,30 +316,22 @@ load_current_modes_finish (MMIfaceModem *self,
     if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)) {
         if (match_error)
             g_propagate_error (error, match_error);
-        else {
-            g_set_error (error,
-                         MM_CORE_ERROR,
-                         MM_CORE_ERROR_FAILED,
+        else
+            g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                          "Couldn't parse +ERAT response: '%s'",
                          response);
-
-        }
-        goto done;
+        return FALSE;
     }
 
     if (!mm_get_int_from_match_info (match_info, 1, &erat_mode) ||
         !mm_get_int_from_match_info (match_info, 2, &erat_pref)) {
-        g_set_error (error,
-                     MM_CORE_ERROR,
-                     MM_CORE_ERROR_FAILED,
+        g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "Failed to parse the ERAT response: m=%d p=%d",
                      erat_mode, erat_pref);
-            goto done;
+        return FALSE;
     }
 
     /* Correctly parsed! */
-    result = TRUE;
-
     switch (erat_mode) {
         case 0:
             *allowed = MM_MODEM_MODE_2G;
@@ -376,9 +355,8 @@ load_current_modes_finish (MMIfaceModem *self,
             *allowed = MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G;
             break;
         default:
-            result = FALSE;
             mm_obj_dbg (self, "unsupported allowed mode reported in +ERAT: %d", erat_mode);
-            goto done;
+            return FALSE;
     }
 
     switch (erat_pref) {
@@ -395,17 +373,11 @@ load_current_modes_finish (MMIfaceModem *self,
             *preferred = MM_MODEM_MODE_4G;
             break;
         default:
-            result = FALSE;
             mm_obj_dbg (self, "unsupported preferred mode %d", erat_pref);
-            goto done;
+            return FALSE;
     }
 
-done:
-    if (r)
-        g_regex_unref (r);
-    g_match_info_free (match_info);
-
-    return result;
+    return TRUE;
 }
 
 static void
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c
index 1cc88e906..46bf438a2 100644
--- a/plugins/novatel/mm-broadband-modem-novatel.c
+++ b/plugins/novatel/mm-broadband-modem-novatel.c
@@ -159,12 +159,12 @@ nwrat_query_ready (MMBaseModem *self,
                    GTask *task)
 {
     LoadCurrentModesResult *result;
-    GError *error = NULL;
-    const gchar *response;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    gint a = -1;
-    gint b = -1;
+    GError                 *error = NULL;
+    const gchar            *response;
+    g_autoptr(GRegex)       r = NULL;
+    g_autoptr(GMatchInfo)   match_info = NULL;
+    gint                    a = -1;
+    gint                    b = -1;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (!response) {
@@ -187,8 +187,6 @@ nwrat_query_ready (MMBaseModem *self,
                                      "Couldn't match NWRAT reply: %s",
                                      response);
         g_object_unref (task);
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return;
     }
 
@@ -203,8 +201,6 @@ nwrat_query_ready (MMBaseModem *self,
             "Failed to parse mode/tech response '%s': invalid modes reported",
             response);
         g_object_unref (task);
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return;
     }
 
@@ -239,9 +235,6 @@ nwrat_query_ready (MMBaseModem *self,
         break;
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     g_task_return_pointer (task, result, g_free);
     g_object_unref (task);
 }
@@ -1396,13 +1389,18 @@ parse_nwltime_reply (const char *response,
                      MMNetworkTimezone **out_tz,
                      GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint year, month, day, hour, minute, second;
-    gchar *result = NULL;
-    gint utc_offset = 0;
-    gboolean success = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  year;
+    guint                  month;
+    guint                  day;
+    guint                  hour;
+    guint                  minute;
+    guint                  second;
+    g_autofree gchar      *result = NULL;
+    gint                   utc_offset = 0;
+    gboolean               success = FALSE;
 
     /* Sample reply: 2013.3.27.15.47.19.2.-5 */
     r = g_regex_new ("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\\.([\\-\\+\\d]+)$", 0, 0, NULL);
@@ -1429,7 +1427,6 @@ parse_nwltime_reply (const char *response,
             mm_get_uint_from_match_info (match_info, 5, &minute) &&
             mm_get_uint_from_match_info (match_info, 6, &second) &&
             mm_get_int_from_match_info (match_info, 8, &utc_offset)) {
-
             result = mm_new_iso8601_time (year, month, day, hour, minute, second,
                                           TRUE, utc_offset * 60, error);
             if (out_tz) {
@@ -1447,12 +1444,8 @@ parse_nwltime_reply (const char *response,
     }
 
     if (out_iso_8601)
-        *out_iso_8601 = result;
-    else
-        g_free (result);
+        *out_iso_8601 = g_steal_pointer (&result);
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return success;
 }
 
diff --git a/plugins/option/mm-broadband-modem-option.c b/plugins/option/mm-broadband-modem-option.c
index 5919364da..dcecd5b08 100644
--- a/plugins/option/mm-broadband-modem-option.c
+++ b/plugins/option/mm-broadband-modem-option.c
@@ -362,12 +362,10 @@ static gboolean
 parse_ossys_response (const gchar *response,
                       MMModemAccessTechnology *access_technology)
 {
-    MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
-    const gchar *p;
-    GRegex *r;
-    GMatchInfo *match_info;
-    gchar *str;
-    gboolean success = FALSE;
+    MMModemAccessTechnology  current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    const gchar             *p;
+    g_autoptr(GRegex)        r = NULL;
+    g_autoptr(GMatchInfo)    match_info = NULL;
 
     p = mm_strip_tag (response, "_OSSYS:");
     r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL);
@@ -375,17 +373,15 @@ parse_ossys_response (const gchar *response,
 
     g_regex_match (r, p, 0, &match_info);
     if (g_match_info_matches (match_info)) {
+        g_autofree gchar *str = NULL;
+
         str = g_match_info_fetch (match_info, 2);
         if (str && ossys_to_mm (str[0], &current)) {
             *access_technology = current;
-            success = TRUE;
-        }
-        g_free (str);
+            return TRUE;
+       }
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    return success;
+    return FALSE;
 }
 
 static void
@@ -445,12 +441,10 @@ static gboolean
 parse_octi_response (const gchar *response,
                      MMModemAccessTechnology *access_technology)
 {
-    MMModemAccessTechnology current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
-    const gchar *p;
-    GRegex *r;
-    GMatchInfo *match_info;
-    gchar *str;
-    gboolean success = FALSE;
+    MMModemAccessTechnology  current = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    const gchar             *p;
+    g_autoptr(GRegex)        r = NULL;
+    g_autoptr(GMatchInfo)    match_info = NULL;
 
     p = mm_strip_tag (response, "_OCTI:");
     r = g_regex_new ("(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL);
@@ -458,17 +452,15 @@ parse_octi_response (const gchar *response,
 
     g_regex_match (r, p, 0, &match_info);
     if (g_match_info_matches (match_info)) {
+        g_autofree gchar *str = NULL;
+
         str = g_match_info_fetch (match_info, 2);
         if (str && octi_to_mm (str[0], &current)) {
             *access_technology = current;
-            success = TRUE;
+            return TRUE;
         }
-        g_free (str);
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    return success;
+    return FALSE;
 }
 
 static void
diff --git a/plugins/quectel/mm-shared-quectel.c b/plugins/quectel/mm-shared-quectel.c
index ab079436d..c383dc05a 100644
--- a/plugins/quectel/mm-shared-quectel.c
+++ b/plugins/quectel/mm-shared-quectel.c
@@ -440,8 +440,8 @@ mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem        *self,
     Private        *priv;
     MMPortSerialAt *ports[2];
     GTask          *task;
-    GRegex         *pattern;
     guint           i;
+    g_autoptr(GRegex)  pattern = NULL;
 
     priv = get_private (MM_SHARED_QUECTEL (self));

@@ -464,7 +464,6 @@ mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem        *self,
                 NULL);
     }
 
-    g_regex_unref (pattern);
     mm_obj_dbg (self, "+QUSIM detection set up");
 
     /* Now, if available, setup parent logic */
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
index 3ac20808f..bae8e3449 100644
--- a/plugins/sierra/mm-broadband-modem-sierra.c
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
@@ -624,7 +624,7 @@ load_current_modes_finish (MMIfaceModem *self,
                            MMModemMode *preferred,
                            GError **error)
 {
-    LoadCurrentModesResult *result;
+    g_autofree LoadCurrentModesResult *result = NULL;
 
     result = g_task_propagate_pointer (G_TASK (res), error);
     if (!result)
@@ -632,7 +632,6 @@ load_current_modes_finish (MMIfaceModem *self,
 
     *allowed = result->allowed;
     *preferred = result->preferred;
-    g_free (result);
     return TRUE;
 }
 
@@ -641,11 +640,11 @@ selrat_query_ready (MMBaseModem *self,
                     GAsyncResult *res,
                     GTask *task)
 {
-    LoadCurrentModesResult *result;
-    const gchar *response;
-    GError *error = NULL;
-    GRegex *r = NULL;
-    GMatchInfo *match_info = NULL;
+    g_autofree LoadCurrentModesResult *result = NULL;
+    const gchar                       *response;
+    GError                            *error = NULL;
+    g_autoptr(GRegex)                  r = NULL;
+    g_autoptr(GMatchInfo)              match_info = NULL;
 
     response = mm_base_modem_at_command_full_finish (self, res, &error);
     if (!response) {
@@ -727,15 +726,10 @@ selrat_query_ready (MMBaseModem *self,
                              "Could not parse allowed mode response: Response didn't match: '%s'",
                              response);
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    if (error) {
-        g_free (result);
+    if (error)
         g_task_return_error (task, error);
-    } else
-        g_task_return_pointer (task, result, g_free);
-
+    else
+        g_task_return_pointer (task, g_steal_pointer (&result), g_free);
     g_object_unref (task);
 }
 
@@ -1630,11 +1624,16 @@ parse_time (const gchar *response,
             const gchar *tag,
             GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint year, month, day, hour, minute, second;
-    gchar *result = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  year;
+    guint                  month;
+    guint                  day;
+    guint                  hour;
+    guint                  minute;
+    guint                  second;
+    gchar                 *result = NULL;
 
     r = g_regex_new (regex, 0, 0, NULL);
     g_assert (r != NULL);
@@ -1665,8 +1664,6 @@ parse_time (const gchar *response,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return result;
 }
 
diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c
index 341006d6a..72cbc34f0 100644
--- a/plugins/sierra/mm-common-sierra.c
+++ b/plugins/sierra/mm-common-sierra.c
@@ -480,7 +480,7 @@ mm_common_sierra_setup_ports (MMBroadbandModem *self)
 {
     MMPortSerialAt *ports[2];
     guint i;
-    GRegex *pacsp_regex;
+    g_autoptr(GRegex) pacsp_regex = NULL;
 
     pacsp_regex = g_regex_new ("\\r\\n\\+PACSP.*\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
 
@@ -505,8 +505,6 @@ mm_common_sierra_setup_ports (MMBroadbandModem *self)
             pacsp_regex,
             NULL, NULL, NULL);
     }
-
-    g_regex_unref (pacsp_regex);
 }
 
 /*****************************************************************************/
diff --git a/plugins/sierra/mm-modem-helpers-sierra.c b/plugins/sierra/mm-modem-helpers-sierra.c
index ac07c9eeb..821be1994 100644
--- a/plugins/sierra/mm-modem-helpers-sierra.c
+++ b/plugins/sierra/mm-modem-helpers-sierra.c
@@ -23,16 +23,15 @@ GList *
 mm_sierra_parse_scact_read_response (const gchar  *reply,
                                      GError      **error)
 {
-    GError     *inner_error = NULL;
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GList      *list;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GList                 *list = NULL;
 
     if (!reply || !reply[0])
         /* Nothing configured, all done */
         return NULL;
 
-    list = NULL;
     r = g_regex_new ("!SCACT:\\s*(\\d+),(\\d+)",
                      G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, &inner_error);
     g_assert (r);
@@ -66,9 +65,6 @@ mm_sierra_parse_scact_read_response (const gchar  *reply,
         g_match_info_next (match_info, &inner_error);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         mm_3gpp_pdp_context_active_list_free (list);
         g_propagate_error (error, inner_error);
@@ -76,7 +72,5 @@ mm_sierra_parse_scact_read_response (const gchar  *reply,
         return NULL;
     }
 
-    list = g_list_sort (list, (GCompareFunc) mm_3gpp_pdp_context_active_cmp);
-
-    return list;
+    return g_list_sort (list, (GCompareFunc) mm_3gpp_pdp_context_active_cmp);
 }
diff --git a/plugins/simtech/tests/test-modem-helpers-simtech.c b/plugins/simtech/tests/test-modem-helpers-simtech.c
index d5d774f24..ba6532cca 100644
--- a/plugins/simtech/tests/test-modem-helpers-simtech.c
+++ b/plugins/simtech/tests/test-modem-helpers-simtech.c
@@ -33,13 +33,13 @@ common_test_clcc_urc (const gchar      *urc,
                       const MMCallInfo *expected_call_info_list,
                       guint             expected_call_info_list_size)
 {
-    GError     *error = NULL;
-    GRegex     *clcc_regex = NULL;
-    gboolean    result;
-    GMatchInfo *match_info = NULL;
-    gchar      *str;
-    GList      *call_info_list = NULL;
-    GList      *l;
+    g_autoptr(GRegex)      clcc_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *str = NULL;
+    GError                *error = NULL;
+    GList                 *call_info_list = NULL;
+    GList                 *l;
+    gboolean               result;
 
     clcc_regex = mm_simtech_get_clcc_urc_regex ();
 
@@ -84,10 +84,6 @@ common_test_clcc_urc (const gchar      *urc,
         g_assert (found);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (clcc_regex);
-    g_free (str);
-
     mm_simtech_call_info_list_free (call_info_list);
 }
 
@@ -148,12 +144,12 @@ common_test_voice_call_urc (const gchar *urc,
                             gboolean     expected_start_or_stop,
                             guint        expected_duration)
 {
-    GError     *error = NULL;
-    gboolean    start_or_stop = FALSE; /* start = TRUE, stop = FALSE */
-    guint       duration = 0;
-    GRegex     *voice_call_regex = NULL;
-    gboolean    result;
-    GMatchInfo *match_info = NULL;
+    g_autoptr(GRegex)      voice_call_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *error = NULL;
+    gboolean               start_or_stop = FALSE; /* start = TRUE, stop = FALSE */
+    guint                  duration = 0;
+    gboolean               result;
 
     voice_call_regex = mm_simtech_get_voice_call_urc_regex ();
 
@@ -168,9 +164,6 @@ common_test_voice_call_urc (const gchar *urc,
 
     g_assert_cmpuint (expected_start_or_stop, ==, start_or_stop);
     g_assert_cmpuint (expected_duration, ==, duration);
-
-    g_match_info_free (match_info);
-    g_regex_unref (voice_call_regex);
 }
 
 static void
@@ -197,11 +190,11 @@ static void
 common_test_missed_call_urc (const gchar *urc,
                              const gchar *expected_details)
 {
-    GError     *error = NULL;
-    gchar      *details = NULL;
-    GRegex     *missed_call_regex = NULL;
-    gboolean    result;
-    GMatchInfo *match_info = NULL;
+    g_autoptr(GRegex)      missed_call_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *details = NULL;
+    GError                *error = NULL;
+    gboolean               result;
 
     missed_call_regex = mm_simtech_get_missed_call_urc_regex ();
 
@@ -215,10 +208,6 @@ common_test_missed_call_urc (const gchar *urc,
     g_assert (result);
 
     g_assert_cmpstr (expected_details, ==, details);
-    g_free (details);
-
-    g_match_info_free (match_info);
-    g_regex_unref (missed_call_regex);
 }
 
 static void
@@ -233,11 +222,11 @@ static void
 common_test_cring_urc (const gchar *urc,
                        const gchar *expected_type)
 {
-    GError     *error = NULL;
-    GRegex     *cring_regex = NULL;
-    GMatchInfo *match_info = NULL;
-    gchar      *type;
-    gboolean    result;
+    g_autoptr(GRegex)      cring_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *type = NULL;
+    GError                *error = NULL;
+    gboolean               result;
 
     cring_regex = mm_simtech_get_cring_urc_regex ();
 
@@ -250,10 +239,6 @@ common_test_cring_urc (const gchar *urc,
     g_assert (type);
 
     g_assert_cmpstr (type, ==, expected_type);
-
-    g_match_info_free (match_info);
-    g_regex_unref (cring_regex);
-    g_free (type);
 }
 
 static void
@@ -274,11 +259,11 @@ static void
 common_test_rxdtmf_urc (const gchar *urc,
                         const gchar *expected_str)
 {
-    GError     *error = NULL;
-    GRegex     *rxdtmf_regex = NULL;
-    GMatchInfo *match_info = NULL;
-    gchar      *type;
-    gboolean    result;
+    g_autoptr(GRegex)      rxdtmf_regex = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *type = NULL;
+    GError                *error = NULL;
+    gboolean               result;
 
     rxdtmf_regex = mm_simtech_get_rxdtmf_urc_regex ();
 
@@ -291,10 +276,6 @@ common_test_rxdtmf_urc (const gchar *urc,
     g_assert (type);
 
     g_assert_cmpstr (type, ==, expected_str);
-
-    g_match_info_free (match_info);
-    g_regex_unref (rxdtmf_regex);
-    g_free (type);
 }
 
 static void
diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c
index 49e48247c..bbf3f7603 100644
--- a/plugins/telit/mm-broadband-modem-telit.c
+++ b/plugins/telit/mm-broadband-modem-telit.c
@@ -501,10 +501,10 @@ telit_qss_enable_ready (MMBaseModem *self,
                         GAsyncResult *res,
                         GTask *task)
 {
-    QssSetupContext *ctx;
-    MMPortSerialAt *port;
-    GError **error;
-    GRegex *pattern;
+    QssSetupContext    *ctx;
+    MMPortSerialAt     *port;
+    GError            **error;
+    g_autoptr(GRegex)   pattern = NULL;
 
     ctx = g_task_get_task_data (task);
 
@@ -530,7 +530,6 @@ telit_qss_enable_ready (MMBaseModem *self,
         (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler,
         self,
         NULL);
-    g_regex_unref (pattern);
 
 next_step:
     ctx->step++;
diff --git a/plugins/telit/mm-common-telit.c b/plugins/telit/mm-common-telit.c
index 2e0b38015..911c605b2 100644
--- a/plugins/telit/mm-common-telit.c
+++ b/plugins/telit/mm-common-telit.c
@@ -112,12 +112,12 @@ cache_port_mode (MMPortProbe *probe,
                  MMDevice    *device,
                  const gchar *reply)
 {
-    GRegex *r = NULL;
-    GRegexCompileFlags flags = G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW;
-    GMatchInfo *match_info = NULL;
-    GError *error = NULL;
-    gboolean ret = FALSE;
-    guint portcfg_current;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GRegexCompileFlags     flags = G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW;
+    GError                *error = NULL;
+    gboolean               ret = FALSE;
+    guint                  portcfg_current;
 
     /* #PORTCFG: <requested>,<active> */
     r = g_regex_new ("#PORTCFG:\\s*(\\d+),(\\d+)", flags, 0, NULL);
@@ -173,9 +173,7 @@ cache_port_mode (MMPortProbe *probe,
     ret = TRUE;
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-    if (error != NULL) {
+    if (error) {
         mm_obj_dbg (probe, "error while matching #PORTCFG: %s", error->message);
         g_error_free (error);
     }
diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c
index c2061fcd5..54cd6a0cf 100644
--- a/plugins/telit/mm-modem-helpers-telit.c
+++ b/plugins/telit/mm-modem-helpers-telit.c
@@ -701,10 +701,10 @@ common_parse_bnd_response (const gchar    *response,
                            gpointer        log_object,
                            GError        **error)
 {
-    GError     *inner_error = NULL;
-    GArray     *bands = NULL;
-    GMatchInfo *match_info = NULL;
-    GRegex     *r;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    GError                *inner_error = NULL;
+    GArray                *bands = NULL;
 
     static const gchar *load_bands_regex[] = {
         [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?(,\\s*\\((?P<Bands4G>[0-9\\-,]*)\\))?",
@@ -761,9 +761,6 @@ common_parse_bnd_response (const gchar    *response,
         goto out;
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         g_clear_pointer (&bands, g_array_unref);
diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c
index bb0e02ac9..5cc035422 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.c
+++ b/plugins/ublox/mm-modem-helpers-ublox.c
@@ -31,14 +31,14 @@ mm_ublox_parse_upincnt_response (const gchar  *response,
                                  guint        *out_puk2_attempts,
                                  GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       pin_attempts = 0;
-    guint       pin2_attempts = 0;
-    guint       puk_attempts = 0;
-    guint       puk2_attempts = 0;
-    gboolean    success = TRUE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  pin_attempts = 0;
+    guint                  pin2_attempts = 0;
+    guint                  puk_attempts = 0;
+    guint                  puk2_attempts = 0;
+    gboolean               success = TRUE;
 
     g_assert (out_pin_attempts);
     g_assert (out_pin2_attempts);
@@ -78,9 +78,6 @@ mm_ublox_parse_upincnt_response (const gchar  *response,
 
 out:
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -107,10 +104,10 @@ mm_ublox_parse_uusbconf_response (const gchar        *response,
                                   MMUbloxUsbProfile  *out_profile,
                                   GError            **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    MMUbloxUsbProfile profile = MM_UBLOX_USB_PROFILE_UNKNOWN;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    MMUbloxUsbProfile      profile = MM_UBLOX_USB_PROFILE_UNKNOWN;
 
     g_assert (out_profile != NULL);
 
@@ -127,7 +124,7 @@ mm_ublox_parse_uusbconf_response (const gchar        *response,
 
     g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
     if (!inner_error && g_match_info_matches (match_info)) {
-        gchar *profile_name;
+        g_autofree gchar *profile_name = NULL;
 
         profile_name = mm_get_string_unquoted_from_match_info (match_info, 2);
         if (profile_name && profile_name[0]) {
@@ -140,12 +137,8 @@ mm_ublox_parse_uusbconf_response (const gchar        *response,
                                            "Unknown USB profile: '%s'", profile_name);
         } else
             profile = MM_UBLOX_USB_PROFILE_BACK_COMPATIBLE;
-        g_free (profile_name);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -169,10 +162,10 @@ mm_ublox_parse_ubmconf_response (const gchar            *response,
                                  MMUbloxNetworkingMode  *out_mode,
                                  GError                **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    MMUbloxNetworkingMode mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    MMUbloxNetworkingMode  mode = MM_UBLOX_NETWORKING_MODE_UNKNOWN;
 
     g_assert (out_mode != NULL);
 
@@ -203,9 +196,6 @@ mm_ublox_parse_ubmconf_response (const gchar            *response,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -234,15 +224,15 @@ mm_ublox_parse_uipaddr_response (const gchar  *response,
                                  gchar       **out_ipv6_link_local_address,
                                  GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       cid = 0;
-    gchar      *if_name = NULL;
-    gchar      *ipv4_address = NULL;
-    gchar      *ipv4_subnet = NULL;
-    gchar      *ipv6_global_address = NULL;
-    gchar      *ipv6_link_local_address = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  cid = 0;
+    gchar                 *if_name = NULL;
+    gchar                 *ipv4_address = NULL;
+    gchar                 *ipv4_subnet = NULL;
+    gchar                 *ipv6_global_address = NULL;
+    gchar                 *ipv6_link_local_address = NULL;
 
     /* Response may be e.g.:
      * +UIPADDR: 1,"ccinet0","5.168.120.13","255.255.255.0","",""
@@ -288,10 +278,6 @@ mm_ublox_parse_uipaddr_response (const gchar  *response,
         ipv6_link_local_address = mm_get_string_unquoted_from_match_info (match_info, 6);
 
 out:
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_free (if_name);
         g_free (ipv4_address);
@@ -1550,11 +1536,11 @@ GArray *
 mm_ublox_parse_uact_response (const gchar  *response,
                               GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    GArray     *nums = NULL;
-    GArray     *bands = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GArray                *nums = NULL;
+    GArray                *bands = NULL;
 
     /*
      * AT+UACT?
@@ -1566,16 +1552,12 @@ mm_ublox_parse_uact_response (const gchar  *response,
 
     g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
     if (!inner_error && g_match_info_matches (match_info)) {
-        gchar *bandstr;
+        g_autofree gchar *bandstr = NULL;
 
         bandstr = mm_get_string_unquoted_from_match_info (match_info, 4);
         nums = mm_parse_uint_list (bandstr, &inner_error);
-        g_free (bandstr);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return NULL;
@@ -1632,16 +1614,16 @@ mm_ublox_parse_uact_test (const gchar  *response,
                           GArray      **bands4g_out,
                           GError      **error)
 {
-    GRegex       *r;
-    GMatchInfo   *match_info;
-    GError       *inner_error = NULL;
-    const gchar  *bands2g_str = NULL;
-    const gchar  *bands3g_str = NULL;
-    const gchar  *bands4g_str = NULL;
-    GArray       *bands2g = NULL;
-    GArray       *bands3g = NULL;
-    GArray       *bands4g = NULL;
-    gchar       **split = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_auto(GStrv)          split = NULL;
+    GError                *inner_error = NULL;
+    const gchar           *bands2g_str = NULL;
+    const gchar           *bands3g_str = NULL;
+    const gchar           *bands4g_str = NULL;
+    GArray                *bands2g = NULL;
+    GArray                *bands3g = NULL;
+    GArray                *bands4g = NULL;
 
     g_assert (bands2g_out && bands3g_out && bands4g_out);
 
@@ -1658,8 +1640,8 @@ mm_ublox_parse_uact_test (const gchar  *response,
         goto out;
 
     if (g_match_info_matches (match_info)) {
-        gchar *aux;
-        guint n_groups;
+        g_autofree gchar *aux = NULL;
+        guint             n_groups;
 
         aux  = mm_get_string_unquoted_from_match_info (match_info, 4);
         split = mm_split_string_groups (aux);
@@ -1670,7 +1652,6 @@ mm_ublox_parse_uact_test (const gchar  *response,
             bands3g_str = split[1];
         if (n_groups >= 3)
             bands4g_str = split[2];
-        g_free (aux);
     }
 
     if (!bands2g_str && !bands3g_str && !bands4g_str) {
@@ -1692,10 +1673,6 @@ mm_ublox_parse_uact_test (const gchar  *response,
     /* success */
 
 out:
-    g_strfreev (split);
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         if (bands2g)
             g_array_unref (bands2g);
@@ -1760,13 +1737,13 @@ mm_ublox_parse_urat_read_response (const gchar  *response,
                                    MMModemMode  *out_preferred,
                                    GError      **error)
 {
-    GRegex      *r;
-    GMatchInfo  *match_info;
-    GError      *inner_error = NULL;
-    MMModemMode  allowed = MM_MODEM_MODE_NONE;
-    MMModemMode  preferred = MM_MODEM_MODE_NONE;
-    gchar       *allowed_str = NULL;
-    gchar       *preferred_str = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    MMModemMode            allowed = MM_MODEM_MODE_NONE;
+    MMModemMode            preferred = MM_MODEM_MODE_NONE;
+    g_autofree gchar      *allowed_str = NULL;
+    g_autofree gchar      *preferred_str = NULL;
 
     g_assert (out_allowed != NULL && out_preferred != NULL);
 
@@ -1821,13 +1798,6 @@ mm_ublox_parse_urat_read_response (const gchar  *response,
     }
 
 out:
-
-    g_free (allowed_str);
-    g_free (preferred_str);
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -1981,14 +1951,14 @@ mm_ublox_parse_ugcntrd_response_for_cid (const gchar  *response,
                                          guint64      *out_total_rx_bytes,
                                          GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info = NULL;
-    GError     *inner_error = NULL;
-    guint64     session_tx_bytes = 0;
-    guint64     session_rx_bytes = 0;
-    guint64     total_tx_bytes   = 0;
-    guint64     total_rx_bytes   = 0;
-    gboolean    matched = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint64                session_tx_bytes = 0;
+    guint64                session_rx_bytes = 0;
+    guint64                total_tx_bytes   = 0;
+    guint64                total_rx_bytes   = 0;
+    gboolean               matched = FALSE;
 
     /* Response may be e.g.:
      *  +UGCNTRD: 31,2704,1819,2724,1839
@@ -2044,10 +2014,6 @@ mm_ublox_parse_ugcntrd_response_for_cid (const gchar  *response,
     }
 
 out:
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
diff --git a/plugins/via/mm-broadband-modem-via.c b/plugins/via/mm-broadband-modem-via.c
index 6a8b45081..896db8cd4 100644
--- a/plugins/via/mm-broadband-modem-via.c
+++ b/plugins/via/mm-broadband-modem-via.c
@@ -153,7 +153,7 @@ get_detailed_registration_state_finish (MMIfaceModemCdma              *self,
                                         MMModemCdmaRegistrationState  *detailed_evdo_state,
                                         GError                       **error)
 {
-    DetailedRegistrationStateResults *results;
+    g_autofree DetailedRegistrationStateResults *results = NULL;
 
     results = g_task_propagate_pointer (G_TASK (res), error);
     if (!results)
@@ -161,7 +161,6 @@ get_detailed_registration_state_finish (MMIfaceModemCdma              *self,
 
     *detailed_cdma1x_state = results->detailed_cdma1x_state;
     *detailed_evdo_state   = results->detailed_evdo_state;
-    g_free (results);
     return TRUE;
 }
 
@@ -171,13 +170,13 @@ sysinfo_ready (MMBaseModem  *self,
                GTask        *task)
 
 {
-    DetailedRegistrationStateResults *ctx;
-    DetailedRegistrationStateResults *results;
-    const gchar                      *response;
-    GRegex                           *r;
-    GMatchInfo                       *match_info;
-    MMModemCdmaRegistrationState      reg_state;
-    guint                             val = 0;
+    DetailedRegistrationStateResults            *ctx;
+    g_autofree DetailedRegistrationStateResults *results = NULL;
+    const gchar                                 *response;
+    g_autoptr(GRegex)                            r = NULL;
+    g_autoptr(GMatchInfo)                        match_info = NULL;
+    MMModemCdmaRegistrationState                 reg_state;
+    guint                                        val = 0;
 
     ctx = g_task_get_task_data (task);
 
@@ -236,11 +235,8 @@ sysinfo_ready (MMBaseModem  *self,
         results->detailed_cdma1x_state = reg_state;
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
 out:
-    g_task_return_pointer (task, results, NULL);
+    g_task_return_pointer (task, g_steal_pointer (&results), g_free);
     g_object_unref (task);
 }
 
diff --git a/plugins/wavecom/mm-broadband-modem-wavecom.c b/plugins/wavecom/mm-broadband-modem-wavecom.c
index 8659e1c46..521e72de2 100644
--- a/plugins/wavecom/mm-broadband-modem-wavecom.c
+++ b/plugins/wavecom/mm-broadband-modem-wavecom.c
@@ -1223,9 +1223,9 @@ modem_power_off (MMIfaceModem *self,
 static void
 setup_ports (MMBroadbandModem *self)
 {
-    gpointer parser;
-    MMPortSerialAt *primary;
-    GRegex *regex;
+    gpointer           parser;
+    MMPortSerialAt    *primary;
+    g_autoptr(GRegex)  regex = NULL;
 
     /* Call parent's setup ports first always */
     MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_wavecom_parent_class)->setup_ports (self);
@@ -1242,7 +1242,6 @@ setup_ports (MMBroadbandModem *self)
                          G_REGEX_RAW | G_REGEX_OPTIMIZE,
                          0, NULL);
     mm_serial_parser_v1_set_custom_regex (parser, regex, NULL);
-    g_regex_unref (regex);
 
     mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (primary),
                                            mm_serial_parser_v1_parse,
diff --git a/plugins/x22x/mm-broadband-modem-x22x.c b/plugins/x22x/mm-broadband-modem-x22x.c
index c47442628..1ce32f57a 100644
--- a/plugins/x22x/mm-broadband-modem-x22x.c
+++ b/plugins/x22x/mm-broadband-modem-x22x.c
@@ -120,12 +120,12 @@ load_current_modes_finish (MMIfaceModem *self,
                            MMModemMode *preferred,
                            GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    const gchar *response;
-    gchar *str;
-    gint mode = -1;
-    GError *match_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    const gchar           *response;
+    gchar                 *str;
+    gint                   mode = -1;
+    GError                *match_error = NULL;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
     if (!response)
@@ -143,17 +143,12 @@ load_current_modes_finish (MMIfaceModem *self,
                          MM_CORE_ERROR_FAILED,
                          "Couldn't match +SYSSEL reply: %s", response);
         }
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return FALSE;
     }
 
     str = g_match_info_fetch (match_info, 3);
     mode = atoi (str);
     g_free (str);
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
     switch (mode) {
     case 0:
diff --git a/plugins/xmm/mm-modem-helpers-xmm.c b/plugins/xmm/mm-modem-helpers-xmm.c
index 9b3933d2a..70e02a8f5 100644
--- a/plugins/xmm/mm-modem-helpers-xmm.c
+++ b/plugins/xmm/mm-modem-helpers-xmm.c
@@ -364,11 +364,11 @@ mm_xmm_parse_xact_query_response (const gchar             *response,
                                   GArray                 **bands_out,
                                   GError                 **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    GArray     *bands = NULL;
-    guint       i;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GArray                *bands = NULL;
+    guint                  i;
 
     MMModemModeCombination mode = {
         .allowed   = MM_MODEM_MODE_NONE,
@@ -450,9 +450,6 @@ mm_xmm_parse_xact_query_response (const gchar             *response,
     /* success */
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         if (bands)
             g_array_unref (bands);
@@ -609,17 +606,17 @@ mm_xmm_parse_xcesq_query_response (const gchar  *response,
                                    gint         *out_rssnr,
                                    GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       rxlev = 99;
-    guint       ber = 99;
-    guint       rscp = 255;
-    guint       ecn0 = 255;
-    guint       rsrq = 255;
-    guint       rsrp = 255;
-    gint        rssnr = 255;
-    gboolean    success = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  rxlev = 99;
+    guint                  ber = 99;
+    guint                  rscp = 255;
+    guint                  ecn0 = 255;
+    guint                  rsrq = 255;
+    guint                  rsrp = 255;
+    gint                   rssnr = 255;
+    gboolean               success = FALSE;
 
     g_assert (out_rxlev);
     g_assert (out_ber);
@@ -672,9 +669,6 @@ mm_xmm_parse_xcesq_query_response (const gchar  *response,
     }
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -959,11 +953,11 @@ mm_xmm_parse_xlcsslp_query_response (const gchar  *response,
                                      gchar       **supl_address,
                                      GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    gchar      *address = NULL;
-    guint       port = 0;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    gchar                 *address = NULL;
+    guint                  port = 0;
 
     /*
      * E.g.:
@@ -996,9 +990,6 @@ mm_xmm_parse_xlcsslp_query_response (const gchar  *response,
     }
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
diff --git a/plugins/zte/mm-broadband-modem-zte.c b/plugins/zte/mm-broadband-modem-zte.c
index f4cb774d3..352835318 100644
--- a/plugins/zte/mm-broadband-modem-zte.c
+++ b/plugins/zte/mm-broadband-modem-zte.c
@@ -339,22 +339,20 @@ load_current_modes_finish (MMIfaceModem *self,
                            MMModemMode *preferred,
                            GError **error)
 {
-    const gchar *response;
-    GMatchInfo *match_info = NULL;
-    GRegex *r;
-    gint cm_mode = -1;
-    gint pref_acq = -1;
-    gboolean result;
-    GError *match_error = NULL;
+    const gchar           *response;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    gint                   cm_mode = -1;
+    gint                   pref_acq = -1;
+    GError                *match_error = NULL;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
     if (!response)
         return FALSE;
 
-    r = g_regex_new ("\\+ZSNT:\\s*(\\d),(\\d),(\\d)", G_REGEX_UNGREEDY, 0, error);
+    r = g_regex_new ("\\+ZSNT:\\s*(\\d),(\\d),(\\d)", G_REGEX_UNGREEDY, 0, NULL);
     g_assert (r != NULL);
 
-    result = FALSE;
     if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &match_error)) {
         if (match_error)
             g_propagate_error (error, match_error);
@@ -364,7 +362,7 @@ load_current_modes_finish (MMIfaceModem *self,
                          MM_CORE_ERROR_FAILED,
                          "Couldn't parse +ZSNT response: '%s'",
                          response);
-        goto done;
+        return FALSE;
     }
 
     if (!mm_get_int_from_match_info (match_info, 1, &cm_mode) ||
@@ -376,11 +374,10 @@ load_current_modes_finish (MMIfaceModem *self,
                      MM_CORE_ERROR_FAILED,
                      "Failed to parse the allowed mode response: '%s'",
                      response);
-        goto done;
+        return FALSE;
     }
 
     /* Correctly parsed! */
-    result = TRUE;
     if (cm_mode == 0) {
         /* Both 2G, 3G and LTE allowed. For LTE modems, no 2G/3G preference supported. */
         if (pref_acq == 0 || mm_iface_modem_is_3gpp_lte (self)) {
@@ -410,12 +407,7 @@ load_current_modes_finish (MMIfaceModem *self,
     } else
         g_assert_not_reached ();
 
-done:
-    g_match_info_free (match_info);
-    if (r)
-        g_regex_unref (r);
-
-    return result;
+    return TRUE;
 }
 
 static void
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index c30021cb0..12b77649e 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -3169,9 +3169,9 @@ static void
 set_cgev_unsolicited_events_handlers (MMBroadbandModem *self,
                                       gboolean          enable)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *cgev_regex;
-    guint i;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  cgev_regex = NULL;
+    guint              i;
 
     cgev_regex = mm_3gpp_cgev_regex_get ();
     ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
@@ -3193,8 +3193,6 @@ set_cgev_unsolicited_events_handlers (MMBroadbandModem *self,
             enable ? self : NULL,
             NULL);
     }
-
-    g_regex_unref (cgev_regex);
 }
 
 static void
@@ -3245,9 +3243,9 @@ static void
 set_ciev_unsolicited_events_handlers (MMBroadbandModem *self,
                                       gboolean          enable)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *ciev_regex;
-    guint i;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  ciev_regex = NULL;
+    guint              i;
 
     ciev_regex = mm_3gpp_ciev_regex_get ();
     ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
@@ -3269,8 +3267,6 @@ set_ciev_unsolicited_events_handlers (MMBroadbandModem *self,
             enable ? self : NULL,
             NULL);
     }
-
-    g_regex_unref (ciev_regex);
 }
 
 static void
@@ -5160,20 +5156,20 @@ registration_status_check_ready (MMBroadbandModem *self,
                                  GAsyncResult     *res,
                                  GTask            *task)
 {
+    g_autoptr(GMatchInfo)         match_info = NULL;
     RunRegistrationChecksContext *ctx;
-    const gchar *response;
-    GError *error = NULL;
-    GMatchInfo *match_info = NULL;
-    guint i;
-    gboolean parsed;
-    gboolean cgreg = FALSE;
-    gboolean cereg = FALSE;
-    gboolean c5greg = FALSE;
-    MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
-    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
-    gulong lac = 0;
-    gulong tac = 0;
-    gulong cid = 0;
+    const gchar                  *response;
+    GError                       *error = NULL;
+    guint                         i;
+    gboolean                      parsed;
+    gboolean                      cgreg = FALSE;
+    gboolean                      cereg = FALSE;
+    gboolean                      c5greg = FALSE;
+    MMModem3gppRegistrationState  state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+    MMModemAccessTechnology       act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    gulong                        lac = 0;
+    gulong                        tac = 0;
+    gulong                        cid = 0;
 
     ctx = g_task_get_task_data (task);
 
@@ -5205,8 +5201,7 @@ registration_status_check_ready (MMBroadbandModem *self,
                            0,
                            &match_info))
             break;
-        g_match_info_free (match_info);
-        match_info = NULL;
+        g_clear_pointer (&match_info, g_match_info_free);
     }
 
     if (!match_info) {
@@ -5229,7 +5224,6 @@ registration_status_check_ready (MMBroadbandModem *self,
                                           &cereg,
                                           &c5greg,
                                           &error);
-    g_match_info_free (match_info);
 
     if (!parsed) {
         if (!error)
@@ -6306,10 +6300,10 @@ set_unsolicited_result_code_handlers (MMIfaceModem3gppUssd *self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *cusd_regex;
-    guint i;
-    GTask *task;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  cusd_regex = NULL;
+    guint              i;
+    GTask             *task;
 
     cusd_regex = mm_3gpp_cusd_regex_get ();
     ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
@@ -6331,8 +6325,6 @@ set_unsolicited_result_code_handlers (MMIfaceModem3gppUssd *self,
             NULL);
     }
 
-    g_regex_unref (cusd_regex);
-
     task = g_task_new (self, NULL, callback, user_data);
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -7233,11 +7225,11 @@ set_messaging_unsolicited_events_handlers (MMIfaceModemMessaging *self,
                                            GAsyncReadyCallback callback,
                                            gpointer user_data)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *cmti_regex;
-    GRegex *cds_regex;
-    guint i;
-    GTask *task;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  cmti_regex = NULL;
+    g_autoptr(GRegex)  cds_regex = NULL;
+    guint              i;
+    GTask             *task;
 
     cmti_regex = mm_3gpp_cmti_regex_get ();
     cds_regex = mm_3gpp_cds_regex_get ();
@@ -7267,9 +7259,6 @@ set_messaging_unsolicited_events_handlers (MMIfaceModemMessaging *self,
             NULL);
     }
 
-    g_regex_unref (cmti_regex);
-    g_regex_unref (cds_regex);
-
     task = g_task_new (self, NULL, callback, user_data);
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -7486,11 +7475,11 @@ sms_text_part_list_ready (MMBroadbandModem *self,
                           GAsyncResult *res,
                           GTask *task)
 {
-    ListPartsContext *ctx;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    const gchar *response;
-    GError *error = NULL;
+    ListPartsContext      *ctx;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    const gchar           *response;
+    GError                *error = NULL;
 
     response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
     if (error) {
@@ -7510,8 +7499,6 @@ sms_text_part_list_ready (MMBroadbandModem *self,
                                  MM_CORE_ERROR_INVALID_ARGS,
                                  "Couldn't parse SMS list response");
         g_object_unref (task);
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return;
     }
 
@@ -7597,8 +7584,6 @@ sms_text_part_list_ready (MMBroadbandModem *self,
 next:
         g_match_info_next (match_info, NULL);
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
     /* We consider all done */
     g_task_return_boolean (task, TRUE);
@@ -7929,9 +7914,9 @@ set_voice_in_call_unsolicited_events_handlers (MMBroadbandModem *self,
                                                PortsContext     *ports_ctx,
                                                gboolean          enable)
 {
-    MMPortSerialAt *ports[2];
-    GRegex         *in_call_event_regex;
-    guint           i;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex) in_call_event_regex = NULL;
+    guint             i;
 
     in_call_event_regex = g_regex_new ("\\r\\n(NO CARRIER|BUSY|NO ANSWER|NO DIALTONE)(\\r)?\\r\\n$",
                                        G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
@@ -7954,8 +7939,6 @@ set_voice_in_call_unsolicited_events_handlers (MMBroadbandModem *self,
             enable ? self : NULL,
             NULL);
     }
-
-    g_regex_unref (in_call_event_regex);
 }
 
 static void
@@ -8146,13 +8129,13 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self,
                                        GAsyncReadyCallback callback,
                                        gpointer user_data)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *cring_regex;
-    GRegex *ring_regex;
-    GRegex *clip_regex;
-    GRegex *ccwa_regex;
-    guint i;
-    GTask *task;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  cring_regex = NULL;
+    g_autoptr(GRegex)  ring_regex = NULL;
+    g_autoptr(GRegex)  clip_regex = NULL;
+    g_autoptr(GRegex)  ccwa_regex = NULL;
+    guint              i;
+    GTask             *task;
 
     cring_regex = mm_voice_cring_regex_get ();
     ring_regex  = mm_voice_ring_regex_get ();
@@ -8196,11 +8179,6 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self,
             NULL);
     }
 
-    g_regex_unref (ccwa_regex);
-    g_regex_unref (clip_regex);
-    g_regex_unref (cring_regex);
-    g_regex_unref (ring_regex);
-
     task = g_task_new (self, NULL, callback, user_data);
     g_task_return_boolean (task, TRUE);
     g_object_unref (task);
@@ -9264,8 +9242,8 @@ css_query_ready (MMIfaceModemCdma *self,
         band = 'Z';
         success = TRUE;
     } else {
-        GRegex *r;
-        GMatchInfo *match_info;
+        g_autoptr(GRegex)     r = NULL;
+        g_autoptr(GMatchInfo) match_info = NULL;
 
         /* Format is "<band_class>,<band>,<sid>" */
         r = g_regex_new ("\\s*([^,]*?)\\s*,\\s*([^,]*?)\\s*,\\s*(\\d+)", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
@@ -9296,9 +9274,6 @@ css_query_ready (MMIfaceModemCdma *self,
 
             success = TRUE;
         }
-
-        g_match_info_free (match_info);
-        g_regex_unref (r);
     }
 
     if (!success) {
@@ -10914,10 +10889,13 @@ static const gchar *secondary_init_sequence[] = {
 static void
 setup_ports (MMBroadbandModem *self)
 {
-    MMPortSerialAt *ports[2];
-    GRegex *regex;
-    GPtrArray *array;
-    guint i, j;
+    MMPortSerialAt    *ports[2];
+    g_autoptr(GRegex)  ciev_regex = NULL;
+    g_autoptr(GRegex)  cmti_regex = NULL;
+    g_autoptr(GRegex)  cusd_regex = NULL;
+    GPtrArray         *array;
+    guint              i;
+    guint              j;
 
     ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
     ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
@@ -10933,64 +10911,23 @@ setup_ports (MMBroadbandModem *self)
                       NULL);
 
     /* Cleanup all unsolicited message handlers in all AT ports */
-
-    /* Set up CREG unsolicited message handlers, with NULL callbacks */
     array = mm_3gpp_creg_regex_get (FALSE);
-    for (i = 0; i < 2; i++) {
-        if (!ports[i])
-            continue;
-
-        for (j = 0; j < array->len; j++) {
-            mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
-                                                           (GRegex *)g_ptr_array_index (array, j),
-                                                           NULL,
-                                                           NULL,
-                                                           NULL);
-        }
-    }
-    mm_3gpp_creg_regex_destroy (array);
-
-    /* Set up CIEV unsolicited message handler, with NULL callback */
-    regex = mm_3gpp_ciev_regex_get ();
-    for (i = 0; i < 2; i++) {
-        if (!ports[i])
-            continue;
-
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
-                                                       regex,
-                                                       NULL,
-                                                       NULL,
-                                                       NULL);
-    }
-    g_regex_unref (regex);
+    ciev_regex = mm_3gpp_ciev_regex_get ();
+    cmti_regex = mm_3gpp_cmti_regex_get ();
+    cusd_regex = mm_3gpp_cusd_regex_get ();
 
-    /* Set up CMTI unsolicited message handler, with NULL callback */
-    regex = mm_3gpp_cmti_regex_get ();
     for (i = 0; i < 2; i++) {
         if (!ports[i])
             continue;
 
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
-                                                       regex,
-                                                       NULL,
-                                                       NULL,
-                                                       NULL);
+        for (j = 0; j < array->len; j++)
+            mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), (GRegex *)g_ptr_array_index (array, j), NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), ciev_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cmti_regex, NULL, NULL, NULL);
+        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]), cusd_regex, NULL, NULL, NULL);
     }
-    g_regex_unref (regex);
 
-    /* Set up CUSD unsolicited message handler, with NULL callback */
-    regex = mm_3gpp_cusd_regex_get ();
-    for (i = 0; i < 2; i++) {
-        if (!ports[i])
-            continue;
-
-        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
-                                                       regex,
-                                                       NULL,
-                                                       NULL,
-                                                       NULL);
-    }
-    g_regex_unref (regex);
+    mm_3gpp_creg_regex_destroy (array);
 }
 
 /*****************************************************************************/
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index 5e58ba9dd..58207bb15 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -528,10 +528,10 @@ mm_3gpp_parse_clcc_response (const gchar  *str,
                              GList       **out_list,
                              GError      **error)
 {
-    GRegex     *r;
-    GList      *list = NULL;
-    GError     *inner_error = NULL;
-    GMatchInfo *match_info  = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info  = NULL;
+    GList                 *list = NULL;
+    GError                *inner_error = NULL;
 
     static const MMCallDirection call_direction[] = {
         [0] = MM_CALL_DIRECTION_OUTGOING,
@@ -641,9 +641,6 @@ mm_3gpp_parse_clcc_response (const gchar  *str,
     }
 
 out:
-    g_clear_pointer (&match_info, g_match_info_free);
-    g_regex_unref (r);
-
     if (inner_error) {
         mm_3gpp_call_info_list_free (list);
         g_propagate_error (error, inner_error);
@@ -736,12 +733,12 @@ mm_parse_ifc_test_response (const gchar  *response,
                             gpointer      log_object,
                             GError      **error)
 {
-    GRegex        *r;
-    GError        *inner_error = NULL;
-    GMatchInfo    *match_info  = NULL;
-    MMFlowControl  te_mask     = MM_FLOW_CONTROL_UNKNOWN;
-    MMFlowControl  ta_mask     = MM_FLOW_CONTROL_UNKNOWN;
-    MMFlowControl  mask        = MM_FLOW_CONTROL_UNKNOWN;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info  = NULL;
+    GError                *inner_error = NULL;
+    MMFlowControl          te_mask     = MM_FLOW_CONTROL_UNKNOWN;
+    MMFlowControl          ta_mask     = MM_FLOW_CONTROL_UNKNOWN;
+    MMFlowControl          mask        = MM_FLOW_CONTROL_UNKNOWN;
 
     r = g_regex_new ("(?:\\+IFC:)?\\s*\\((.*)\\),\\((.*)\\)(?:\\r\\n)?", 0, 0, NULL);
     g_assert (r != NULL);
@@ -767,10 +764,6 @@ mm_parse_ifc_test_response (const gchar  *response,
     mask = te_mask & ta_mask;
 
 out:
-
-    g_clear_pointer (&match_info, g_match_info_free);
-    g_regex_unref (r);
-
     if (inner_error)
         g_propagate_error (error, inner_error);
 
@@ -982,21 +975,21 @@ mm_3gpp_parse_ws46_test_response (const gchar  *response,
                                   gpointer      log_object,
                                   GError      **error)
 {
-    GArray     *modes = NULL;
-    GArray     *tech_values = NULL;
-    GRegex     *r;
-    GError     *inner_error = NULL;
-    GMatchInfo *match_info = NULL;
-    gchar      *full_list = NULL;
-    guint       val;
-    guint       i;
-    guint       j;
-    gboolean    supported_5g = FALSE;
-    gboolean    supported_4g = FALSE;
-    gboolean    supported_3g = FALSE;
-    gboolean    supported_2g = FALSE;
-    gboolean    supported_mode_25 = FALSE;
-    gboolean    supported_mode_29 = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GArray                *modes = NULL;
+    GArray                *tech_values = NULL;
+    GError                *inner_error = NULL;
+    gchar                 *full_list = NULL;
+    guint                  val;
+    guint                  i;
+    guint                  j;
+    gboolean               supported_5g = FALSE;
+    gboolean               supported_4g = FALSE;
+    gboolean               supported_3g = FALSE;
+    gboolean               supported_2g = FALSE;
+    gboolean               supported_mode_25 = FALSE;
+    gboolean               supported_mode_29 = FALSE;
 
     r = g_regex_new ("(?:\\+WS46:)?\\s*\\((.*)\\)(?:\\r\\n)?", 0, 0, NULL);
     g_assert (r != NULL);
@@ -1095,9 +1088,6 @@ out:
 
     g_free (full_list);
 
-    g_clear_pointer (&match_info, g_match_info_free);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return NULL;
@@ -1190,10 +1180,10 @@ mm_3gpp_parse_cops_test_response (const gchar     *reply,
                                   gpointer         log_object,
                                   GError         **error)
 {
-    GRegex *r;
-    GList *info_list = NULL;
-    GMatchInfo *match_info;
-    gboolean umts_format = TRUE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GList                 *info_list = NULL;
+    gboolean               umts_format = TRUE;
 
     g_return_val_if_fail (reply != NULL, NULL);
     if (error)
@@ -1227,9 +1217,8 @@ mm_3gpp_parse_cops_test_response (const gchar     *reply,
 
     /* If we didn't get any hits, try the pre-UMTS format match */
     if (!g_regex_match (r, reply, 0, &match_info)) {
-        g_regex_unref (r);
-        g_match_info_free (match_info);
-        match_info = NULL;
+        g_clear_pointer (&r, g_regex_unref);
+        g_clear_pointer (&match_info, g_match_info_free);
 
         /* Pre-UMTS format doesn't include the cell access technology after
          * the numeric operator element.
@@ -1320,9 +1309,6 @@ mm_3gpp_parse_cops_test_response (const gchar     *reply,
         g_match_info_next (match_info, NULL);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     return info_list;
 }
 
@@ -1337,14 +1323,14 @@ mm_3gpp_parse_cops_read_response (const gchar              *response,
                                   gpointer                  log_object,
                                   GError                  **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    guint mode = 0;
-    guint format = 0;
-    gchar *operator = NULL;
-    guint actval = 0;
-    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    g_autoptr(GRegex)        r = NULL;
+    g_autoptr(GMatchInfo)    match_info = NULL;
+    GError                  *inner_error = NULL;
+    guint                    mode = 0;
+    guint                    format = 0;
+    gchar                   *operator = NULL;
+    guint                    actval = 0;
+    MMModemAccessTechnology  act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
 
     g_assert (out_mode || out_format || out_operator || out_act);
 
@@ -1390,9 +1376,6 @@ mm_3gpp_parse_cops_read_response (const gchar              *response,
     }
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_free (operator);
         g_propagate_error (error, inner_error);
@@ -1725,10 +1708,10 @@ mm_3gpp_parse_cgdcont_test_response (const gchar  *response,
                                      gpointer      log_object,
                                      GError      **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    GList *list = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GList                 *list = NULL;
 
     if (!response || !g_str_has_prefix (response, "+CGDCONT:")) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing +CGDCONT prefix");
@@ -1776,9 +1759,6 @@ mm_3gpp_parse_cgdcont_test_response (const gchar  *response,
         g_match_info_next (match_info, &inner_error);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         mm_obj_warn (log_object, "unexpected error matching +CGDCONT response: '%s'", inner_error->message);
         g_error_free (inner_error);
@@ -1813,52 +1793,46 @@ GList *
 mm_3gpp_parse_cgdcont_read_response (const gchar *reply,
                                      GError **error)
 {
-    GError *inner_error = NULL;
-    GRegex *r;
-    GMatchInfo *match_info;
-    GList *list;
+    GError                *inner_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GList                 *list = NULL;
 
     if (!reply || !reply[0])
         /* No APNs configured, all done */
         return NULL;
 
-    list = NULL;
     r = g_regex_new ("\\+CGDCONT:\\s*(\\d+)\\s*,([^, \\)]*)\\s*,([^, \\)]*)\\s*,([^, \\)]*)",
                      G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
-                     0, &inner_error);
-    if (r) {
-        g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error);
-
-        while (!inner_error &&
-               g_match_info_matches (match_info)) {
-            gchar *str;
-            MMBearerIpFamily ip_family;
-
-            str = mm_get_string_unquoted_from_match_info (match_info, 2);
-            ip_family = mm_3gpp_get_ip_family_from_pdp_type (str);
-            if (ip_family != MM_BEARER_IP_FAMILY_NONE) {
-                MM3gppPdpContext *pdp;
-
-                pdp = g_slice_new0 (MM3gppPdpContext);
-                if (!mm_get_uint_from_match_info (match_info, 1, &pdp->cid)) {
-                    inner_error = g_error_new (MM_CORE_ERROR,
-                                               MM_CORE_ERROR_FAILED,
-                                               "Couldn't parse CID from reply: '%s'",
-                                               reply);
-                    break;
-                }
-                pdp->pdp_type = ip_family;
-                pdp->apn = mm_get_string_unquoted_from_match_info (match_info, 3);
+                     0, NULL);
+    g_assert (r);
 
-                list = g_list_prepend (list, pdp);
+    g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &inner_error);
+    while (!inner_error && g_match_info_matches (match_info)) {
+        gchar *str;
+        MMBearerIpFamily ip_family;
+
+        str = mm_get_string_unquoted_from_match_info (match_info, 2);
+        ip_family = mm_3gpp_get_ip_family_from_pdp_type (str);
+        if (ip_family != MM_BEARER_IP_FAMILY_NONE) {
+            MM3gppPdpContext *pdp;
+
+            pdp = g_slice_new0 (MM3gppPdpContext);
+            if (!mm_get_uint_from_match_info (match_info, 1, &pdp->cid)) {
+                inner_error = g_error_new (MM_CORE_ERROR,
+                                           MM_CORE_ERROR_FAILED,
+                                           "Couldn't parse CID from reply: '%s'",
+                                           reply);
+                break;
             }
+            pdp->pdp_type = ip_family;
+            pdp->apn = mm_get_string_unquoted_from_match_info (match_info, 3);
 
-            g_free (str);
-            g_match_info_next (match_info, &inner_error);
+            list = g_list_prepend (list, pdp);
         }
 
-        g_match_info_free (match_info);
-        g_regex_unref (r);
+        g_free (str);
+        g_match_info_next (match_info, &inner_error);
     }
 
     if (inner_error) {
@@ -1868,9 +1842,7 @@ mm_3gpp_parse_cgdcont_read_response (const gchar *reply,
         return NULL;
     }
 
-    list = g_list_sort (list, (GCompareFunc)mm_3gpp_pdp_context_cmp);
-
-    return list;
+    return g_list_sort (list, (GCompareFunc)mm_3gpp_pdp_context_cmp);
 }
 
 /*************************************************************************/
@@ -1898,16 +1870,15 @@ GList *
 mm_3gpp_parse_cgact_read_response (const gchar *reply,
                                    GError **error)
 {
-    GError *inner_error = NULL;
-    GRegex *r;
-    GMatchInfo *match_info;
-    GList *list;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GList                 *list = NULL;
 
     if (!reply || !reply[0])
         /* Nothing configured, all done */
         return NULL;
 
-    list = NULL;
     r = g_regex_new ("\\+CGACT:\\s*(\\d+),(\\d+)",
                      G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, &inner_error);
     g_assert (r);
@@ -1941,9 +1912,6 @@ mm_3gpp_parse_cgact_read_response (const gchar *reply,
         g_match_info_next (match_info, &inner_error);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         mm_3gpp_pdp_context_active_list_free (list);
         g_propagate_error (error, inner_error);
@@ -2142,10 +2110,11 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply,
                                   gboolean *sms_text_supported,
                                   GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    gchar *s;
-    guint32 min = -1, max = -1;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gchar                 *s;
+    guint32                min = -1;
+    guint32                max = -1;
 
     /* Strip whitespace and response tag */
     if (g_str_has_prefix (reply, CMGF_TAG))
@@ -2163,8 +2132,6 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply,
                      MM_CORE_ERROR_FAILED,
                      "Failed to parse CMGF query result '%s'",
                      reply);
-        g_match_info_free (match_info);
-        g_regex_unref (r);
         return FALSE;
     }
 
@@ -2184,8 +2151,6 @@ mm_3gpp_parse_cmgf_test_response (const gchar *reply,
     /* CMGF=1 for Text mode */
     *sms_text_supported = (max >= 1);
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
     return TRUE;
 }
 
@@ -2196,12 +2161,12 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply,
                                   guint index,
                                   GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    gint count;
-    gint status;
-    gchar *pdu;
-    MM3gppPduInfo *info = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gint                   count;
+    gint                   status;
+    gchar                 *pdu;
+    MM3gppPduInfo         *info = NULL;
 
     /* +CMGR: <stat>,<alpha>,<length>(whitespace)<pdu> */
     /* The <alpha> and <length> fields are matched, but not currently used */
@@ -2214,7 +2179,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply,
                      MM_CORE_ERROR_FAILED,
                      "Failed to parse CMGR read result: response didn't match '%s'",
                      reply);
-        goto done;
+        return NULL;
     }
 
     /* g_match_info_get_match_count includes match #0 */
@@ -2225,7 +2190,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply,
                      "Failed to match CMGR fields (matched %d) '%s'",
                      count,
                      reply);
-        goto done;
+        return NULL;
     }
 
     if (!mm_get_int_from_match_info (match_info, 1, &status)) {
@@ -2234,7 +2199,7 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply,
                      MM_CORE_ERROR_FAILED,
                      "Failed to extract CMGR status field '%s'",
                      reply);
-        goto done;
+        return NULL;
     }
 
 
@@ -2245,18 +2210,13 @@ mm_3gpp_parse_cmgr_read_response (const gchar *reply,
                      MM_CORE_ERROR_FAILED,
                      "Failed to extract CMGR pdu field '%s'",
                      reply);
-        goto done;
+        return NULL;
     }
 
     info = g_new0 (MM3gppPduInfo, 1);
     info->index = index;
     info->status = status;
     info->pdu = pdu;
-
-done:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     return info;
 }
 
@@ -2270,8 +2230,8 @@ mm_3gpp_parse_crsm_response (const gchar *reply,
                              gchar **hex,
                              GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
+    g_autoptr(GRegex)     r = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     g_assert (sw1 != NULL);
     g_assert (sw2 != NULL);
@@ -2292,11 +2252,9 @@ mm_3gpp_parse_crsm_response (const gchar *reply,
 
     if (g_regex_match (r, reply, 0, &match_info) &&
         mm_get_uint_from_match_info (match_info, 1, sw1) &&
-        mm_get_uint_from_match_info (match_info, 2, sw2))
+        mm_get_uint_from_match_info (match_info, 2, sw2)) {
         *hex = mm_get_string_unquoted_from_match_info (match_info, 3);
-
-    g_match_info_free (match_info);
-    g_regex_unref (r);
+    }
 
     if (*hex == NULL) {
         g_set_error (error,
@@ -2372,19 +2330,19 @@ mm_3gpp_parse_cgcontrdp_response (const gchar  *response,
                                   gchar       **out_dns_secondary_address,
                                   GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       cid = 0;
-    guint       bearer_id = 0;
-    gchar      *apn = NULL;
-    gchar      *local_address_and_subnet = NULL;
-    gchar      *local_address = NULL;
-    gchar      *subnet = NULL;
-    gchar      *gateway_address = NULL;
-    gchar      *dns_primary_address = NULL;
-    gchar      *dns_secondary_address = NULL;
-    guint       field_format_extra_index = 0;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  cid = 0;
+    guint                  bearer_id = 0;
+    gchar                 *apn = NULL;
+    gchar                 *local_address_and_subnet = NULL;
+    gchar                 *local_address = NULL;
+    gchar                 *subnet = NULL;
+    gchar                 *gateway_address = NULL;
+    gchar                 *dns_primary_address = NULL;
+    gchar                 *dns_secondary_address = NULL;
+    guint                  field_format_extra_index = 0;
 
     /* Response may be e.g.:
      * +CGCONTRDP: 4,5,"ibox.tim.it.mnc001.mcc222.gprs","2.197.17.49.255.255.255.255","2.197.17.49","10.207.43.46","10.206.56.132","0.0.0.0","0.0.0.0",0
@@ -2462,9 +2420,6 @@ mm_3gpp_parse_cgcontrdp_response (const gchar  *response,
         dns_secondary_address = mm_get_string_unquoted_from_match_info (match_info, 7 + field_format_extra_index);
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     g_free (local_address_and_subnet);
 
     if (inner_error) {
@@ -2513,10 +2468,10 @@ mm_3gpp_parse_cfun_query_response (const gchar  *response,
                                    guint        *out_state,
                                    GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       state = G_MAXUINT;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  state = G_MAXUINT;
 
     g_assert (out_state != NULL);
 
@@ -2546,9 +2501,6 @@ mm_3gpp_parse_cfun_query_response (const gchar  *response,
     *out_state = state;
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -2570,16 +2522,16 @@ mm_3gpp_parse_cesq_response (const gchar  *response,
                              guint        *out_rsrp,
                              GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info;
-    GError     *inner_error = NULL;
-    guint       rxlev = 99;
-    guint       ber = 99;
-    guint       rscp = 255;
-    guint       ecn0 = 255;
-    guint       rsrq = 255;
-    guint       rsrp = 255;
-    gboolean    success = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  rxlev = 99;
+    guint                  ber = 99;
+    guint                  rscp = 255;
+    guint                  ecn0 = 255;
+    guint                  rsrq = 255;
+    guint                  rsrp = 255;
+    gboolean               success = FALSE;
 
     g_assert (out_rxlev);
     g_assert (out_ber);
@@ -2624,9 +2576,6 @@ mm_3gpp_parse_cesq_response (const gchar  *response,
     }
 
 out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -2883,10 +2832,10 @@ mm_3gpp_parse_ccwa_service_query_response (const gchar  *response,
                                            gboolean     *status,
                                            GError      **error)
 {
-    GRegex     *r;
-    GError     *inner_error = NULL;
-    GMatchInfo *match_info  = NULL;
-    gint        class_1_status = -1;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    gint                   class_1_status = -1;
 
     /*
      * AT+CCWA=<n>[,<mode>]
@@ -2928,9 +2877,6 @@ mm_3gpp_parse_ccwa_service_query_response (const gchar  *response,
     }
 
 out:
-    g_clear_pointer (&match_info, g_match_info_free);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -3035,8 +2981,8 @@ mm_3gpp_parse_cpms_test_response (const gchar  *reply,
     g_assert (r);
 
     for (i = 0; i < N_EXPECTED_GROUPS; i++) {
-        GMatchInfo *match_info = NULL;
-        GArray *array;
+        g_autoptr(GMatchInfo)  match_info = NULL;
+        GArray                *array;
 
         /* We always return a valid array, even if it may be empty */
         array = g_array_new (FALSE, FALSE, sizeof (MMSmsStorage));
@@ -3058,7 +3004,6 @@ mm_3gpp_parse_cpms_test_response (const gchar  *reply,
                 g_match_info_next (match_info, NULL);
             }
         }
-        g_match_info_free (match_info);
 
         if (!tmp1)
             tmp1 = array;
@@ -3100,43 +3045,31 @@ mm_3gpp_parse_cpms_query_response (const gchar *reply,
                                    MMSmsStorage *memw,
                                    GError **error)
 {
-    GRegex *r = NULL;
-    gboolean ret = FALSE;
-    GMatchInfo *match_info = NULL;
+    g_autoptr(GRegex)     r = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     r = g_regex_new (CPMS_QUERY_REGEX, G_REGEX_RAW, 0, NULL);
-
     g_assert (r);
 
     if (!g_regex_match (r, reply, 0, &match_info)) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "Could not parse CPMS query response '%s'", reply);
-        goto end;
+        return FALSE;
     }
 
     if (!g_match_info_matches (match_info)) {
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "Could not find matches in CPMS query reply '%s'", reply);
-        goto end;
-    }
-
-    if (!mm_3gpp_get_cpms_storage_match (match_info, "memr", memr, error)) {
-        goto end;
-    }
-
-    if (!mm_3gpp_get_cpms_storage_match (match_info, "memw", memw, error)) {
-        goto end;
+        return FALSE;
     }
 
-    ret = TRUE;
-
-end:
-    if (r != NULL)
-        g_regex_unref (r);
+    if (!mm_3gpp_get_cpms_storage_match (match_info, "memr", memr, error))
+        return FALSE;
 
-    g_match_info_free (match_info);
+    if (!mm_3gpp_get_cpms_storage_match (match_info, "memw", memw, error))
+        return FALSE;
 
-    return ret;
+    return TRUE;
 }
 
 gboolean
@@ -3168,11 +3101,12 @@ gboolean
 mm_3gpp_parse_cscs_test_response (const gchar *reply,
                                   MMModemCharset *out_charsets)
 {
-    MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
-    GRegex *r;
-    GMatchInfo *match_info;
-    gchar *p, *str;
-    gboolean success = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    MMModemCharset         charsets = MM_MODEM_CHARSET_UNKNOWN;
+    gchar                 *p;
+    gchar                 *str;
+    gboolean               success = FALSE;
 
     g_return_val_if_fail (reply != NULL, FALSE);
     g_return_val_if_fail (out_charsets != NULL, FALSE);
@@ -3194,8 +3128,7 @@ mm_3gpp_parse_cscs_test_response (const gchar *reply,
 
     /* Now parse each charset */
     r = g_regex_new ("\\s*([^,\\)]+)\\s*", 0, 0, NULL);
-    if (!r)
-        return FALSE;
+    g_assert (r);
 
     if (g_regex_match (r, p, 0, &match_info)) {
         while (g_match_info_matches (match_info)) {
@@ -3207,8 +3140,6 @@ mm_3gpp_parse_cscs_test_response (const gchar *reply,
             success = TRUE;
         }
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
     if (success)
         *out_charsets = charsets;
@@ -3222,8 +3153,8 @@ gboolean
 mm_3gpp_parse_clck_test_response (const gchar *reply,
                                   MMModem3gppFacility *out_facilities)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
+    g_autoptr(GRegex)     r = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     g_return_val_if_fail (reply != NULL, FALSE);
     g_return_val_if_fail (out_facilities != NULL, FALSE);
@@ -3252,8 +3183,6 @@ mm_3gpp_parse_clck_test_response (const gchar *reply,
             g_match_info_next (match_info, NULL);
         }
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
     return (*out_facilities != MM_MODEM_3GPP_FACILITY_NONE);
 }
@@ -3264,9 +3193,8 @@ gboolean
 mm_3gpp_parse_clck_write_response (const gchar *reply,
                                    gboolean *enabled)
 {
-    GRegex *r;
-    GMatchInfo *match_info;
-    gboolean success = FALSE;
+    g_autoptr(GRegex)     r = NULL;
+    g_autoptr(GMatchInfo) match_info = NULL;
 
     g_return_val_if_fail (reply != NULL, FALSE);
     g_return_val_if_fail (enabled != NULL, FALSE);
@@ -3277,7 +3205,7 @@ mm_3gpp_parse_clck_write_response (const gchar *reply,
     g_assert (r != NULL);
 
     if (g_regex_match (r, reply, 0, &match_info)) {
-        gchar *str;
+        g_autofree gchar *str = NULL;
 
         str = g_match_info_fetch (match_info, 1);
         if (str) {
@@ -3289,15 +3217,11 @@ mm_3gpp_parse_clck_write_response (const gchar *reply,
                 *enabled = TRUE;
             else
                 g_assert_not_reached ();
-
-            g_free (str);
-            success = TRUE;
+            return TRUE;
         }
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
-    return success;
+    return FALSE;
 }
 
 /*************************************************************************/
@@ -3530,10 +3454,10 @@ GHashTable *
 mm_3gpp_parse_cind_test_response (const gchar *reply,
                                   GError **error)
 {
-    GHashTable *hash;
-    GRegex *r;
-    GMatchInfo *match_info;
-    guint idx = 1;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GHashTable            *hash;
+    guint                  idx = 1;
 
     g_return_val_if_fail (reply != NULL, NULL);
 
@@ -3544,12 +3468,7 @@ mm_3gpp_parse_cind_test_response (const gchar *reply,
         reply++;
 
     r = g_regex_new ("\\(([^,]*),\\((\\d+)[-,](\\d+).*\\)", G_REGEX_UNGREEDY, 0, NULL);
-    if (!r) {
-        g_set_error_literal (error,
-                             MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
-                             "Could not parse scan results.");
-        return NULL;
-    }
+    g_assert (r);
 
     hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cind_response_free);
 
@@ -3578,8 +3497,6 @@ mm_3gpp_parse_cind_test_response (const gchar *reply,
             g_match_info_next (match_info, NULL);
         }
     }
-    g_match_info_free (match_info);
-    g_regex_unref (r);
 
     return hash;
 }
@@ -3590,11 +3507,11 @@ GByteArray *
 mm_3gpp_parse_cind_read_response (const gchar *reply,
                                   GError **error)
 {
-    GByteArray *array = NULL;
-    GRegex *r = NULL;
-    GMatchInfo *match_info;
-    GError *inner_error = NULL;
-    guint8 t;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GByteArray            *array = NULL;
+    GError                *inner_error = NULL;
+    guint8                 t;
 
     g_return_val_if_fail (reply != NULL, NULL);
 
@@ -3614,7 +3531,7 @@ mm_3gpp_parse_cind_read_response (const gchar *reply,
         g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
                      "Could not parse the +CIND response '%s': didn't match",
                      reply);
-        goto done;
+        return NULL;
     }
 
     array = g_byte_array_sized_new (g_match_info_get_match_count (match_info));
@@ -3625,10 +3542,9 @@ mm_3gpp_parse_cind_read_response (const gchar *reply,
     t = 0;
     g_byte_array_append (array, &t, 1);
 
-    while (!inner_error &&
-           g_match_info_matches (match_info)) {
-        gchar *str;
-        guint val = 0;
+    while (!inner_error && g_match_info_matches (match_info)) {
+        g_autofree gchar *str = NULL;
+        guint             val = 0;
 
         str = g_match_info_fetch (match_info, 1);
         if (mm_get_uint_from_str (str, &val) && val < 255) {
@@ -3639,21 +3555,14 @@ mm_3gpp_parse_cind_read_response (const gchar *reply,
                                        "Could not parse the +CIND response: invalid index '%s'",
                                        str);
         }
-
-        g_free (str);
         g_match_info_next (match_info, NULL);
     }
 
     if (inner_error) {
         g_propagate_error (error, inner_error);
-        g_byte_array_unref (array);
-        array = NULL;
+        g_clear_pointer (&array, g_byte_array_unref);
     }
 
-done:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     return array;
 }
 
@@ -3755,12 +3664,12 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar  *str,
                                    guint        *out_cid,
                                    GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info = NULL;
-    GError     *inner_error = NULL;
-    gchar      *pdp_type = NULL;
-    gchar      *pdp_addr = NULL;
-    guint       cid = 0;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    gchar                 *pdp_type = NULL;
+    gchar                 *pdp_addr = NULL;
+    guint                  cid = 0;
 
     g_assert (type == MM_3GPP_CGEV_REJECT   ||
               type == MM_3GPP_CGEV_NW_REACT ||
@@ -3772,6 +3681,7 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar  *str,
                      "NW REACT|"
                      "NW DEACT|ME DEACT"
                      ")\\s*([^,]*),\\s*([^,]*)(?:,\\s*([0-9]+))?", 0, 0, NULL);
+    g_assert (r);
 
     str = mm_strip_tag (str, "+CGEV:");
     g_regex_match_full (r, str, strlen (str), 0, 0, &match_info, &inner_error);
@@ -3802,10 +3712,6 @@ mm_3gpp_parse_cgev_indication_pdp (const gchar  *str,
     }
 
 out:
-    if (match_info)
-        g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_free (pdp_type);
         g_free (pdp_addr);
@@ -3841,10 +3747,10 @@ mm_3gpp_parse_cgev_indication_primary (const gchar  *str,
                                        guint        *out_cid,
                                        GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info = NULL;
-    GError     *inner_error = NULL;
-    guint       cid = 0;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  cid = 0;
 
     g_assert ((type == MM_3GPP_CGEV_NW_ACT_PRIMARY)   ||
               (type == MM_3GPP_CGEV_ME_ACT_PRIMARY)   ||
@@ -3872,10 +3778,6 @@ mm_3gpp_parse_cgev_indication_primary (const gchar  *str,
     }
 
 out:
-    if (match_info)
-        g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -3900,12 +3802,12 @@ mm_3gpp_parse_cgev_indication_secondary (const gchar  *str,
                                          guint        *out_event_type,
                                          GError      **error)
 {
-    GRegex     *r;
-    GMatchInfo *match_info = NULL;
-    GError     *inner_error = NULL;
-    guint       p_cid = 0;
-    guint       cid = 0;
-    guint       event_type = 0;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    guint                  p_cid = 0;
+    guint                  cid = 0;
+    guint                  event_type = 0;
 
     g_assert (type == MM_3GPP_CGEV_NW_ACT_SECONDARY   ||
               type == MM_3GPP_CGEV_ME_ACT_SECONDARY   ||
@@ -3943,10 +3845,6 @@ mm_3gpp_parse_cgev_indication_secondary (const gchar  *str,
     }
 
 out:
-    if (match_info)
-        g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return FALSE;
@@ -3980,10 +3878,10 @@ GList *
 mm_3gpp_parse_pdu_cmgl_response (const gchar *str,
                                  GError **error)
 {
-    GError *inner_error = NULL;
-    GList *list = NULL;
-    GMatchInfo *match_info;
-    GRegex *r;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *inner_error = NULL;
+    GList                 *list = NULL;
 
     /*
      * +CMGL: <index>, <status>, [<alpha>], <length>
@@ -4016,9 +3914,6 @@ mm_3gpp_parse_pdu_cmgl_response (const gchar *str,
         }
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         mm_3gpp_pdu_info_list_free (list);
@@ -4754,10 +4649,10 @@ mm_cdma_parse_crm_test_response (const gchar *reply,
                                  MMModemCdmaRmProtocol *max,
                                  GError **error)
 {
-    gboolean result = FALSE;
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gboolean               result = FALSE;
+    GError                *match_error = NULL;
 
     /* Expected reply format is:
      *   ---> AT+CRM=?
@@ -4810,9 +4705,6 @@ mm_cdma_parse_crm_test_response (const gchar *reply,
                      reply);
     }
 
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
     return result;
 }
 
@@ -5039,12 +4931,16 @@ mm_parse_cclk_response (const char *response,
                         MMNetworkTimezone **tzp,
                         GError **error)
 {
-    GRegex *r;
-    GMatchInfo *match_info = NULL;
-    GError *match_error = NULL;
-    guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
-    gint tz = 0;
-    gboolean ret = FALSE;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    GError                *match_error = NULL;
+    guint                  year = 0;
+    guint                  month = 0;
+    guint                  day = 0;
+    guint                  hour = 0;
+    guint                  minute = 0;
+    guint                  second = 0;
+    gint                   tz = 0;
 
     g_assert (iso8601p || tzp); /* at least one */
 
@@ -5065,7 +4961,7 @@ mm_parse_cclk_response (const char *response,
                          MM_CORE_ERROR_FAILED,
                          "Couldn't match +CCLK reply: %s", response);
         }
-        goto out;
+        return FALSE;
     }
 
     /* Remember that g_match_info_get_match_count() includes match #0 */
@@ -5082,7 +4978,7 @@ mm_parse_cclk_response (const char *response,
                      MM_CORE_ERROR,
                      MM_CORE_ERROR_FAILED,
                      "Failed to parse +CCLK reply: %s", response);
-        goto out;
+        return FALSE;
     }
 
     /* Read optional time zone offset; if not given assume UTC (tz = 0).
@@ -5094,7 +4990,7 @@ mm_parse_cclk_response (const char *response,
                      MM_CORE_ERROR,
                      MM_CORE_ERROR_FAILED,
                      "Failed to parse timezone in +CCLK reply: %s", response);
-        goto out;
+        return FALSE;
     }
 
     /* Adjust year to support YYYY format, as per +CSDF in 3GPP TS 27.007. Also,
@@ -5112,22 +5008,16 @@ mm_parse_cclk_response (const char *response,
         mm_network_timezone_set_offset (*tzp, tz * 15);
     }
 
-    ret = TRUE;
-
     if (iso8601p) {
         /* Return ISO-8601 format date/time string */
         *iso8601p = mm_new_iso8601_time (year, month, day, hour,
                                          minute, second,
                                          TRUE, (tz * 15),
                                          error);
-        ret = (*iso8601p != NULL);
+        return (*iso8601p != NULL);
     }
 
- out:
-    g_match_info_free (match_info);
-    g_regex_unref (r);
-
-    return ret;
+    return TRUE;
 }
 
 /*****************************************************************************/
@@ -5139,12 +5029,12 @@ gint
 mm_parse_csim_response (const gchar *response,
                               GError **error)
 {
-    GMatchInfo *match_info = NULL;
-    GRegex *r = NULL;
-    gchar *str_code = NULL;
-    gint retries = -1;
-    guint hex_code;
-    GError *inner_error = NULL;
+    g_autoptr(GRegex)      r = NULL;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autofree gchar      *str_code = NULL;
+    gint                   retries = -1;
+    guint                  hex_code;
+    GError                *inner_error = NULL;
 
     r = g_regex_new ("\\+CSIM:\\s*[0-9]+,\\s*\".*([0-9a-fA-F]{4})\"", G_REGEX_RAW, 0, NULL);
     g_regex_match (r, response, 0, &match_info);
@@ -5202,10 +5092,6 @@ mm_parse_csim_response (const gchar *response,
     retries = (gint)(hex_code - MM_MIN_SIM_RETRY_HEX);
 
 out:
-    g_regex_unref (r);
-    g_match_info_free (match_info);
-    g_free (str_code);
-
     if (inner_error) {
         g_propagate_error (error, inner_error);
         return -1;
diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c
index 44c0fc92e..88d01cf48 100644
--- a/src/mm-port-serial-at.c
+++ b/src/mm-port-serial-at.c
@@ -269,8 +269,8 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response)
 
     for (iter = self->priv->unsolicited_msg_handlers; iter; iter = iter->next) {
         MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) iter->data;
-        GMatchInfo *match_info;
-        gboolean matches;
+        g_autoptr(GMatchInfo)      match_info = NULL;
+        gboolean                   matches;
 
         if (!handler->enable)
             continue;
@@ -286,12 +286,10 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response)
             }
         }
 
-        g_match_info_free (match_info);
-
         if (matches) {
             /* Remove matches */
-            char *str;
-            int result_len = response->len;
+            g_autofree gchar *str = NULL;
+            gint              result_len = response->len;
 
             str = g_regex_replace_eval (handler->regex,
                                         (const char *) response->data,
@@ -301,7 +299,6 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response)
 
             g_byte_array_remove_range (response, 0, response->len);
             g_byte_array_append (response, (const guint8 *) str, result_len);
-            g_free (str);
         }
     }
 }
diff --git a/src/mm-port-serial-gps.c b/src/mm-port-serial-gps.c
index ea4049946..fe8ec6a84 100644
--- a/src/mm-port-serial-gps.c
+++ b/src/mm-port-serial-gps.c
@@ -74,12 +74,12 @@ parse_response (MMPortSerial *port,
                 GByteArray **parsed_response,
                 GError **error)
 {
-    MMPortSerialGps *self = MM_PORT_SERIAL_GPS (port);
-    gboolean matches;
-    GMatchInfo *match_info;
-    gchar *str;
-    gint result_len;
-    guint i;
+    MMPortSerialGps       *self = MM_PORT_SERIAL_GPS (port);
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    gboolean               matches;
+    gchar                 *str;
+    gint                   result_len;
+    guint                  i;
 
     for (i = 0; i < response->len; i++) {
         /* If there is any content before the first $,
@@ -110,8 +110,6 @@ parse_response (MMPortSerial *port,
         }
     }
 
-    g_match_info_free (match_info);
-
     if (!matches)
         return MM_PORT_SERIAL_RESPONSE_NONE;
 
diff --git a/src/mm-serial-parsers.c b/src/mm-serial-parsers.c
index fd01537d7..a577faee7 100644
--- a/src/mm-serial-parsers.c
+++ b/src/mm-serial-parsers.c
@@ -167,7 +167,7 @@ mm_serial_parser_v1_parse (gpointer   data,
                            GError   **error)
 {
     MMSerialParserV1 *parser = (MMSerialParserV1 *) data;
-    GMatchInfo *match_info;
+    GMatchInfo *match_info = NULL;
     GError *local_error = NULL;
     gboolean found = FALSE;
     char *str = NULL;
@@ -242,7 +242,7 @@ mm_serial_parser_v1_parse (gpointer   data,
             local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object);
             goto done;
         }
-        g_match_info_free (match_info);
+        g_clear_pointer (&match_info, g_match_info_free);
     }
 
     /* Numeric CME errors */
@@ -255,7 +255,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_mobile_equipment_error_for_code (atoi (str), log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* Numeric CMS errors */
     found = g_regex_match_full (parser->regex_cms_error,
@@ -267,7 +267,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_message_error_for_code (atoi (str), log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* String CME errors */
     found = g_regex_match_full (parser->regex_cme_error_str,
@@ -279,7 +279,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_mobile_equipment_error_for_string (str, log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* String CMS errors */
     found = g_regex_match_full (parser->regex_cms_error_str,
@@ -291,7 +291,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_message_error_for_string (str, log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* Motorola EZX errors */
     found = g_regex_match_full (parser->regex_ezx_error,
@@ -303,7 +303,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* Last resort; unknown error */
     found = g_regex_match_full (parser->regex_unknown_error,
@@ -313,7 +313,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* Connection failures */
     found = g_regex_match_full (parser->regex_connect_failed,
@@ -341,7 +341,7 @@ mm_serial_parser_v1_parse (gpointer   data,
         local_error = mm_connection_error_for_code (code, log_object);
         goto done;
     }
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
 
     /* NA error */
     found = g_regex_match_full (parser->regex_na,
@@ -357,7 +357,8 @@ mm_serial_parser_v1_parse (gpointer   data,
 
 done:
     g_free (str);
-    g_match_info_free (match_info);
+    g_clear_pointer (&match_info, g_match_info_free);
+
     if (found)
         response_clean (response);
 
diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c
index 21ed2f207..01f4c910b 100644
--- a/src/tests/test-modem-helpers.c
+++ b/src/tests/test-modem-helpers.c
@@ -1129,15 +1129,19 @@ test_creg_match (const char *test,
                  RegTestData *data,
                  const CregResult *result)
 {
-    guint i;
-    GMatchInfo *info  = NULL;
-    MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
-    MMModemAccessTechnology access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
-    gulong lac = 0, ci = 0;
-    GError *error = NULL;
-    gboolean success, cgreg = FALSE, cereg = FALSE, c5greg = FALSE;
-    guint regex_num = 0;
-    GPtrArray *array;
+    g_autoptr(GMatchInfo)         info  = NULL;
+    guint                         i;
+    MMModem3gppRegistrationState  state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
+    MMModemAccessTechnology       access_tech = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
+    gulong                        lac = 0;
+    gulong                        ci = 0;
+    GError                       *error = NULL;
+    gboolean                      success;
+    gboolean                      cgreg = FALSE;
+    gboolean                      cereg = FALSE;
+    gboolean                      c5greg = FALSE;
+    guint                         regex_num = 0;
+    GPtrArray                    *array;
 
     g_assert (reply);
     g_assert (test);
@@ -1158,8 +1162,7 @@ test_creg_match (const char *test,
             regex_num = i;
             break;
         }
-        g_match_info_free (info);
-        info = NULL;
+        g_clear_pointer (&info, g_match_info_free);
     }
 
     g_debug ("  regex_num (%u) == result->regex_num (%u)",
@@ -1171,7 +1174,6 @@ test_creg_match (const char *test,
 
     success = mm_3gpp_parse_creg_response (info, NULL, &state, &lac, &ci, &access_tech, &cgreg, &cereg, &c5greg, &error);
 
-    g_match_info_free (info);
     g_assert (success);
     g_assert_no_error (error);
     g_assert_cmpuint (state, ==, result->state);
@@ -3351,10 +3353,10 @@ common_parse_cds (const gchar *str,
                   guint expected_pdu_len,
                   const gchar *expected_pdu)
 {
-    GMatchInfo *match_info;
-    GRegex *regex;
-    gchar *pdu_len_str;
-    gchar *pdu;
+    g_autoptr(GMatchInfo)  match_info = NULL;
+    g_autoptr(GRegex)      regex = NULL;
+    g_autofree gchar      *pdu_len_str = NULL;
+    g_autofree gchar      *pdu = NULL;
 
     regex = mm_3gpp_cds_regex_get ();
     g_regex_match (regex, str, 0, &match_info);
@@ -3368,12 +3370,6 @@ common_parse_cds (const gchar *str,
     g_assert (pdu != NULL);
 
     g_assert_cmpstr (pdu, ==, expected_pdu);
-
-    g_free (pdu);
-    g_free (pdu_len_str);
-
-    g_match_info_free (match_info);
-    g_regex_unref (regex);
 }
 
 static void
@@ -4143,15 +4139,15 @@ static const ClipUrcTest clip_urc_tests[] = {
 static void
 test_clip_indication (void)
 {
-    GRegex *r;
-    guint   i;
+    g_autoptr(GRegex) r = NULL;
+    guint             i;
 
     r = mm_voice_clip_regex_get ();
 
     for (i = 0; i < G_N_ELEMENTS (clip_urc_tests); i++) {
-        GMatchInfo *match_info = NULL;
-        gchar      *number;
-        guint       type;
+        g_autoptr(GMatchInfo)  match_info = NULL;
+        g_autofree gchar      *number = NULL;
+        guint                  type;
 
         g_assert (g_regex_match (r, clip_urc_tests[i].str, 0, &match_info));
         g_assert (g_match_info_matches (match_info));
@@ -4161,12 +4157,7 @@ test_clip_indication (void)
 
         g_assert (mm_get_uint_from_match_info (match_info, 2, &type));
         g_assert_cmpuint (type, ==, clip_urc_tests[i].type);
-
-        g_free (number);
-        g_match_info_free (match_info);
     }
-
-    g_regex_unref (r);
 }
 
 /*****************************************************************************/
@@ -4188,16 +4179,16 @@ static const CcwaUrcTest ccwa_urc_tests[] = {
 static void
 test_ccwa_indication (void)
 {
-    GRegex *r;
-    guint   i;
+    g_autoptr(GRegex) r = NULL;
+    guint             i;
 
     r = mm_voice_ccwa_regex_get ();
 
     for (i = 0; i < G_N_ELEMENTS (ccwa_urc_tests); i++) {
-        GMatchInfo *match_info = NULL;
-        gchar      *number;
-        guint       type;
-        guint       class;
+        g_autoptr(GMatchInfo)  match_info = NULL;
+        g_autofree gchar      *number = NULL;
+        guint                  type;
+        guint                  class;
 
         g_assert (g_regex_match (r, ccwa_urc_tests[i].str, 0, &match_info));
         g_assert (g_match_info_matches (match_info));
@@ -4210,12 +4201,7 @@ test_ccwa_indication (void)
 
         g_assert (mm_get_uint_from_match_info (match_info, 3, &class));
         g_assert_cmpuint (class, ==, ccwa_urc_tests[i].class);
-
-        g_free (number);
-        g_match_info_free (match_info);
     }
-
-    g_regex_unref (r);
 }
 
 /*****************************************************************************/
-- 
GitLab

