From 4546b4bd56c2e7274c8a54f7c9f019f20bc8fc2d Mon Sep 17 00:00:00 2001
From: Oliver Sander <oliver.sander@tu-dresden.de>
Date: Fri, 2 Oct 2020 16:30:06 +0200
Subject: [PATCH] Guard against misuse of AxisAlignedCubeGeometry constructor

The AxisAlignedCubeGeometry has always had a constructor that was always
intended to be used with dim==coorddim only.  However, this precondition
was never checked anywhere, which could lead to strange bugs.
This patch introduces a static_assert that fails at compile time
if the dim==coorddim precondition is not met.

BUG: https://gitlab.dune-project.org/core/dune-geometry/-/issues/25
---
 CHANGELOG.md                                       |  6 ++++++
 dune/geometry/axisalignedcubegeometry.hh           |  1 +
 dune/geometry/refinement/hcube.cc                  | 11 +++++++----
 dune/geometry/test/test-axisalignedcubegeometry.cc |  7 +++++--
 4 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 88060895..e9633535 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,12 @@
   Furthermore, flags for either shared library or position independent code
   needs to be used.
 
+- The class `AxisAlignedCubeGeometry` has always had a constructor taking
+  two arguments `FieldVector<ctype,coorddim> lower` and `FieldVector<ctype,coorddim> upper`.
+  This constructor was always to be used in the case `dim==coorddim` only,
+  but this was never enforced.  Starting with version 2.8, compilation
+  fails with an error message if this constructor is used with `dim!=coorddim`.
+
 ## Deprecations and removals
 
 - Remove code needed to use reference elements by reference.
diff --git a/dune/geometry/axisalignedcubegeometry.hh b/dune/geometry/axisalignedcubegeometry.hh
index b4d6ca09..65df510e 100644
--- a/dune/geometry/axisalignedcubegeometry.hh
+++ b/dune/geometry/axisalignedcubegeometry.hh
@@ -99,6 +99,7 @@ namespace Dune {
         upper_(upper),
         axes_()
     {
+      static_assert(dim==coorddim, "Use this constructor only if dim==coorddim!");
       // all 'true', but is never actually used
       axes_ = (1<<coorddim)-1;
     }
diff --git a/dune/geometry/refinement/hcube.cc b/dune/geometry/refinement/hcube.cc
index 27855e7c..9c92fc9a 100644
--- a/dune/geometry/refinement/hcube.cc
+++ b/dune/geometry/refinement/hcube.cc
@@ -397,19 +397,22 @@ namespace Dune
 
         assert(codimension == 0 or codimension == dimension);
 
-        if (codimension == 0) {
+        if constexpr (codimension == 0) {
           for (size_t j = 0; j < dimension; j++)
           {
             lower[j] = double(intCoords[j])     / double(_nIntervals);
             upper[j] = double(intCoords[j] + 1) / double(_nIntervals);
           }
+
+          return typename RefinementImp<dimension,
+                                        CoordType>::template Codim<codimension>::Geometry(lower,upper);
         } else {
           for (size_t j = 0; j < dimension; j++)
             lower[j] = upper[j] = double(intCoords[j]) / double(_nIntervals);
-        }
 
-        return typename RefinementImp<dimension,
-            CoordType>::template Codim<codimension>::Geometry(lower,upper);
+          return typename RefinementImp<dimension,
+                                        CoordType>::template Codim<codimension>::Geometry(lower,upper,std::bitset<dimension>(0));
+        }
       }
 
 #endif // DOXYGEN
diff --git a/dune/geometry/test/test-axisalignedcubegeometry.cc b/dune/geometry/test/test-axisalignedcubegeometry.cc
index ec932545..2ec10cd9 100644
--- a/dune/geometry/test/test-axisalignedcubegeometry.cc
+++ b/dune/geometry/test/test-axisalignedcubegeometry.cc
@@ -58,8 +58,11 @@ void testCodimZero(int& result)
 
   FieldVector<double,coorddim> lower(0);
   FieldVector<double,coorddim> upper(1);
+  std::bitset<coorddim> axes(0);
+  for (int i=0; i<dim; i++)
+    axes[i] = true;
 
-  ElementGeometry geometry( lower, upper );
+  ElementGeometry geometry( lower, upper, axes );
 
   if (checkGeometry(geometry))
     pass(result);
@@ -69,7 +72,7 @@ void testCodimZero(int& result)
   testBasicGeometryAffine(geometry, result);
 
   // test assignability
-  ElementGeometry geometry2( lower, upper );
+  ElementGeometry geometry2( lower, upper, axes );
   geometry2 = geometry;
 }
 
-- 
GitLab