summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/CHANGES10
-rw-r--r--cpp/src/slice2cpp/Gen.cpp26
-rw-r--r--cpp/src/slice2cppe/Gen.cpp11
-rw-r--r--cpp/test/Ice/objects/AllTests.cpp20
4 files changed, 55 insertions, 12 deletions
diff --git a/cpp/CHANGES b/cpp/CHANGES
index 579adf04531..4a819157f84 100644
--- a/cpp/CHANGES
+++ b/cpp/CHANGES
@@ -1,3 +1,13 @@
+Changes since version 3.1.0
+---------------------------
+
+- For non-abstract Slice classes, the C++ code generated now adds a
+ protected destructor. This prevents accidental allocation of
+ class instances on the stack or as static variables. For the
+ implementation of abstract Slice classes and for servant classes
+ applications can do the same thing and add a protected destructor
+ to prevent non-heap allocation.
+
Changes since version 3.0.1
---------------------------
diff --git a/cpp/src/slice2cpp/Gen.cpp b/cpp/src/slice2cpp/Gen.cpp
index 8f51fc4173e..d6eae4aa3b3 100644
--- a/cpp/src/slice2cpp/Gen.cpp
+++ b/cpp/src/slice2cpp/Gen.cpp
@@ -3108,6 +3108,19 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
C << nl << "extern \"C\" { void " << initfuncname << "() {} }";
C << nl << "#endif";
}
+
+ //
+ // We add a protected destructor to force heap instantiation of the class.
+ //
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+ H << sp << nl << "virtual ~" << fixKwd(p->name()) << "() {}";
+
+ if(!p->isAbstract() && !_doneStaticSymbol)
+ {
+ H << sp << nl << "friend class " << p->name() << "__staticInit;";
+ }
}
H << eb << ';';
@@ -3115,14 +3128,23 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
if(!p->isAbstract() && !p->isLocal())
{
//
- // We need an instance here to trigger initialization if the implementation is in a shared libarry.
+ // We need an instance here to trigger initialization if the implementation is in a shared library.
// But we do this only once per source file, because a single instance is sufficient to initialize
// all of the globals in a shared library.
+ // For a Slice class Foo, we instantiate a dummy class Foo__staticInit instead of using a static
+ // Foo instance directly because Foo has a protected destructor.
//
if(!_doneStaticSymbol)
{
+ H << sp << nl << "class " << p->name() << "__staticInit";
+ H << sb;
+ H.dec();
+ H << nl << "public:";
+ H.inc();
+ H << sp << nl << scoped << " _init;";
+ H << eb << ';';
_doneStaticSymbol = true;
- H << sp << nl << "static " << scoped << " __" << p->name() << "_init;";
+ H << sp << nl << "static " << scoped << "__staticInit _" << p->name() << "_init;";
}
}
diff --git a/cpp/src/slice2cppe/Gen.cpp b/cpp/src/slice2cppe/Gen.cpp
index c9e77de1445..8455816dbbc 100644
--- a/cpp/src/slice2cppe/Gen.cpp
+++ b/cpp/src/slice2cppe/Gen.cpp
@@ -2078,6 +2078,17 @@ Slice::Gen::ObjectVisitor::visitClassDefEnd(const ClassDefPtr& p)
}
+ //
+ // We add a protected destructor to force heap instantiation of the class.
+ //
+ if(!p->isAbstract())
+ {
+ H.dec();
+ H << sp << nl << "protected:";
+ H.inc();
+ H << sp << nl << "virtual ~" << fixKwd(p->name()) << "() {}";
+ }
+
H << eb << ';';
if(!p->isLocal())
diff --git a/cpp/test/Ice/objects/AllTests.cpp b/cpp/test/Ice/objects/AllTests.cpp
index a49eb3d8116..61f381fab5b 100644
--- a/cpp/test/Ice/objects/AllTests.cpp
+++ b/cpp/test/Ice/objects/AllTests.cpp
@@ -31,22 +31,22 @@ allTests(const Ice::CommunicatorPtr& communicator, bool collocated)
cout << "testing constructor, copy constructor, and assignment operator... " << flush;
- Base ba1;
- test(ba1.theS.str == "");
- test(ba1.str == "");
+ BasePtr ba1 = new Base;
+ test(ba1->theS.str == "");
+ test(ba1->str == "");
S s;
s.str = "hello";
- Base ba2(s, "hi");
- test(ba2.theS.str == "hello");
- test(ba2.str == "hi");
+ BasePtr ba2 = new Base(s, "hi");
+ test(ba2->theS.str == "hello");
+ test(ba2->str == "hi");
- ba1 = ba2;
- test(ba1.theS.str == "hello");
- test(ba1.str == "hi");
+ *ba1 = *ba2;
+ test(ba1->theS.str == "hello");
+ test(ba1->str == "hi");
BasePtr bp1 = new Base();
- *bp1 = ba2;
+ *bp1 = *ba2;
test(bp1->theS.str == "hello");
test(bp1->str == "hi");