Make GfxShading::parse & friends use unique_ptr
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 3c3b3c0..5d9d3e6 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -401,22 +401,20 @@
     return {};
 }
 
-GfxShading *GfxResources::lookupShading(const char *name, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxShading> GfxResources::lookupShading(const char *name, OutputDev *out, GfxState *state)
 {
     GfxResources *resPtr;
-    GfxShading *shading;
 
     for (resPtr = this; resPtr; resPtr = resPtr->next) {
         if (resPtr->shadingDict.isDict()) {
             Object obj = resPtr->shadingDict.dictLookup(name);
             if (!obj.isNull()) {
-                shading = GfxShading::parse(resPtr, &obj, out, state);
-                return shading;
+                return GfxShading::parse(resPtr, &obj, out, state);
             }
         }
     }
     error(errSyntaxError, -1, "ExtGState '{0:s}' is unknown", name);
-    return nullptr;
+    return {};
 }
 
 Object GfxResources::lookupGState(const char *name)
@@ -2332,7 +2330,7 @@
 
 void Gfx::opShFill(Object args[], int numArgs)
 {
-    GfxShading *shading;
+    std::unique_ptr<GfxShading> shading;
     GfxState *savedState;
     double xMin, yMin, xMax, yMax;
 
@@ -2374,21 +2372,21 @@
     // do shading type-specific operations
     switch (shading->getType()) {
     case GfxShading::FunctionBasedShading:
-        doFunctionShFill((GfxFunctionShading *)shading);
+        doFunctionShFill((GfxFunctionShading *)shading.get());
         break;
     case GfxShading::AxialShading:
-        doAxialShFill((GfxAxialShading *)shading);
+        doAxialShFill((GfxAxialShading *)shading.get());
         break;
     case GfxShading::RadialShading:
-        doRadialShFill((GfxRadialShading *)shading);
+        doRadialShFill((GfxRadialShading *)shading.get());
         break;
     case GfxShading::FreeFormGouraudShadedTriangleMesh:
     case GfxShading::LatticeFormGouraudShadedTriangleMesh:
-        doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading);
+        doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading.get());
         break;
     case GfxShading::CoonsPatchMesh:
     case GfxShading::TensorProductPatchMesh:
-        doPatchMeshShFill((GfxPatchMeshShading *)shading);
+        doPatchMeshShFill((GfxPatchMeshShading *)shading.get());
         break;
     }
 
@@ -2400,8 +2398,6 @@
 
     // restore graphics state
     restoreStateStack(savedState);
-
-    delete shading;
 }
 
 void Gfx::doFunctionShFill(GfxFunctionShading *shading)
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index 77da7a6..e1e8b8f 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -124,7 +124,7 @@
     Object lookupMarkedContentNF(const char *name);
     Object lookupColorSpace(const char *name);
     std::unique_ptr<GfxPattern> lookupPattern(const char *name, OutputDev *out, GfxState *state);
-    GfxShading *lookupShading(const char *name, OutputDev *out, GfxState *state);
+    std::unique_ptr<GfxShading> lookupShading(const char *name, OutputDev *out, GfxState *state);
     Object lookupGState(const char *name);
     Object lookupGStateNF(const char *name);
 
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index ae5dcdd..6646008 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -3333,7 +3333,6 @@
 std::unique_ptr<GfxShadingPattern> GfxShadingPattern::parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state, int patternRefNum)
 {
     Dict *dict;
-    GfxShading *shadingA;
     double matrixA[6];
     Object obj1;
     int i;
@@ -3344,7 +3343,7 @@
     dict = patObj->getDict();
 
     obj1 = dict->lookup("Shading");
-    shadingA = GfxShading::parse(res, &obj1, out, state);
+    std::unique_ptr<GfxShading> shadingA = GfxShading::parse(res, &obj1, out, state);
     if (!shadingA) {
         return {};
     }
@@ -3365,24 +3364,18 @@
         }
     }
 
-    auto pattern = new GfxShadingPattern(shadingA, matrixA, patternRefNum);
+    auto pattern = new GfxShadingPattern(std::move(shadingA), matrixA, patternRefNum);
     return std::unique_ptr<GfxShadingPattern>(pattern);
 }
 
-GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, const double *matrixA, int patternRefNumA) : GfxPattern(2, patternRefNumA)
+GfxShadingPattern::GfxShadingPattern(std::unique_ptr<GfxShading> &&shadingA, const double *matrixA, int patternRefNumA) : GfxPattern(2, patternRefNumA), shading(std::move(shadingA))
 {
-    int i;
-
-    shading = shadingA;
-    for (i = 0; i < 6; ++i) {
+    for (int i = 0; i < 6; ++i) {
         matrix[i] = matrixA[i];
     }
 }
 
-GfxShadingPattern::~GfxShadingPattern()
-{
-    delete shading;
-}
+GfxShadingPattern::~GfxShadingPattern() = default;
 
 std::unique_ptr<GfxPattern> GfxShadingPattern::copy() const
 {
@@ -3418,9 +3411,8 @@
 
 GfxShading::~GfxShading() = default;
 
-GfxShading *GfxShading::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxShading> GfxShading::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state)
 {
-    GfxShading *shading;
     Dict *dict;
     int typeA;
     Object obj1;
@@ -3430,67 +3422,58 @@
     } else if (obj->isStream()) {
         dict = obj->streamGetDict();
     } else {
-        return nullptr;
+        return {};
     }
 
     obj1 = dict->lookup("ShadingType");
     if (!obj1.isInt()) {
         error(errSyntaxWarning, -1, "Invalid ShadingType in shading dictionary");
-        return nullptr;
+        return {};
     }
     typeA = obj1.getInt();
 
     switch (typeA) {
     case 1:
-        shading = GfxFunctionShading::parse(res, dict, out, state);
+        return GfxFunctionShading::parse(res, dict, out, state);
         break;
     case 2:
-        shading = GfxAxialShading::parse(res, dict, out, state);
+        return GfxAxialShading::parse(res, dict, out, state);
         break;
     case 3:
-        shading = GfxRadialShading::parse(res, dict, out, state);
+        return GfxRadialShading::parse(res, dict, out, state);
         break;
     case 4:
         if (obj->isStream()) {
-            shading = GfxGouraudTriangleShading::parse(res, 4, dict, obj->getStream(), out, state);
+            return GfxGouraudTriangleShading::parse(res, 4, dict, obj->getStream(), out, state);
         } else {
             error(errSyntaxWarning, -1, "Invalid Type 4 shading object");
-            goto err1;
         }
         break;
     case 5:
         if (obj->isStream()) {
-            shading = GfxGouraudTriangleShading::parse(res, 5, dict, obj->getStream(), out, state);
+            return GfxGouraudTriangleShading::parse(res, 5, dict, obj->getStream(), out, state);
         } else {
             error(errSyntaxWarning, -1, "Invalid Type 5 shading object");
-            goto err1;
         }
         break;
     case 6:
         if (obj->isStream()) {
-            shading = GfxPatchMeshShading::parse(res, 6, dict, obj->getStream(), out, state);
+            return GfxPatchMeshShading::parse(res, 6, dict, obj->getStream(), out, state);
         } else {
             error(errSyntaxWarning, -1, "Invalid Type 6 shading object");
-            goto err1;
         }
         break;
     case 7:
         if (obj->isStream()) {
-            shading = GfxPatchMeshShading::parse(res, 7, dict, obj->getStream(), out, state);
+            return GfxPatchMeshShading::parse(res, 7, dict, obj->getStream(), out, state);
         } else {
             error(errSyntaxWarning, -1, "Invalid Type 7 shading object");
-            goto err1;
         }
         break;
     default:
         error(errSyntaxWarning, -1, "Unimplemented shading type {0:d}", typeA);
-        goto err1;
     }
-
-    return shading;
-
-err1:
-    return nullptr;
+    return {};
 }
 
 bool GfxShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
@@ -3576,9 +3559,8 @@
 
 GfxFunctionShading::~GfxFunctionShading() { }
 
-GfxFunctionShading *GfxFunctionShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxFunctionShading> GfxFunctionShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
 {
-    GfxFunctionShading *shading;
     double x0A, y0A, x1A, y1A;
     double matrixA[6];
     std::vector<std::unique_ptr<Function>> funcsA;
@@ -3597,7 +3579,7 @@
 
         if (!decodeOk) {
             error(errSyntaxWarning, -1, "Invalid Domain array in function shading dictionary");
-            return nullptr;
+            return {};
         }
     }
 
@@ -3619,7 +3601,7 @@
 
         if (!decodeOk) {
             error(errSyntaxWarning, -1, "Invalid Matrix array in function shading dictionary");
-            return nullptr;
+            return {};
         }
     }
 
@@ -3628,28 +3610,27 @@
         const int nFuncsA = obj1.arrayGetLength();
         if (nFuncsA > gfxColorMaxComps || nFuncsA <= 0) {
             error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
-            return nullptr;
+            return {};
         }
         for (i = 0; i < nFuncsA; ++i) {
             Object obj2 = obj1.arrayGet(i);
             Function *f = Function::parse(&obj2);
             if (!f) {
-                return nullptr;
+                return {};
             }
             funcsA.emplace_back(f);
         }
     } else {
         Function *f = Function::parse(&obj1);
         if (!f) {
-            return nullptr;
+            return {};
         }
         funcsA.emplace_back(f);
     }
 
-    shading = new GfxFunctionShading(x0A, y0A, x1A, y1A, matrixA, std::move(funcsA));
+    auto shading = std::make_unique<GfxFunctionShading>(x0A, y0A, x1A, y1A, matrixA, std::move(funcsA));
     if (!shading->init(res, dict, out, state)) {
-        delete shading;
-        return nullptr;
+        return {};
     }
     return shading;
 }
@@ -3693,9 +3674,9 @@
     return true;
 }
 
-GfxShading *GfxFunctionShading::copy() const
+std::unique_ptr<GfxShading> GfxFunctionShading::copy() const
 {
-    return new GfxFunctionShading(this);
+    return std::make_unique<GfxFunctionShading>(this);
 }
 
 void GfxFunctionShading::getColor(double x, double y, GfxColor *color) const
@@ -3948,9 +3929,8 @@
 
 GfxAxialShading::~GfxAxialShading() { }
 
-GfxAxialShading *GfxAxialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxAxialShading> GfxAxialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
 {
-    GfxAxialShading *shading;
     double x0A, y0A, x1A, y1A;
     double t0A, t1A;
     std::vector<std::unique_ptr<Function>> funcsA;
@@ -3966,7 +3946,7 @@
         y1A = obj1.arrayGet(3).getNumWithDefaultValue(0);
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
-        return nullptr;
+        return {};
     }
 
     t0A = 0;
@@ -3982,20 +3962,20 @@
         const int nFuncsA = obj1.arrayGetLength();
         if (nFuncsA > gfxColorMaxComps || nFuncsA == 0) {
             error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
-            return nullptr;
+            return {};
         }
         for (int i = 0; i < nFuncsA; ++i) {
             Object obj2 = obj1.arrayGet(i);
             Function *f = Function::parse(&obj2);
             if (!f) {
-                return nullptr;
+                return {};
             }
             funcsA.emplace_back(f);
         }
     } else {
         Function *f = Function::parse(&obj1);
         if (!f) {
-            return nullptr;
+            return {};
         }
         funcsA.emplace_back(f);
     }
@@ -4017,17 +3997,16 @@
         }
     }
 
-    shading = new GfxAxialShading(x0A, y0A, x1A, y1A, t0A, t1A, std::move(funcsA), extend0A, extend1A);
+    auto shading = std::make_unique<GfxAxialShading>(x0A, y0A, x1A, y1A, t0A, t1A, std::move(funcsA), extend0A, extend1A);
     if (!shading->init(res, dict, out, state)) {
-        delete shading;
-        shading = nullptr;
+        return {};
     }
     return shading;
 }
 
-GfxShading *GfxAxialShading::copy() const
+std::unique_ptr<GfxShading> GfxAxialShading::copy() const
 {
-    return new GfxAxialShading(this);
+    return std::make_unique<GfxAxialShading>(this);
 }
 
 double GfxAxialShading::getDistance(double sMin, double sMax) const
@@ -4129,9 +4108,8 @@
 
 GfxRadialShading::~GfxRadialShading() { }
 
-GfxRadialShading *GfxRadialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxRadialShading> GfxRadialShading::parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
 {
-    GfxRadialShading *shading;
     double x0A, y0A, r0A, x1A, y1A, r1A;
     double t0A, t1A;
     std::vector<std::unique_ptr<Function>> funcsA;
@@ -4150,7 +4128,7 @@
         r1A = obj1.arrayGet(5).getNumWithDefaultValue(0);
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid Coords in shading dictionary");
-        return nullptr;
+        return {};
     }
 
     t0A = 0;
@@ -4166,20 +4144,20 @@
         const int nFuncsA = obj1.arrayGetLength();
         if (nFuncsA > gfxColorMaxComps) {
             error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
-            return nullptr;
+            return {};
         }
         for (i = 0; i < nFuncsA; ++i) {
             Object obj2 = obj1.arrayGet(i);
             Function *f = Function::parse(&obj2);
             if (!f) {
-                return nullptr;
+                return {};
             }
             funcsA.emplace_back(f);
         }
     } else {
         Function *f = Function::parse(&obj1);
         if (!f) {
-            return nullptr;
+            return {};
         }
         funcsA.emplace_back(f);
     }
@@ -4191,17 +4169,16 @@
         extend1A = obj1.arrayGet(1).getBoolWithDefaultValue(false);
     }
 
-    shading = new GfxRadialShading(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, std::move(funcsA), extend0A, extend1A);
+    auto shading = std::make_unique<GfxRadialShading>(x0A, y0A, r0A, x1A, y1A, r1A, t0A, t1A, std::move(funcsA), extend0A, extend1A);
     if (!shading->init(res, dict, out, state)) {
-        delete shading;
-        return nullptr;
+        return {};
     }
     return shading;
 }
 
-GfxShading *GfxRadialShading::copy() const
+std::unique_ptr<GfxShading> GfxRadialShading::copy() const
 {
-    return new GfxRadialShading(this);
+    return std::make_unique<GfxRadialShading>(this);
 }
 
 double GfxRadialShading::getDistance(double sMin, double sMax) const
@@ -4613,9 +4590,8 @@
     gfree(triangles);
 }
 
-GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *gfxState)
+std::unique_ptr<GfxGouraudTriangleShading> GfxGouraudTriangleShading::parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *gfxState)
 {
-    GfxGouraudTriangleShading *shading;
     std::vector<std::unique_ptr<Function>> funcsA;
     int coordBits, compBits, flagBits, vertsPerRow, nRows;
     double xMin, xMax, yMin, yMax;
@@ -4636,22 +4612,22 @@
         coordBits = obj1.getInt();
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
-        return nullptr;
+        return {};
     }
     if (unlikely(coordBits <= 0)) {
         error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary");
-        return nullptr;
+        return {};
     }
     obj1 = dict->lookup("BitsPerComponent");
     if (obj1.isInt()) {
         compBits = obj1.getInt();
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
-        return nullptr;
+        return {};
     }
     if (unlikely(compBits <= 0 || compBits > 31)) {
         error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary");
-        return nullptr;
+        return {};
     }
     flagBits = vertsPerRow = 0; // make gcc happy
     if (typeA == 4) {
@@ -4660,7 +4636,7 @@
             flagBits = obj1.getInt();
         } else {
             error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
-            return nullptr;
+            return {};
         }
     } else {
         obj1 = dict->lookup("VerticesPerRow");
@@ -4668,7 +4644,7 @@
             vertsPerRow = obj1.getInt();
         } else {
             error(errSyntaxWarning, -1, "Missing or invalid VerticesPerRow in shading dictionary");
-            return nullptr;
+            return {};
         }
     }
     obj1 = dict->lookup("Decode");
@@ -4689,11 +4665,11 @@
 
         if (!decodeOk) {
             error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
-            return nullptr;
+            return {};
         }
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
-        return nullptr;
+        return {};
     }
 
     obj1 = dict->lookup("Function");
@@ -4702,20 +4678,20 @@
             const int nFuncsA = obj1.arrayGetLength();
             if (nFuncsA > gfxColorMaxComps) {
                 error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
-                return nullptr;
+                return {};
             }
             for (i = 0; i < nFuncsA; ++i) {
                 Object obj2 = obj1.arrayGet(i);
                 Function *f = Function::parse(&obj2);
                 if (!f) {
-                    return nullptr;
+                    return {};
                 }
                 funcsA.emplace_back(f);
             }
         } else {
             Function *f = Function::parse(&obj1);
             if (!f) {
-                return nullptr;
+                return {};
             }
             funcsA.emplace_back(f);
         }
@@ -4816,10 +4792,9 @@
         }
     }
 
-    shading = new GfxGouraudTriangleShading(typeA, verticesA, nVerticesA, trianglesA, nTrianglesA, std::move(funcsA));
+    auto shading = std::make_unique<GfxGouraudTriangleShading>(typeA, verticesA, nVerticesA, trianglesA, nTrianglesA, std::move(funcsA));
     if (!shading->init(res, dict, out, gfxState)) {
-        delete shading;
-        return nullptr;
+        return {};
     }
     return shading;
 }
@@ -4864,9 +4839,9 @@
     return true;
 }
 
-GfxShading *GfxGouraudTriangleShading::copy() const
+std::unique_ptr<GfxShading> GfxGouraudTriangleShading::copy() const
 {
-    return new GfxGouraudTriangleShading(this);
+    return std::make_unique<GfxGouraudTriangleShading>(this);
 }
 
 void GfxGouraudTriangleShading::getTriangle(int i, double *x0, double *y0, GfxColor *color0, double *x1, double *y1, GfxColor *color1, double *x2, double *y2, GfxColor *color2)
@@ -4952,9 +4927,8 @@
     gfree(patches);
 }
 
-GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state)
+std::unique_ptr<GfxPatchMeshShading> GfxPatchMeshShading::parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state)
 {
-    GfxPatchMeshShading *shading;
     std::vector<std::unique_ptr<Function>> funcsA;
     int coordBits, compBits, flagBits;
     double xMin, xMax, yMin, yMax;
@@ -4976,29 +4950,29 @@
         coordBits = obj1.getInt();
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary");
-        return nullptr;
+        return {};
     }
     if (unlikely(coordBits <= 0)) {
         error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary");
-        return nullptr;
+        return {};
     }
     obj1 = dict->lookup("BitsPerComponent");
     if (obj1.isInt()) {
         compBits = obj1.getInt();
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary");
-        return nullptr;
+        return {};
     }
     if (unlikely(compBits <= 0 || compBits > 31)) {
         error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary");
-        return nullptr;
+        return {};
     }
     obj1 = dict->lookup("BitsPerFlag");
     if (obj1.isInt()) {
         flagBits = obj1.getInt();
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid BitsPerFlag in shading dictionary");
-        return nullptr;
+        return {};
     }
     obj1 = dict->lookup("Decode");
     if (obj1.isArray() && obj1.arrayGetLength() >= 6) {
@@ -5018,11 +4992,11 @@
 
         if (!decodeOk) {
             error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
-            return nullptr;
+            return {};
         }
     } else {
         error(errSyntaxWarning, -1, "Missing or invalid Decode array in shading dictionary");
-        return nullptr;
+        return {};
     }
 
     obj1 = dict->lookup("Function");
@@ -5031,20 +5005,20 @@
             const int nFuncsA = obj1.arrayGetLength();
             if (nFuncsA > gfxColorMaxComps) {
                 error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary");
-                return nullptr;
+                return {};
             }
             for (i = 0; i < nFuncsA; ++i) {
                 Object obj2 = obj1.arrayGet(i);
                 Function *f = Function::parse(&obj2);
                 if (!f) {
-                    return nullptr;
+                    return {};
                 }
                 funcsA.emplace_back(f);
             }
         } else {
             Function *f = Function::parse(&obj1);
             if (!f) {
-                return nullptr;
+                return {};
             }
             funcsA.emplace_back(f);
         }
@@ -5121,7 +5095,7 @@
             patchesSize = (patchesSize == 0) ? 16 : 2 * patchesSize;
             patchesA = (GfxPatch *)greallocn_checkoverflow(patchesA, patchesSize, sizeof(GfxPatch));
             if (unlikely(!patchesA)) {
-                return nullptr;
+                return {};
             }
             memset(patchesA + oldPatchesSize, 0, (patchesSize - oldPatchesSize) * sizeof(GfxPatch));
         }
@@ -5199,7 +5173,7 @@
             case 2:
                 if (nPatchesA == 0) {
                     gfree(patchesA);
-                    return nullptr;
+                    return {};
                 }
                 p->x[0][0] = patchesA[nPatchesA - 1].x[3][3];
                 p->y[0][0] = patchesA[nPatchesA - 1].y[3][3];
@@ -5235,7 +5209,7 @@
             case 3:
                 if (nPatchesA == 0) {
                     gfree(patchesA);
-                    return nullptr;
+                    return {};
                 }
                 p->x[0][0] = patchesA[nPatchesA - 1].x[3][0];
                 p->y[0][0] = patchesA[nPatchesA - 1].y[3][0];
@@ -5314,7 +5288,7 @@
             case 1:
                 if (nPatchesA == 0) {
                     gfree(patchesA);
-                    return nullptr;
+                    return {};
                 }
                 p->x[0][0] = patchesA[nPatchesA - 1].x[0][3];
                 p->y[0][0] = patchesA[nPatchesA - 1].y[0][3];
@@ -5358,7 +5332,7 @@
             case 2:
                 if (nPatchesA == 0) {
                     gfree(patchesA);
-                    return nullptr;
+                    return {};
                 }
                 p->x[0][0] = patchesA[nPatchesA - 1].x[3][3];
                 p->y[0][0] = patchesA[nPatchesA - 1].y[3][3];
@@ -5402,7 +5376,7 @@
             case 3:
                 if (nPatchesA == 0) {
                     gfree(patchesA);
-                    return nullptr;
+                    return {};
                 }
                 p->x[0][0] = patchesA[nPatchesA - 1].x[3][0];
                 p->y[0][0] = patchesA[nPatchesA - 1].y[3][0];
@@ -5463,10 +5437,9 @@
         }
     }
 
-    shading = new GfxPatchMeshShading(typeA, patchesA, nPatchesA, std::move(funcsA));
+    auto shading = std::make_unique<GfxPatchMeshShading>(typeA, patchesA, nPatchesA, std::move(funcsA));
     if (!shading->init(res, dict, out, state)) {
-        delete shading;
-        return nullptr;
+        return {};
     }
     return shading;
 }
@@ -5523,9 +5496,9 @@
     }
 }
 
-GfxShading *GfxPatchMeshShading::copy() const
+std::unique_ptr<GfxShading> GfxPatchMeshShading::copy() const
 {
-    return new GfxPatchMeshShading(this);
+    return std::make_unique<GfxPatchMeshShading>(this);
 }
 
 //------------------------------------------------------------------------
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 797ad4d..b569438 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -845,13 +845,13 @@
 
     std::unique_ptr<GfxPattern> copy() const override;
 
-    GfxShading *getShading() { return shading; }
+    GfxShading *getShading() { return shading.get(); }
     const double *getMatrix() const { return matrix; }
 
 private:
-    GfxShadingPattern(GfxShading *shadingA, const double *matrixA, int patternRefNumA);
+    GfxShadingPattern(std::unique_ptr<GfxShading> &&shadingA, const double *matrixA, int patternRefNumA);
 
-    GfxShading *shading;
+    std::unique_ptr<GfxShading> shading;
     double matrix[6];
 };
 
@@ -880,9 +880,9 @@
     GfxShading(const GfxShading &) = delete;
     GfxShading &operator=(const GfxShading &other) = delete;
 
-    static GfxShading *parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxShading> parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state);
 
-    virtual GfxShading *copy() const = 0;
+    virtual std::unique_ptr<GfxShading> copy() const = 0;
 
     ShadingType getType() const { return type; }
     GfxColorSpace *getColorSpace() { return colorSpace.get(); }
@@ -960,9 +960,9 @@
     explicit GfxFunctionShading(const GfxFunctionShading *shading);
     ~GfxFunctionShading() override;
 
-    static GfxFunctionShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxFunctionShading> parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
 
-    GfxShading *copy() const override;
+    std::unique_ptr<GfxShading> copy() const override;
 
     void getDomain(double *x0A, double *y0A, double *x1A, double *y1A) const
     {
@@ -996,9 +996,9 @@
     explicit GfxAxialShading(const GfxAxialShading *shading);
     ~GfxAxialShading() override;
 
-    static GfxAxialShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxAxialShading> parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
 
-    GfxShading *copy() const override;
+    std::unique_ptr<GfxShading> copy() const override;
 
     void getCoords(double *x0A, double *y0A, double *x1A, double *y1A) const
     {
@@ -1027,9 +1027,9 @@
     explicit GfxRadialShading(const GfxRadialShading *shading);
     ~GfxRadialShading() override;
 
-    static GfxRadialShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxRadialShading> parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
 
-    GfxShading *copy() const override;
+    std::unique_ptr<GfxShading> copy() const override;
 
     void getCoords(double *x0A, double *y0A, double *r0A, double *x1A, double *y1A, double *r1A) const
     {
@@ -1066,9 +1066,9 @@
     explicit GfxGouraudTriangleShading(const GfxGouraudTriangleShading *shading);
     ~GfxGouraudTriangleShading() override;
 
-    static GfxGouraudTriangleShading *parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxGouraudTriangleShading> parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);
 
-    GfxShading *copy() const override;
+    std::unique_ptr<GfxShading> copy() const override;
 
     int getNTriangles() const { return nTriangles; }
 
@@ -1158,9 +1158,9 @@
     explicit GfxPatchMeshShading(const GfxPatchMeshShading *shading);
     ~GfxPatchMeshShading() override;
 
-    static GfxPatchMeshShading *parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);
+    static std::unique_ptr<GfxPatchMeshShading> parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);
 
-    GfxShading *copy() const override;
+    std::unique_ptr<GfxShading> copy() const override;
 
     int getNPatches() const { return nPatches; }
     const GfxPatch *getPatch(int i) const { return &patches[i]; }