summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--THANKS1
-rw-r--r--tests/c++.at58
2 files changed, 38 insertions, 21 deletions
diff --git a/THANKS b/THANKS
index 9b7a8963..ebadb447 100644
--- a/THANKS
+++ b/THANKS
@@ -96,6 +96,7 @@ Odd Arild Olsen oao@fibula.no
Oleg Smolsky oleg.smolsky@pacific-simulators.co.nz
Oleksii Taran oleksii.taran@gmail.com
Paolo Bonzini bonzini@gnu.org
+Paolo Simone Gasparello djgaspa@gmail.com
Pascal Bart pascal.bart@epita.fr
Paul Eggert eggert@cs.ucla.edu
Paul Hilfinger Hilfinger@CS.Berkeley.EDU
diff --git a/tests/c++.at b/tests/c++.at
index 14a001a4..355e6247 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -649,14 +649,18 @@ AT_CLEANUP
## Exception safety. ##
## ------------------ ##
-# AT_TEST([BISON-DIRECTIVES])
-# ---------------------------
+# AT_TEST([BISON-DIRECTIVES = ''], [WITH-RECOVERY = "with"])
+# ----------------------------------------------------------
# Check that no object is leaked when exceptions are thrown.
+# WITH-RECOVERY = "with" or "without".
m4_pushdef([AT_TEST],
-[AT_SETUP([[Exception safety $1]])
+[AT_SETUP([[Exception safety $2 error recovery $1]])
AT_SKIP_IF_EXCEPTION_SUPPORT_IS_POOR
+m4_if([$1], [], [],
+ [m4_if([$2], [without], [AT_XFAIL_IF([true])])])
+
AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc" $1])
AT_DATA_GRAMMAR([[input.yy]],
@@ -669,43 +673,53 @@ $1
#include <cassert>
#include <cstdlib> // size_t and getenv.
#include <iostream>
- #include <list>
+ #include <set>
bool debug = false;
- /// A class that counts its number of instances.
+ /// A class that tracks its instances.
struct Object
{
char val;
- Object (char v)
- : val (v)
+ Object ()
+ : val ('?')
{
- Object::instances.push_back(this);
log (this, "Object::Object");
+ Object::instances.insert (this);
}
- Object ()
- : val ('?')
+ Object (const Object& that)
+ : val (that.val)
{
- Object::instances.push_back(this);
log (this, "Object::Object");
+ Object::instances.insert (this);
}
- Object& operator= (char v)
+ Object (char v)
+ : val (v)
{
- val = v;
- return *this;
+ log (this, "Object::Object");
+ Object::instances.insert (this);
}
~Object ()
{
- Object::instances.remove (this);
log (this, "Object::~Object");
+ objects::const_iterator i = instances.find (this);
+ // Make sure this object is alive.
+ assert (i != instances.end ());
+ Object::instances.erase (i);
+ }
+
+ Object& operator= (char v)
+ {
+ val = v;
+ return *this;
}
// Static part.
- typedef std::list<const Object*> objects;
+ typedef std::set<const Object*> objects;
static objects instances;
static bool
@@ -800,7 +814,8 @@ item:
| 'p' { $$ = $][1; }
| 's' { $$ = $][1; throw std::runtime_error ("reduction"); }
| 'T' { ]AT_VARIANT_IF([], [$$ = YY_NULLPTR; delete $][1]; )[YYABORT; }
-| error { ]AT_VARIANT_IF([], [$][$ = YY_NULLPTR; ])[yyerrok; }
+]m4_if([$2], [with],
+[[| error { $$ = ]AT_VARIANT_IF([], [new ])[Object ('R'); yyerrok; }]])[
;
%%
@@ -903,16 +918,17 @@ AT_PARSER_CHECK([[./input aaaaE]], [[2]], [[]],
AT_PARSER_CHECK([[./input aaaaT]], [[1]])
-# There is error-recovery, so exit success.
-AT_PARSER_CHECK([[./input aaaaR]], [[0]])
+AT_PARSER_CHECK([[./input aaaaR]], [m4_if([$2], [with], [0], [1])])
AT_BISON_OPTION_POPDEFS
AT_CLEANUP
])
-AT_TEST
-AT_TEST([%define api.value.type variant])
+AT_TEST([], [with])
+AT_TEST([], [without])
+AT_TEST([%define api.value.type variant], [with])
+AT_TEST([%define api.value.type variant], [without])
m4_popdef([AT_TEST])