Pablo Greco 40546a
From 85d367abe6063225117cc27c85e01e36a7b70409 Mon Sep 17 00:00:00 2001
Pablo Greco 40546a
Message-Id: <85d367abe6063225117cc27c85e01e36a7b70409@dist-git>
Pablo Greco 40546a
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
Pablo Greco 40546a
Date: Fri, 21 Jun 2019 09:24:47 +0200
Pablo Greco 40546a
Subject: [PATCH] cpu: simplify failure cleanup paths
Pablo Greco 40546a
MIME-Version: 1.0
Pablo Greco 40546a
Content-Type: text/plain; charset=UTF-8
Pablo Greco 40546a
Content-Transfer-Encoding: 8bit
Pablo Greco 40546a
Pablo Greco 40546a
Get rid of the separate 'error:' label, so all code paths jump straight
Pablo Greco 40546a
to the 'cleanup:' label.
Pablo Greco 40546a
Pablo Greco 40546a
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Pablo Greco 40546a
(cherry picked from commit 18cab54c3a0bc72390f29300684396690a7ecf51)
Pablo Greco 40546a
Pablo Greco 40546a
https://bugzilla.redhat.com/show_bug.cgi?id=1686895
Pablo Greco 40546a
Pablo Greco 40546a
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Pablo Greco 40546a
Message-Id: <40ff4abfea153cf8210286a84967c3ca7850b775.1561068591.git.jdenemar@redhat.com>
Pablo Greco 40546a
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Pablo Greco 40546a
---
Pablo Greco 40546a
 src/cpu/cpu_ppc64.c | 38 ++++++++++++------------
Pablo Greco 40546a
 src/cpu/cpu_x86.c   | 71 ++++++++++++++++++++-------------------------
Pablo Greco 40546a
 2 files changed, 49 insertions(+), 60 deletions(-)
Pablo Greco 40546a
Pablo Greco 40546a
diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
index 75da5b77d8..fcba7e9b37 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_ppc64.c
Pablo Greco 40546a
@@ -288,27 +288,28 @@ ppc64VendorParse(xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
Pablo Greco 40546a
 {
Pablo Greco 40546a
     struct ppc64_map *map = data;
Pablo Greco 40546a
     struct ppc64_vendor *vendor;
Pablo Greco 40546a
+    int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(vendor) < 0)
Pablo Greco 40546a
         return -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_STRDUP(vendor->name, name) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (ppc64VendorFind(map, vendor->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("CPU vendor %s already defined"), vendor->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
-    return 0;
Pablo Greco 40546a
+    ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
- error:
Pablo Greco 40546a
+ cleanup:
Pablo Greco 40546a
     ppc64VendorFree(vendor);
Pablo Greco 40546a
-    return -1;
Pablo Greco 40546a
+    return ret;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -327,15 +328,15 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(model) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_STRDUP(model->name, name) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (ppc64ModelFind(map, model->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("CPU model %s already defined"), model->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virXPathBoolean("boolean(./vendor)", ctxt)) {
Pablo Greco 40546a
@@ -344,14 +345,14 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Invalid vendor element in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (!(model->vendor = ppc64VendorFind(map, vendor))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Unknown vendor %s referenced by CPU model %s"),
Pablo Greco 40546a
                            vendor, model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -359,11 +360,11 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("Missing PVR information for CPU model %s"),
Pablo Greco 40546a
                        model->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC_N(model->data.pvr, n) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     model->data.len = n;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -374,7 +375,7 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing or invalid PVR value in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
         model->data.pvr[i].value = pvr;
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -382,24 +383,21 @@ ppc64ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing or invalid PVR mask in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
         model->data.pvr[i].mask = pvr;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
+    ppc64ModelFree(model);
Pablo Greco 40546a
     VIR_FREE(vendor);
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
-
Pablo Greco 40546a
- error:
Pablo Greco 40546a
-    ppc64ModelFree(model);
Pablo Greco 40546a
-    goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
Pablo Greco 40546a
index 11dbd1e757..ce48ca6867 100644
Pablo Greco 40546a
--- a/src/cpu/cpu_x86.c
Pablo Greco 40546a
+++ b/src/cpu/cpu_x86.c
Pablo Greco 40546a
@@ -731,15 +731,15 @@ x86VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_ALLOC(vendor) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_STRDUP(vendor->name, name) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (x86VendorFind(map, vendor->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("CPU vendor %s already defined"), vendor->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     string = virXPathString("string(@string)", ctxt);
Pablo Greco 40546a
@@ -747,24 +747,21 @@ x86VendorParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("Missing vendor string for CPU vendor %s"),
Pablo Greco 40546a
                        vendor->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virCPUx86VendorToCPUID(string, &vendor->cpuid) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
+    x86VendorFree(vendor);
Pablo Greco 40546a
     VIR_FREE(string);
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
-
Pablo Greco 40546a
- error:
Pablo Greco 40546a
-    x86VendorFree(vendor);
Pablo Greco 40546a
-    goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -904,17 +901,17 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(feature = x86FeatureNew()))
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     feature->migratable = true;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_STRDUP(feature->name, name) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (x86FeatureFind(map, feature->name)) {
Pablo Greco 40546a
         virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                        _("CPU feature %s already defined"), feature->name);
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     str = virXPathString("string(@migratable)", ctxt);
Pablo Greco 40546a
@@ -923,7 +920,7 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
 
Pablo Greco 40546a
     n = virXPathNodeSet("./cpuid", ctxt, &nodes);
Pablo Greco 40546a
     if (n < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < n; i++) {
Pablo Greco 40546a
         ctxt->node = nodes[i];
Pablo Greco 40546a
@@ -931,31 +928,28 @@ x86FeatureParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Invalid cpuid[%zu] in %s feature"),
Pablo Greco 40546a
                            i, feature->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
         if (virCPUx86DataAddCPUIDInt(&feature->data, &cpuid))
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!feature->migratable &&
Pablo Greco 40546a
         VIR_APPEND_ELEMENT_COPY(map->migrate_blockers,
Pablo Greco 40546a
                                 map->nblockers,
Pablo Greco 40546a
                                 feature) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_APPEND_ELEMENT(map->features, map->nfeatures, feature) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
+    x86FeatureFree(feature);
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
     VIR_FREE(str);
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
-
Pablo Greco 40546a
- error:
Pablo Greco 40546a
-    x86FeatureFree(feature);
Pablo Greco 40546a
-    goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
@@ -1168,10 +1162,10 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
     int ret = -1;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (!(model = x86ModelNew()))
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_STRDUP(model->name, name) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virXPathNode("./model", ctxt)) {
Pablo Greco 40546a
         virCPUx86ModelPtr ancestor;
Pablo Greco 40546a
@@ -1182,7 +1176,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing ancestor's name in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (!(ancestor = x86ModelFind(map, anname))) {
Pablo Greco 40546a
@@ -1190,7 +1184,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
                            _("Ancestor model %s not found for CPU model %s"),
Pablo Greco 40546a
                            anname, model->name);
Pablo Greco 40546a
             VIR_FREE(anname);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         VIR_FREE(anname);
Pablo Greco 40546a
@@ -1198,7 +1192,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         model->vendor = ancestor->vendor;
Pablo Greco 40546a
         model->signature = ancestor->signature;
Pablo Greco 40546a
         if (x86DataCopy(&model->data, &ancestor->data) < 0)
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (virXPathBoolean("boolean(./signature)", ctxt)) {
Pablo Greco 40546a
@@ -1211,7 +1205,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Invalid CPU signature family in model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         rc = virXPathUInt("string(./signature/@model)", ctxt, &sigModel);
Pablo Greco 40546a
@@ -1219,7 +1213,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Invalid CPU signature model in model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         model->signature = x86MakeSignature(sigFamily, sigModel, 0);
Pablo Greco 40546a
@@ -1231,20 +1225,20 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Invalid vendor element in CPU model %s"),
Pablo Greco 40546a
                            model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (!(model->vendor = x86VendorFind(map, vendor))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Unknown vendor %s referenced by CPU model %s"),
Pablo Greco 40546a
                            vendor, model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     n = virXPathNodeSet("./feature", ctxt, &nodes);
Pablo Greco 40546a
     if (n < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     for (i = 0; i < n; i++) {
Pablo Greco 40546a
         virCPUx86FeaturePtr feature;
Pablo Greco 40546a
@@ -1253,7 +1247,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
         if (!(ftname = virXMLPropString(nodes[i], "name"))) {
Pablo Greco 40546a
             virReportError(VIR_ERR_INTERNAL_ERROR,
Pablo Greco 40546a
                            _("Missing feature name for CPU model %s"), model->name);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (!(feature = x86FeatureFind(map, ftname))) {
Pablo Greco 40546a
@@ -1261,27 +1255,24 @@ x86ModelParse(xmlXPathContextPtr ctxt,
Pablo Greco 40546a
                            _("Feature %s required by CPU model %s not found"),
Pablo Greco 40546a
                            ftname, model->name);
Pablo Greco 40546a
             VIR_FREE(ftname);
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
         }
Pablo Greco 40546a
         VIR_FREE(ftname);
Pablo Greco 40546a
 
Pablo Greco 40546a
         if (x86DataAdd(&model->data, &feature->data))
Pablo Greco 40546a
-            goto error;
Pablo Greco 40546a
+            goto cleanup;
Pablo Greco 40546a
     }
Pablo Greco 40546a
 
Pablo Greco 40546a
     if (VIR_APPEND_ELEMENT(map->models, map->nmodels, model) < 0)
Pablo Greco 40546a
-        goto error;
Pablo Greco 40546a
+        goto cleanup;
Pablo Greco 40546a
 
Pablo Greco 40546a
     ret = 0;
Pablo Greco 40546a
 
Pablo Greco 40546a
  cleanup:
Pablo Greco 40546a
+    x86ModelFree(model);
Pablo Greco 40546a
     VIR_FREE(vendor);
Pablo Greco 40546a
     VIR_FREE(nodes);
Pablo Greco 40546a
     return ret;
Pablo Greco 40546a
-
Pablo Greco 40546a
- error:
Pablo Greco 40546a
-    x86ModelFree(model);
Pablo Greco 40546a
-    goto cleanup;
Pablo Greco 40546a
 }
Pablo Greco 40546a
 
Pablo Greco 40546a
 
Pablo Greco 40546a
-- 
Pablo Greco 40546a
2.22.0
Pablo Greco 40546a