diff --git a/intl/ChangeLog b/intl/ChangeLog
index fa518ec154a173d7a2451ddec4f2bb00f64e7006..a3762f81f566ca1a963f737ff456d951c82632e6 100644
--- a/intl/ChangeLog
+++ b/intl/ChangeLog
@@ -1,3 +1,22 @@
+2020-04-16  Jakub Jelinek  <jakub@redhat.com>
+
+	PR bootstrap/92008
+	* configure.ac: Add check for bison >= 3, AC_DEFINE HAVE_BISON3
+	and AC_SUBST BISON3_YES and BISON3_NO.
+	* Makefile.in (.y.c): Prefix $(YACC) invocation with @BISON3_NO@,
+	add @BISON3_YES@ prefixed rule to adjust the *.y source using sed
+	and adjust output afterwards.
+	* plural-exp.h (PLURAL_PARSE): If HAVE_BISON3 is defined, use
+	struct parse_args * type for arg instead of void *.
+	* plural.y: Add magic /* BISON3 ... */ comments with bison >= 3
+	directives.
+	(YYLEX_PARAM, YYPARSE_PARAM): Don't define if HAVE_BISON3 is defined.
+	(yylex, yyerror): Adjust prototypes and definitions if HAVE_BISON3
+	is defined.
+	* plural.c: Regenerated.
+	* config.h.in: Regenerated.
+	* configure: Regenerated.
+
 2020-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* configure: Regenerate.
diff --git a/intl/Makefile.in b/intl/Makefile.in
index 3dd0b7fe8fdf3906898749bdeb2d914f60babac3..bdb74ebb78c6af4be5fad7f37f31fd7fd5f13d72 100644
--- a/intl/Makefile.in
+++ b/intl/Makefile.in
@@ -133,7 +133,11 @@ libintl.h: $(srcdir)/libgnuintl.h
 	$(COMPILE) $<
 
 .y.c:
-	$(YACC) $(YFLAGS) --output $@ $<
+@BISON3_YES@	sed 's,%pure_parser,,;s,^/\* BISON3 \(.*\) \*/$$,\1,' $< > $@.y
+@BISON3_YES@	$(YACC) $(YFLAGS) --output $@.c $@.y
+@BISON3_YES@	sed 's/\.c\.y"/.y"/' $@.c > $@
+@BISON3_YES@	rm -f $@.c $@.y $@.h
+@BISON3_NO@	$(YACC) $(YFLAGS) --output $@ $<
 	rm -f $*.h
 
 INCLUDES = -I. -I$(srcdir)
diff --git a/intl/config.h.in b/intl/config.h.in
index 9c9b53dc0eac8b7cb63b7e1cc83f3f6ec16200c5..87738c0aad2398cdc6867e63fe45cdb80e2b2db0 100644
--- a/intl/config.h.in
+++ b/intl/config.h.in
@@ -28,6 +28,9 @@
 /* Define to 1 if you have the <argz.h> header file. */
 #undef HAVE_ARGZ_H
 
+/* Define if bison 3 or later is used. */
+#undef HAVE_BISON3
+
 /* Define if the GNU dcgettext() function is already present or preinstalled.
    */
 #undef HAVE_DCGETTEXT
diff --git a/intl/configure b/intl/configure
index 870b29f7d3fe660ba3d16b50a0c2dbad62dd3a34..58cee2983a5b1daf1939e994deaaf3367366b778 100755
--- a/intl/configure
+++ b/intl/configure
@@ -622,6 +622,8 @@ ac_unique_file="gettext.c"
 ac_header_list=
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
+BISON3_NO
+BISON3_YES
 INCINTL
 LIBINTL_DEP
 MAINT
@@ -6791,6 +6793,31 @@ case $USE_INCLUDED_LIBINTL in
     ;;
 esac
 
+BISON3_YES='#'
+BISON3_NO=
+if test "$INTLBISON" != :; then
+  ac_bison3=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking bison 3 or later" >&5
+$as_echo_n "checking bison 3 or later... " >&6; }
+  ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
+  case $ac_prog_version in
+    [3-9].*)
+      ac_prog_version="$ac_prog_version, bison3"; ac_bison3=yes;;
+    *) ac_prog_version="$ac_prog_version, old";;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_prog_version" >&5
+$as_echo "$ac_prog_version" >&6; }
+  if test $ac_bison3 = yes; then
+
+$as_echo "#define HAVE_BISON3 1" >>confdefs.h
+
+    BISON3_YES=
+    BISON3_NO='#'
+  fi
+fi
+
+
+
 ac_config_files="$ac_config_files Makefile config.intl"
 
 cat >confcache <<\_ACEOF
diff --git a/intl/configure.ac b/intl/configure.ac
index 48832b98f1aef74c1fdc9abb50a331225afaa604..b11033712bc589f9993cafb86d4b8e3f8fc8a8b2 100644
--- a/intl/configure.ac
+++ b/intl/configure.ac
@@ -47,5 +47,28 @@ case $USE_INCLUDED_LIBINTL in
     ;;
 esac
 
+BISON3_YES='#'
+BISON3_NO=
+if test "$INTLBISON" != :; then
+  ac_bison3=no
+  AC_MSG_CHECKING([bison 3 or later])
+changequote(<<,>>)dnl
+  ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'`
+  case $ac_prog_version in
+    [3-9].*)
+changequote([,])dnl
+      ac_prog_version="$ac_prog_version, bison3"; ac_bison3=yes;;
+    *) ac_prog_version="$ac_prog_version, old";;
+  esac
+  AC_MSG_RESULT([$ac_prog_version])
+  if test $ac_bison3 = yes; then
+    AC_DEFINE(HAVE_BISON3, 1, [Define if bison 3 or later is used.])
+    BISON3_YES=
+    BISON3_NO='#'
+  fi
+fi
+AC_SUBST(BISON3_YES)
+AC_SUBST(BISON3_NO)
+
 AC_CONFIG_FILES(Makefile config.intl)
 AC_OUTPUT
diff --git a/intl/plural-exp.h b/intl/plural-exp.h
index cedc0db68824222607499c8df0069f122d405ac5..e27c28050937889cf5a8595406da0649e6061b94 100644
--- a/intl/plural-exp.h
+++ b/intl/plural-exp.h
@@ -1,5 +1,5 @@
 /* Expression parsing and evaluation for plural form selection.
-   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
    This program is free software; you can redistribute it and/or modify it
@@ -111,7 +111,11 @@ struct parse_args
 
 extern void FREE_EXPRESSION PARAMS ((struct expression *exp))
      internal_function;
+#ifdef HAVE_BISON3
+extern int PLURAL_PARSE PARAMS ((struct parse_args *arg));
+#else
 extern int PLURAL_PARSE PARAMS ((void *arg));
+#endif
 extern struct expression GERMANIC_PLURAL attribute_hidden;
 extern void EXTRACT_PLURAL_EXPRESSION PARAMS ((const char *nullentry,
 					       struct expression **pluralp,
diff --git a/intl/plural.c b/intl/plural.c
index 951303a16f5ee0f5418c64023ed2b430a5bb71cd..ad86faa89ce325928dffb05c1f35b3fbf84b7e2f 100644
--- a/intl/plural.c
+++ b/intl/plural.c
@@ -19,7 +19,7 @@
 #line 1 "plural.y"
 
 /* Expression parsing for plural form selection.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
    This program is free software; you can redistribute it and/or modify it
@@ -59,10 +59,12 @@
 # define __gettextparse PLURAL_PARSE
 #endif
 
+#ifndef HAVE_BISON3
 #define YYLEX_PARAM	&((struct parse_args *) arg)->cp
 #define YYPARSE_PARAM	arg
+#endif
 
-#line 49 "plural.y"
+#line 54 "plural.y"
 #ifndef YYSTYPE
 typedef union {
   unsigned long int num;
@@ -72,7 +74,7 @@ typedef union {
 # define YYSTYPE yystype
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
-#line 55 "plural.y"
+#line 60 "plural.y"
 
 /* Prototypes for local functions.  */
 static struct expression *new_exp PARAMS ((int nargs, enum operator op,
@@ -87,8 +89,13 @@ static inline struct expression *new_exp_3 PARAMS ((enum operator op,
 						   struct expression *bexp,
 						   struct expression *tbranch,
 						   struct expression *fbranch));
+#ifdef HAVE_BISON3
+static int yylex PARAMS ((YYSTYPE *lval, struct parse_args *arg));
+static void yyerror PARAMS ((struct parse_args *arg, const char *str));
+#else
 static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
 static void yyerror PARAMS ((const char *str));
+#endif
 
 /* Allocation of expressions.  */
 
@@ -236,8 +243,8 @@ static const short yyrhs[] =
 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
 static const short yyrline[] =
 {
-       0,   174,   182,   186,   190,   194,   198,   202,   206,   210,
-     214,   218,   223
+       0,   184,   192,   196,   200,   204,   208,   212,   216,   220,
+     224,   228,   233
 };
 #endif
 
@@ -339,8 +346,8 @@ static const short yycheck[] =
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 /* As a special exception, when this file is copied by Bison into a
    Bison output file, you may use that output file without restriction.
@@ -1027,7 +1034,7 @@ yyreduce:
   switch (yyn) {
 
 case 1:
-#line 175 "plural.y"
+#line 185 "plural.y"
 {
 	    if (yyvsp[0].exp == NULL)
 	      YYABORT;
@@ -1035,68 +1042,68 @@ case 1:
 	  }
     break;
 case 2:
-#line 183 "plural.y"
+#line 193 "plural.y"
 {
 	    yyval.exp = new_exp_3 (qmop, yyvsp[-4].exp, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 3:
-#line 187 "plural.y"
+#line 197 "plural.y"
 {
 	    yyval.exp = new_exp_2 (lor, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 4:
-#line 191 "plural.y"
+#line 201 "plural.y"
 {
 	    yyval.exp = new_exp_2 (land, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 5:
-#line 195 "plural.y"
+#line 205 "plural.y"
 {
 	    yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 6:
-#line 199 "plural.y"
+#line 209 "plural.y"
 {
 	    yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 7:
-#line 203 "plural.y"
+#line 213 "plural.y"
 {
 	    yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 8:
-#line 207 "plural.y"
+#line 217 "plural.y"
 {
 	    yyval.exp = new_exp_2 (yyvsp[-1].op, yyvsp[-2].exp, yyvsp[0].exp);
 	  }
     break;
 case 9:
-#line 211 "plural.y"
+#line 221 "plural.y"
 {
 	    yyval.exp = new_exp_1 (lnot, yyvsp[0].exp);
 	  }
     break;
 case 10:
-#line 215 "plural.y"
+#line 225 "plural.y"
 {
 	    yyval.exp = new_exp_0 (var);
 	  }
     break;
 case 11:
-#line 219 "plural.y"
+#line 229 "plural.y"
 {
 	    if ((yyval.exp = new_exp_0 (num)) != NULL)
 	      yyval.exp->val.num = yyvsp[0].num;
 	  }
     break;
 case 12:
-#line 224 "plural.y"
+#line 234 "plural.y"
 {
 	    yyval.exp = yyvsp[-1].exp;
 	  }
@@ -1334,7 +1341,7 @@ yyreturn:
 #endif
   return yyresult;
 }
-#line 229 "plural.y"
+#line 239 "plural.y"
 
 
 void
@@ -1365,11 +1372,20 @@ FREE_EXPRESSION (exp)
 }
 
 
+#ifdef HAVE_BISON3
+static int
+yylex (lval, arg)
+     YYSTYPE *lval;
+     struct parse_args *arg;
+{
+  const char **pexp = &arg->cp;
+#else
 static int
 yylex (lval, pexp)
      YYSTYPE *lval;
      const char **pexp;
 {
+#endif
   const char *exp = *pexp;
   int result;
 
@@ -1510,8 +1526,14 @@ yylex (lval, pexp)
 }
 
 
+#ifdef HAVE_BISON3
+static void
+yyerror (arg, str)
+     struct parse_args *arg;
+#else
 static void
 yyerror (str)
+#endif
      const char *str;
 {
   /* Do nothing.  We don't print error messages here.  */
diff --git a/intl/plural.y b/intl/plural.y
index 3f75cf3dbbe4a1195a4c7437f4a68e5d708608d8..c97f09a6f697429021591e8a78a3774a6d181fad 100644
--- a/intl/plural.y
+++ b/intl/plural.y
@@ -1,6 +1,6 @@
 %{
 /* Expression parsing for plural form selection.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000-2020 Free Software Foundation, Inc.
    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
    This program is free software; you can redistribute it and/or modify it
@@ -40,10 +40,15 @@
 # define __gettextparse PLURAL_PARSE
 #endif
 
+#ifndef HAVE_BISON3
 #define YYLEX_PARAM	&((struct parse_args *) arg)->cp
 #define YYPARSE_PARAM	arg
+#endif
 %}
 %pure_parser
+/* BISON3 %parse-param {struct parse_args *arg} */
+/* BISON3 %lex-param {struct parse_args *arg} */
+/* BISON3 %define api.pure full */
 %expect 7
 
 %union {
@@ -66,8 +71,13 @@ static inline struct expression *new_exp_3 PARAMS ((enum operator op,
 						   struct expression *bexp,
 						   struct expression *tbranch,
 						   struct expression *fbranch));
+#ifdef HAVE_BISON3
+static int yylex PARAMS ((YYSTYPE *lval, struct parse_args *arg));
+static void yyerror PARAMS ((struct parse_args *arg, const char *str));
+#else
 static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
 static void yyerror PARAMS ((const char *str));
+#endif
 
 /* Allocation of expressions.  */
 
@@ -256,11 +266,20 @@ FREE_EXPRESSION (exp)
 }
 
 
+#ifdef HAVE_BISON3
+static int
+yylex (lval, arg)
+     YYSTYPE *lval;
+     struct parse_args *arg;
+{
+  const char **pexp = &arg->cp;
+#else
 static int
 yylex (lval, pexp)
      YYSTYPE *lval;
      const char **pexp;
 {
+#endif
   const char *exp = *pexp;
   int result;
 
@@ -401,8 +420,14 @@ yylex (lval, pexp)
 }
 
 
+#ifdef HAVE_BISON3
+static void
+yyerror (arg, str)
+     struct parse_args *arg;
+#else
 static void
 yyerror (str)
+#endif
      const char *str;
 {
   /* Do nothing.  We don't print error messages here.  */