C++ PATCHes to mangling of sizeof... and fold-expressions

Jason Merrill jason@redhat.com
Fri Jul 15 16:52:00 GMT 2016


Investigating the ICE in 71814, I found that we never implemented the
specified mangling for sizeof...; sZ for a simple sizeof...(pack) and
sP for a more complicated form involving an alias template.  So the
first patch implements mangling and demangling those forms.

Similarly, 71711 shows that we never implemented mangling of C++17
fold-expressions, or partial instantiation of them.

The last patch bumps -fabi-version to 11 to deal with the change in
sizeof... mangling.

Tested x86_64-pc-linux-gnu, applying to trunk.
-------------- next part --------------
commit 81272a102f30521982d4e6442d1ef7b868f2d1fa
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jul 11 16:02:42 2016 -0400

    	PR c++/71814 - mangling sizeof... (sP and sZ)
    
    gcc/cp/
    	* mangle.c (write_expression): Handle sizeof... an argument pack.
    libiberty/
    	* cp-demangle.c (cplus_demangle_operators): Add sP and sZ.
    	(d_print_comp_inner): Handle them.
    	(d_template_args_1): Split out from d_template_args.
    	(d_args_length): New.

diff --git a/gcc/common.opt b/gcc/common.opt
index 2b68fa7..b56ba47 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -882,6 +882,9 @@ Driver Undocumented
 ;     identity, such as ia32 calling convention attributes (stdcall, etc.)
 ;     Default in G++ 6 (set in c_common_post_options).
 ;
+; 11: The version of the ABI that corrects mangling of sizeof... expressions.
+;     Default in G++ 7.
+;
 ; Additional positive integers will be assigned as new versions of
 ; the ABI become the default version of the ABI.
 fabi-version=
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 0e44409..8205da9 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2767,17 +2767,67 @@ write_expression (tree expr)
       write_mangled_name (expr, false);
       write_char ('E');
     }
-  else if (TREE_CODE (expr) == SIZEOF_EXPR
-	   && SIZEOF_EXPR_TYPE_P (expr))
+  else if (TREE_CODE (expr) == SIZEOF_EXPR)
     {
-      write_string ("st");
-      write_type (TREE_TYPE (TREE_OPERAND (expr, 0)));
-    }
-  else if (TREE_CODE (expr) == SIZEOF_EXPR
-	   && TYPE_P (TREE_OPERAND (expr, 0)))
-    {
-      write_string ("st");
-      write_type (TREE_OPERAND (expr, 0));
+      tree op = TREE_OPERAND (expr, 0);
+
+      if (PACK_EXPANSION_P (op))
+	{
+	  if (abi_warn_or_compat_version_crosses (11))
+	    G.need_abi_warning = true;
+	  if (abi_version_at_least (11))
+	    {
+	      /* sZ rather than szDp.  */
+	      write_string ("sZ");
+	      write_expression (PACK_EXPANSION_PATTERN (op));
+	      return;
+	    }
+	}
+
+      if (SIZEOF_EXPR_TYPE_P (expr))
+	{
+	  write_string ("st");
+	  write_type (TREE_TYPE (op));
+	}
+      else if (ARGUMENT_PACK_P (op))
+	{
+	  tree args = ARGUMENT_PACK_ARGS (op);
+	  int length = TREE_VEC_LENGTH (args);
+	  if (abi_warn_or_compat_version_crosses (10))
+	    G.need_abi_warning = true;
+	  if (abi_version_at_least (10))
+	    {
+	      /* sP <template-arg>* E # sizeof...(T), size of a captured
+		 template parameter pack from an alias template */
+	      write_string ("sP");
+	      for (int i = 0; i < length; ++i)
+		write_template_arg (TREE_VEC_ELT (args, i));
+	      write_char ('E');
+	    }
+	  else
+	    {
+	      /* In GCC 5 we represented this sizeof wrong, with the effect
+		 that we mangled it as the last element of the pack.  */
+	      tree arg = TREE_VEC_ELT (args, length-1);
+	      if (TYPE_P (op))
+		{
+		  write_string ("st");
+		  write_type (arg);
+		}
+	      else
+		{
+		  write_string ("sz");
+		  write_expression (arg);
+		}
+	    }
+	}
+      else if (TYPE_P (TREE_OPERAND (expr, 0)))
+	{
+	  write_string ("st");
+	  write_type (TREE_OPERAND (expr, 0));
+	}
+      else
+	goto normal_expr;
     }
   else if (TREE_CODE (expr) == ALIGNOF_EXPR
 	   && TYPE_P (TREE_OPERAND (expr, 0)))
@@ -2947,6 +2997,7 @@ write_expression (tree expr)
     }
   else
     {
+    normal_expr:
       int i, len;
       const char *name;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1.C
new file mode 100644
index 0000000..51f9581
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1.C
@@ -0,0 +1,11 @@
+// Test for sZ mangling.
+// { dg-do compile { target c++11 } }
+// { dg-final { scan-assembler "_Z1fIJidEEv1AIXsZT_EE" } }
+
+template <int I> struct A { };
+template <typename... Ts> void f(A<sizeof...(Ts)>);
+
+int main()
+{
+  f<int,double>(A<2>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C
new file mode 100644
index 0000000..b230ffa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle1a.C
@@ -0,0 +1,12 @@
+// Test for sZ mangling.
+// { dg-do compile { target c++11 } }
+// { dg-final { scan-assembler "_Z1fIJidEEv1AIXstDpT_EE" } }
+// { dg-options -fabi-version=9 }
+
+template <int I> struct A { };
+template <typename... Ts> void f(A<sizeof...(Ts)>);
+
+int main()
+{
+  f<int,double>(A<2>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2.C
new file mode 100644
index 0000000..ea96ef8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2.C
@@ -0,0 +1,18 @@
+// Testcase from cxx-abi-dev.
+// { dg-do compile { target c++11 } }
+
+struct A {
+  template<int...T> using N = int[sizeof...(T)];
+  template<int...A> void f(N<A...> &);
+
+  template<typename...T> using M = int[sizeof...(T)];
+  template<typename...A> void g(M<A...> &);
+};
+void g(A a)
+{
+  int arr[3];
+  // { dg-final { scan-assembler "_ZN1A1fIJLi1ELi2ELi3EEEEvRAsZT__i" } }
+  a.f<1,2,3>(arr);
+  // { dg-final { scan-assembler "_ZN1A1gIJiiiEEEvRAsZT__i" } }
+  a.g<int,int,int>(arr);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C
new file mode 100644
index 0000000..3ac1517
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle2a.C
@@ -0,0 +1,19 @@
+// Testcase from cxx-abi-dev.
+// { dg-do compile { target c++11 } }
+// { dg-options "-fabi-version=9" }
+
+struct A {
+  template<int...T> using N = int[sizeof...(T)];
+  template<int...A> void f(N<A...> &);
+
+  template<typename...T> using M = int[sizeof...(T)];
+  template<typename...A> void g(M<A...> &);
+};
+void g(A a)
+{
+  int arr[3];
+  // { dg-final { scan-assembler "_ZN1A1fIJLi1ELi2ELi3EEEEvRAszspT__i" } }
+  a.f<1,2,3>(arr);
+  // { dg-final { scan-assembler "_ZN1A1gIJiiiEEEvRAstDpT__i" } }
+  a.g<int,int,int>(arr);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C
new file mode 100644
index 0000000..f239ef7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3.C
@@ -0,0 +1,10 @@
+// Testcase from cxx-abi-dev.
+// { dg-do compile { target c++11 } }
+// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_" } }
+
+struct A {
+  template<typename...T> using N = int[sizeof...(T)];
+  template<typename...A, typename B, typename...C>
+      void f(N<A..., B, C...> &, B, C...);
+};
+void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C
new file mode 100644
index 0000000..eba8f59
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic-mangle3a.C
@@ -0,0 +1,11 @@
+// Testcase from cxx-abi-dev.
+// { dg-do compile { target c++11 } }
+// { dg-options -fabi-version=9 }
+// { dg-final { scan-assembler "_ZN1A1fIJiiEiJiiiEEEvRAstDpT1__iT0_S2_" } }
+
+struct A {
+  template<typename...T> using N = int[sizeof...(T)];
+  template<typename...A, typename B, typename...C>
+      void f(N<A..., B, C...> &, B, C...);
+};
+void g(A a) { int arr[6]; a.f<int, int>(arr, 1, 2, 3, 4); }
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 7f664b9..56d3bcb 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -466,6 +466,7 @@ static struct demangle_component *
 d_template_param (struct d_info *);
 
 static struct demangle_component *d_template_args (struct d_info *);
+static struct demangle_component *d_template_args_1 (struct d_info *);
 
 static struct demangle_component *
 d_template_arg (struct d_info *);
@@ -1795,6 +1796,8 @@ const struct demangle_operator_info cplus_demangle_operators[] =
   { "rc", NL ("reinterpret_cast"), 2 },
   { "rm", NL ("%"),         2 },
   { "rs", NL (">>"),        2 },
+  { "sP", NL ("sizeof..."), 1 },
+  { "sZ", NL ("sizeof..."), 1 },
   { "sc", NL ("static_cast"), 2 },
   { "st", NL ("sizeof "),   1 },
   { "sz", NL ("sizeof "),   1 },
@@ -2995,6 +2998,19 @@ d_template_param (struct d_info *di)
 static struct demangle_component *
 d_template_args (struct d_info *di)
 {
+  if (d_peek_char (di) != 'I'
+      && d_peek_char (di) != 'J')
+    return NULL;
+  d_advance (di, 1);
+
+  return d_template_args_1 (di);
+}
+
+/* <template-arg>* E  */
+
+static struct demangle_component *
+d_template_args_1 (struct d_info *di)
+{
   struct demangle_component *hold_last_name;
   struct demangle_component *al;
   struct demangle_component **pal;
@@ -3004,11 +3020,6 @@ d_template_args (struct d_info *di)
      constructor or destructor.  */
   hold_last_name = di->last_name;
 
-  if (d_peek_char (di) != 'I'
-      && d_peek_char (di) != 'J')
-    return NULL;
-  d_advance (di, 1);
-
   if (d_peek_char (di) == 'E')
     {
       /* An argument pack can be empty.  */
@@ -3270,6 +3281,8 @@ d_expression_1 (struct d_info *di)
 	    if (op->type == DEMANGLE_COMPONENT_CAST
 		&& d_check_char (di, '_'))
 	      operand = d_exprlist (di, 'E');
+	    else if (code && !strcmp (code, "sP"))
+	      operand = d_template_args_1 (di);
 	    else
 	      operand = d_expression_1 (di);
 
@@ -4289,6 +4302,30 @@ d_pack_length (const struct demangle_component *dc)
   return count;
 }
 
+/* Returns the number of template args in DC, expanding any pack expansions
+   found there.  */
+
+static int
+d_args_length (struct d_print_info *dpi, const struct demangle_component *dc)
+{
+  int count = 0;
+  for (; dc && dc->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST;
+       dc = d_right (dc))
+    {
+      struct demangle_component *elt = d_left (dc);
+      if (elt == NULL)
+	break;
+      if (elt->type == DEMANGLE_COMPONENT_PACK_EXPANSION)
+	{
+	  struct demangle_component *a = d_find_pack (dpi, d_left (elt));
+	  count += d_pack_length (a);
+	}
+      else
+	++count;
+    }
+  return count;
+}
+
 /* DC is a component of a mangled expression.  Print it, wrapped in parens
    if needed.  */
 
@@ -5125,6 +5162,21 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 	      }
 	  }
 
+	/* For sizeof..., just print the pack length.  */
+	if (code && !strcmp (code, "sZ"))
+	  {
+	    struct demangle_component *a = d_find_pack (dpi, operand);
+	    int len = d_pack_length (a);
+	    d_append_num (dpi, len);
+	    return;
+	  }
+	else if (code && !strcmp (code, "sP"))
+	  {
+	    int len = d_args_length (dpi, operand);
+	    d_append_num (dpi, len);
+	    return;
+	  }
+
 	if (op->type != DEMANGLE_COMPONENT_CAST)
 	  d_print_expr_op (dpi, options, op);
 	else
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index 1d95952..92ad01f 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4536,6 +4536,12 @@ void baz<int>(A<sizeof (foo((int)(), (floatcomplex )00000000_00000000))>*)
 --format=gnu-v3
 _Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv
 X<sizeof ((P(((F)())())).array)>::Type foo<F>()
+
+_Z1fIJidEEv1AIXsZT_EE
+void f<int, double>(A<2>)
+
+_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_
+void A::f<int, int, int, int, int, int>(int (&) [6], int, int, int, int)
 #
 # Tests a use-after-free problem PR70481
 
-------------- next part --------------
commit 4a8f978dceb66e3c87b5a73e0daa29422d3bed92
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jul 13 18:00:48 2016 -0400

    	PR c++/71711 - mangle C++1z fold-expressions.
    
    	* operators.def: Add *_FOLD_EXPR.
    	* cp-tree.h (FOLD_EXPR_P): Parenthesize.
    	* mangle.c (write_expression): Handle fold-expressions.
    	* pt.c (tsubst_unary_left_fold, tsubst_binary_left_fold)
    	(tsubst_unary_right_fold, tsubst_binary_right_fold): Handle
    	partial instantiation.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 74b8c7c..7e84036 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3334,11 +3334,11 @@ extern void decl_shadowed_for_var_insert (tree, tree);
   TREE_CHECK2 (NODE, BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR)
 
 /* True if NODE is UNARY_FOLD_EXPR or a BINARY_FOLD_EXPR */
-#define FOLD_EXPR_P(NODE) \
-  TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR \
-    || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR \
-    || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR \
-    || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR
+#define FOLD_EXPR_P(NODE)				\
+  (TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR		\
+   || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR		\
+   || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR		\
+   || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR)
 
 /* True when NODE is a fold over a compound assignment operator. */
 #define FOLD_EXPR_MODIFY_P(NODE) \
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 8205da9..d5b26d6 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3145,6 +3145,29 @@ write_expression (tree expr)
 			 "cannot be mangled");
 		  continue;
 		}
+	      else if (FOLD_EXPR_P (expr))
+		{
+		  /* The first 'operand' of a fold-expression is the operator
+		     that it folds over.  */
+		  if (i == 0)
+		    {
+		      int fcode = TREE_INT_CST_LOW (operand);
+		      write_string (operator_name_info[fcode].mangled_name);
+		      continue;
+		    }
+		  else if (code == BINARY_LEFT_FOLD_EXPR)
+		    {
+		      /* The order of operands of the binary left and right
+			 folds is the same, but we want to mangle them in
+			 lexical order, i.e. non-pack first.  */
+		      if (i == 1)
+			operand = FOLD_EXPR_INIT (expr);
+		      else
+			operand = FOLD_EXPR_PACK (expr);
+		    }
+		  if (PACK_EXPANSION_P (operand))
+		    operand = PACK_EXPANSION_PATTERN (operand);
+		}
 	      write_expression (operand);
 	    }
 	}
diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def
index aa657fa..5b4f1b0 100644
--- a/gcc/cp/operators.def
+++ b/gcc/cp/operators.def
@@ -155,3 +155,7 @@ DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", -1)
 
 /* Variadic templates extension. */
 DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1)
+DEF_SIMPLE_OPERATOR ("... +", UNARY_LEFT_FOLD_EXPR, "fl", 2)
+DEF_SIMPLE_OPERATOR ("+ ...", UNARY_RIGHT_FOLD_EXPR, "fr", 2)
+DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_LEFT_FOLD_EXPR, "fL", 3)
+DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_RIGHT_FOLD_EXPR, "fR", 3)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 73b53e2..de70fb2 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -10791,6 +10791,12 @@ tsubst_unary_left_fold (tree t, tree args, tsubst_flags_t complain,
   tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl);
   if (pack == error_mark_node)
     return error_mark_node;
+  if (PACK_EXPANSION_P (pack))
+    {
+      tree r = copy_node (t);
+      FOLD_EXPR_PACK (r) = pack;
+      return r;
+    }
   if (TREE_VEC_LENGTH (pack) == 0)
     return expand_empty_fold (t, complain);
   else
@@ -10813,6 +10819,14 @@ tsubst_binary_left_fold (tree t, tree args, tsubst_flags_t complain,
   if (init == error_mark_node)
     return error_mark_node;
 
+  if (PACK_EXPANSION_P (pack))
+    {
+      tree r = copy_node (t);
+      FOLD_EXPR_PACK (r) = pack;
+      FOLD_EXPR_INIT (r) = init;
+      return r;
+    }
+
   tree vec = make_tree_vec (TREE_VEC_LENGTH (pack) + 1);
   TREE_VEC_ELT (vec, 0) = init;
   for (int i = 0; i < TREE_VEC_LENGTH (pack); ++i)
@@ -10854,6 +10868,12 @@ tsubst_unary_right_fold (tree t, tree args, tsubst_flags_t complain,
   tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl);
   if (pack == error_mark_node)
     return error_mark_node;
+  if (PACK_EXPANSION_P (pack))
+    {
+      tree r = copy_node (t);
+      FOLD_EXPR_PACK (r) = pack;
+      return r;
+    }
   if (TREE_VEC_LENGTH (pack) == 0)
     return expand_empty_fold (t, complain);
   else
@@ -10876,6 +10896,14 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain,
   if (init == error_mark_node)
     return error_mark_node;
 
+  if (PACK_EXPANSION_P (pack))
+    {
+      tree r = copy_node (t);
+      FOLD_EXPR_PACK (r) = pack;
+      FOLD_EXPR_INIT (r) = init;
+      return r;
+    }
+
   int n = TREE_VEC_LENGTH (pack);
   tree vec = make_tree_vec (n + 1);
   for (int i = 0; i < n; ++i)
diff --git a/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C b/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C
new file mode 100644
index 0000000..1a8f16c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C
@@ -0,0 +1,20 @@
+// PR c++/71711
+// { dg-options -std=c++1z }
+
+template < int > struct A {};
+template < int ... N > void unary_left (A < (... + N) >);
+template < int ... N > void unary_right (A < (N + ...) >);
+template < int ... N > void binary_left (A < (42 + ... + N) >);
+template < int ... N > void binary_right (A < (N + ... + 42) >);
+
+void bar ()  
+{
+  // { dg-final { scan-assembler "_Z10unary_leftIJLi1ELi2ELi3EEEv1AIXflplT_EE" } }
+  unary_left < 1, 2, 3 > ({});
+  // { dg-final { scan-assembler "_Z11unary_rightIJLi1ELi2ELi3EEEv1AIXfrplT_EE" } }
+  unary_right < 1, 2, 3 > ({});
+  // { dg-final { scan-assembler "_Z11binary_leftIJLi1ELi2ELi3EEEv1AIXfLplLi42ET_EE" } }
+  binary_left < 1, 2, 3 > ({});
+  // { dg-final { scan-assembler "_Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRplT_Li42EEE" } }
+  binary_right < 1, 2, 3 > ({});
+}
-------------- next part --------------
commit bb9c173eedbc3bce2ba4101114a1d36d7fd09ce6
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jul 13 13:08:47 2016 -0400

    	Update -fabi-version default to 11.
    
    	* c-opts.c (c_common_post_options): Update -fabi-version default to 11.

diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index d945825..c11e7e7 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -887,15 +887,15 @@ c_common_post_options (const char **pfilename)
     }
   else if (flag_abi_compat_version == -1)
     {
-      /* Generate compatibility aliases for ABI v8 (5.1) by default. */
+      /* Generate compatibility aliases for ABI v10 (6.1) by default. */
       flag_abi_compat_version
-	= (flag_abi_version == 0 ? 8 : 0);
+	= (flag_abi_version == 0 ? 10 : 0);
     }
 
   /* Change flag_abi_version to be the actual current ABI level for the
      benefit of c_cpp_builtins.  */
   if (flag_abi_version == 0)
-    flag_abi_version = 10;
+    flag_abi_version = 11;
 
   if (cxx_dialect >= cxx11)
     {
diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C
index 6a695b9..5bc2277 100644
--- a/gcc/testsuite/g++.dg/abi/macro0.C
+++ b/gcc/testsuite/g++.dg/abi/macro0.C
@@ -1,6 +1,6 @@
 // This testcase will need to be kept in sync with c_common_post_options.
 // { dg-options "-fabi-version=0" }
 
-#if __GXX_ABI_VERSION != 1010
+#if __GXX_ABI_VERSION != 1011
 #error "Incorrect value of __GXX_ABI_VERSION"
 #endif


More information about the Gcc-patches mailing list