[PATCH] c++: fix %define api.value.automove false to actually disable automove

* Fixes bug reported in 
https://lists.gnu.org/archive/html/bug-bison/2025-07/msg00002.html
* Previously a false value still applied std::move to semantic values on
  the right-hand sides of a rule.
* Added tests for all 5 possible settings for api.value.automove.
* Added NEWS entry.
---
 NEWS                    |   8 ++++
 data/skeletons/c++.m4   |   2 +
 data/skeletons/lalr1.cc |   7 ++-
 tests/c++.at            | 103 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 116 insertions(+), 4 deletions(-)


diff --git a/NEWS b/NEWS
index cdef3238..8c7dd6bc 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,14 @@ GNU Bison NEWS
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Bug fixes
+
+*** Bug fixes in lalr1.cc
+
+  The `api.value.automove` %define variable did not honor an explicit
+  false value. Now `%define api.value.automove false` doesn't generate
+  automatic moves of semantic values on the right-hand sides of a rule.
+
   The `cex.timeout` %define variable allows to control when we give up
   finding a unifying counterexample.  For instance `bison -Wcex
   -Dcex.timeout=.5 gram.y` to limit to 1/2s.
diff --git a/data/skeletons/c++.m4 b/data/skeletons/c++.m4
index fa26b069..61a49041 100644
--- a/data/skeletons/c++.m4
+++ b/data/skeletons/c++.m4
@@ -113,6 +113,8 @@ b4_percent_define_default([[define_location_comparison]],
                           [m4_if(b4_percent_define_get([[filename_type]]),
                                  [std::string], [[true]], [[false]])])
 
+# api.value.automove boolean default value false
+b4_percent_define_default([[api.value.automove]], [[false]])
 
 
 ## ----------- ##
diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc
index 9f60d2b4..c000a062 100644
--- a/data/skeletons/lalr1.cc
+++ b/data/skeletons/lalr1.cc
@@ -111,10 +111,9 @@ m4_define([_b4_rhs_value],
 [b4_symbol_value([b4_rhs_data([$1], [$2]).value], [$3], [$4])])
 
 m4_define([b4_rhs_value],
-[b4_percent_define_ifdef([api.value.automove],
-                         [YY_MOVE (_b4_rhs_value($@))],
-                         [_b4_rhs_value($@)])])
-
+[b4_percent_define_flag_if([api.value.automove],
+                           [YY_MOVE (_b4_rhs_value($@))],
+                           [_b4_rhs_value($@)])])
 
 # b4_rhs_location(RULE-LENGTH, POS)
 # ---------------------------------
diff --git a/tests/c++.at b/tests/c++.at
index 3a60fea4..b37724a3 100644
--- a/tests/c++.at
+++ b/tests/c++.at
@@ -240,6 +240,109 @@ AT_FOR_EACH_CXX([
 AT_BISON_OPTION_POPDEFS
 AT_CLEANUP
 
+## --------------------------------------------------- ##
+## All possible settings for api.value.automove.       ##
+## --------------------------------------------------- ##
+
+AT_SETUP([Check omitted api.value.automove default value])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
+
+AT_DATA_GRAMMAR([input.yy],
+[[%skeleton "lalr1.cc"
+%language "c++"
+%token <int> VAL
+%nterm <int> exp
+%%
+exp: VAL
+]])
+
+AT_BISON_CHECK([-o input.cc input.yy])
+AT_CHECK([grep 'yylhs\.value\.int.*YY_MOVE *' input.cc], 1, [ignore])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
+AT_SETUP([Check api.value.automove defined with no value])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
+
+AT_DATA_GRAMMAR([input.yy],
+[[%skeleton "lalr1.cc"
+%language "c++"
+%define api.value.automove
+%token <int> VAL
+%nterm <int> exp
+%%
+exp: VAL
+]])
+
+AT_BISON_CHECK([-o input.cc input.yy])
+AT_CHECK([grep 'yylhs\.value\.int.*YY_MOVE *' input.cc], 0, [ignore])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
+AT_SETUP([Check api.value.automove true value])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
+
+AT_DATA_GRAMMAR([input.yy],
+[[%skeleton "lalr1.cc"
+%language "c++"
+%define api.value.automove true
+%token <int> VAL
+%nterm <int> exp
+%%
+exp: VAL
+]])
+
+AT_BISON_CHECK([-o input.cc input.yy])
+AT_CHECK([grep 'yylhs\.value\.int.*YY_MOVE *' input.cc], 0, [ignore])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
+AT_SETUP([Check api.value.automove false value])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
+
+AT_DATA_GRAMMAR([input.yy],
+[[%skeleton "lalr1.cc"
+%language "c++"
+%define api.value.automove false
+%token <int> VAL
+%nterm <int> exp
+%%
+exp: VAL
+]])
+
+AT_BISON_CHECK([-o input.cc input.yy])
+AT_CHECK([grep 'yylhs\.value\.int.*YY_MOVE *' input.cc], 1, [ignore])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
+AT_SETUP([Check api.value.automove empty string value])
+
+AT_BISON_OPTION_PUSHDEFS([%skeleton "lalr1.cc"])
+
+AT_DATA_GRAMMAR([input.yy],
+[[%skeleton "lalr1.cc"
+%language "c++"
+%define api.value.automove ""
+%token <int> VAL
+%nterm <int> exp
+%%
+exp: VAL
+]])
+
+AT_BISON_CHECK([-o input.cc input.yy])
+AT_CHECK([grep 'yylhs\.value\.int.*YY_MOVE *' input.cc], 0, [ignore])
+
+AT_BISON_OPTION_POPDEFS
+AT_CLEANUP
+
 ## --------------------------------------------------- ##
 ## Multiple occurrences of $n and api.value.automove.  ##
 ## --------------------------------------------------- ##
-- 
2.45.1

Attachment: zmajeed_fix_automove_false_directive.patch
Description: Binary data

Reply via email to