diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/CHANGES | 10 | ||||
-rw-r--r-- | cpp/src/slice2cpp/Gen.cpp | 26 | ||||
-rw-r--r-- | cpp/src/slice2cppe/Gen.cpp | 11 | ||||
-rw-r--r-- | cpp/test/Ice/objects/AllTests.cpp | 20 |
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"); |