diff --git a/src/data.cpp b/src/data.cpp index d9b49ca..95af43f 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -655,7 +655,10 @@ void Value::copyIn(const void *ptr, StoreType type) // assigning variant union. auto& val = store->as(); if(type==StoreType::Compound) { - val = *reinterpret_cast(ptr); + auto& newval = *reinterpret_cast(ptr); + if(store == newval.store) + throw std::logic_error("Any self-assignment would recurse. Not allowed."); + val = newval; break; } else { diff --git a/test/testdata.cpp b/test/testdata.cpp index 3e9cd31..db3b03b 100644 --- a/test/testdata.cpp +++ b/test/testdata.cpp @@ -98,6 +98,24 @@ void testAssignUnion() testTrue(val["->"].valid()); } +void testAssignAny() +{ + testDiag("%s", __func__); + + auto val = TypeDef(TypeCode::Any).create(); + + // check the simple self assignment is an error. + testThrows([&val](){ + val.from(val); + }); + + val = 42; + + testThrows([&val](){ + val.from(val); + }); +} + void testName() { testDiag("%s", __func__); @@ -416,11 +434,12 @@ void testClear() MAIN(testdata) { - testPlan(146); + testPlan(148); testSetup(); testTraverse(); testAssign(); testAssignUnion(); + testAssignAny(); testName(); testIterStruct(); testIterUnion();