diff mbox

C++ PATCH to add -Wabi=n

Message ID 539A116E.1020006@redhat.com
State New
Headers show

Commit Message

Jason Merrill June 12, 2014, 8:45 p.m. UTC
Now that -fabi-version defaults to 0, -Wabi isn't very useful.  But for 
people interested in compatibility with earlier versions, this patch 
allows you to say -Wabi=2 to get any relevant warnings.  This patch also 
adjusts the compatibility aliases to default to backward compatibility 
with -fabi-version=2.

Tested x86_64-pc-linux-gnu, applying to trunk.

Comments

Rainer Orth June 16, 2014, 11:24 a.m. UTC | #1
Jason Merrill <jason@redhat.com> writes:

> Now that -fabi-version defaults to 0, -Wabi isn't very useful.  But for
> people interested in compatibility with earlier versions, this patch allows
> you to say -Wabi=2 to get any relevant warnings.  This patch also adjusts
> the compatibility aliases to default to backward compatibility with
> -fabi-version=2.

This patch

2014-06-12  Jason Merrill  <jason@redhat.com>

	* toplev.c (process_options): Reject -fabi-version=1.

which was committed as part of the above, but not posted AFAICS,
introduced a testsuite failure on i386-pc-solaris2.1? and
x86_64-unknown-linux-gnu with -m32:

FAIL: g++.dg/abi/layout4.C -std=gnu++98 (test for excess errors)
WARNING: g++.dg/abi/layout4.C -std=gnu++98 compilation failed to produce executable
FAIL: g++.dg/abi/layout4.C -std=gnu++11 (test for excess errors)
WARNING: g++.dg/abi/layout4.C -std=gnu++11 compilation failed to produce executable
FAIL: g++.dg/abi/layout4.C -std=gnu++1y (test for excess errors)
WARNING: g++.dg/abi/layout4.C -std=gnu++1y compilation failed to produce executable

Excess errors:
/vol/gcc/src/hg/trunk/local/gcc/testsuite/g++.dg/abi/layout4.C:1:0: error: '-fabi-version=1' is no longer supported

	Rainer
Jason Merrill June 16, 2014, 11:54 a.m. UTC | #2
On 06/16/2014 01:24 PM, Rainer Orth wrote:
> This patch
>
> 2014-06-12  Jason Merrill  <jason@redhat.com>
>
> 	* toplev.c (process_options): Reject -fabi-version=1.
>
> which was committed as part of the above, but not posted AFAICS,

https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01054.html

> introduced a testsuite failure on i386-pc-solaris2.1? and
> x86_64-unknown-linux-gnu with -m32:
>
> FAIL: g++.dg/abi/layout4.C -std=gnu++98 (test for excess errors)

Fixed, thanks.

Jason
diff mbox

Patch

commit 969f9f501a5a8b7a9498464bf3bef59e685b3895
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jun 9 16:41:07 2014 -0400

    	Support -Wabi warning about backward compatibility.
    gcc/c-family/
    	* c.opt (Wabi=, fabi-compat-version): New.
    	* c-opts.c (c_common_handle_option): Handle -Wabi=.
    	(c_common_post_options): Handle flag_abi_compat_version default.
    	Disallow -fabi-compat-version=1.
    	* c-common.h (abi_version_crosses): New.
    gcc/cp/
    	* call.c (convert_arg_to_ellipsis): Use abi_version_crosses.
    	* cvt.c (type_promotes_to): Likewise.
    	* mangle.c (write_type, write_expression): Likewise.
    	(write_name, write_template_arg): Likewise.
    	(mangle_decl): Make alias based on flag_abi_compat_version.
    	Emit -Wabi warning here.
    	(finish_mangling_internal): Not here.  Drop warn parm.
    	(finish_mangling_get_identifier, finish_mangling): Adjust.
    	(mangle_type_string, mangle_special_for_type): Adjust.
    	(mangle_ctor_vtbl_for_type, mangle_thunk): Adjust.
    	(mangle_guard_variable, mangle_tls_init_fn): Adjust.
    	(mangle_tls_wrapper_fn, mangle_ref_init_variable): Adjust.

diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 83d5dee..6bf4051 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -619,6 +619,13 @@  extern const char *constant_string_class_name;
 /* C++ language option variables.  */
 
 
+/* Return TRUE if one of {flag_abi_version,flag_abi_compat_version} is
+   less than N and the other is at least N, for use by -Wabi.  */
+#define abi_version_crosses(N)			\
+  (abi_version_at_least(N)			\
+   != (flag_abi_compat_version == 0		\
+       || flag_abi_compat_version >= (N)))
+
 /* Nonzero means generate separate instantiation control files and
    juggle them at link time.  */
 
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 29e9a35..fbbc80e 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -456,6 +456,16 @@  c_common_handle_option (size_t scode, const char *arg, int value,
       handle_OPT_d (arg);
       break;
 
+    case OPT_Wabi_:
+      warn_abi = true;
+      if (value == 1)
+	{
+	  warning (0, "%<-Wabi=1%> is not supported, using =2");
+	  value = 2;
+	}
+      flag_abi_compat_version = value;
+      break;
+
     case OPT_fcanonical_system_headers:
       cpp_opts->canonical_system_headers = value;
       break;
@@ -910,6 +920,22 @@  c_common_post_options (const char **pfilename)
   if (flag_declone_ctor_dtor == -1)
     flag_declone_ctor_dtor = optimize_size;
 
+  if (flag_abi_compat_version == 1)
+    {
+      warning (0, "%<-fabi-compat-version=1%> is not supported, using =2");
+      flag_abi_compat_version = 2;
+    }
+  else if (flag_abi_compat_version == -1)
+    {
+      /* Generate compatibility aliases for ABI v2 (3.4-4.9) by default. */
+      flag_abi_compat_version = (flag_abi_version == 0 ? 2 : 0);
+
+      /* But don't warn about backward compatibility unless explicitly
+	 requested with -Wabi=n.  */
+      if (flag_abi_version == 0)
+	warn_abi = false;
+    }
+
   if (cxx_dialect >= cxx11)
     {
       /* If we're allowing C++0x constructs, don't warn about C++98
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 76e67d7..d2e047f 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -256,6 +256,10 @@  Wabi
 C ObjC C++ ObjC++ LTO Var(warn_abi) Warning
 Warn about things that will change when compiling with an ABI-compliant compiler
 
+Wabi=
+C ObjC C++ ObjC++ LTO Joined RejectNegative UInteger Warning
+Warn about things that change between the current -fabi-version and the specified version
+
 Wabi-tag
 C++ ObjC++ Var(warn_abi_tag) Warning
 Warn if a subobject has an abi_tag attribute that the complete object type does not have
@@ -845,6 +849,10 @@  d
 C ObjC C++ ObjC++ Joined
 ; Documented in common.opt.  FIXME - what about -dI, -dD, -dN and -dD?
 
+fabi-compat-version=
+C++ ObjC++ Joined RejectNegative UInteger Var(flag_abi_compat_version) Init(-1)
+The version of the C++ ABI used for -Wabi warnings and link compatibility aliases
+
 faccess-control
 C++ ObjC++ Var(flag_access_control) Init(1)
 Enforce class member access control semantics
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index ac14ce2..44e92fc 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6508,14 +6508,22 @@  convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
     arg = null_pointer_node;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (arg_type))
     {
-      if (SCOPED_ENUM_P (arg_type) && !abi_version_at_least (6))
+      if (SCOPED_ENUM_P (arg_type))
 	{
-	  if (complain & tf_warning)
-	    warning_at (loc, OPT_Wabi, "scoped enum %qT will not promote to an "
-			"integral type in a future version of GCC", arg_type);
-	  arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain);
+	  tree prom = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg,
+				  complain);
+	  prom = cp_perform_integral_promotions (prom, complain);
+	  if (abi_version_crosses (6)
+	      && TYPE_MODE (TREE_TYPE (prom)) != TYPE_MODE (arg_type)
+	      && (complain & tf_warning))
+	    warning_at (loc, OPT_Wabi, "scoped enum %qT passed through ... as "
+			"%qT before -fabi-version=6, %qT after", arg_type,
+			TREE_TYPE (prom), ENUM_UNDERLYING_TYPE (arg_type));
+	  if (!abi_version_at_least (6))
+	    arg = prom;
 	}
-      arg = cp_perform_integral_promotions (arg, complain);
+      else
+	arg = cp_perform_integral_promotions (arg, complain);
     }
 
   arg = require_complete_type_sfinae (arg, complain);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 2a82723..1dec9cc 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1701,13 +1701,9 @@  type_promotes_to (tree type)
   if (TREE_CODE (type) == BOOLEAN_TYPE)
     type = integer_type_node;
 
-  /* Scoped enums don't promote, but pretend they do for backward ABI bug
-     compatibility wrt varargs.  */
-  else if (SCOPED_ENUM_P (type) && abi_version_at_least (6))
-    ;
-
   /* Normally convert enums to int, but convert wide enums to something
-     wider.  */
+     wider.  Scoped enums don't promote, but pretend they do for backward
+     ABI bug compatibility wrt varargs.  */
   else if (TREE_CODE (type) == ENUMERAL_TYPE
 	   || type == char16_type_node
 	   || type == char32_type_node
@@ -1716,16 +1712,26 @@  type_promotes_to (tree type)
       int precision = MAX (TYPE_PRECISION (type),
 			   TYPE_PRECISION (integer_type_node));
       tree totype = c_common_type_for_size (precision, 0);
+      tree prom = type;
+      if (TREE_CODE (prom) == ENUMERAL_TYPE)
+	prom = ENUM_UNDERLYING_TYPE (prom);
+      if (TYPE_UNSIGNED (prom)
+	  && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
+	prom = c_common_type_for_size (precision, 1);
+      else
+	prom = totype;
       if (SCOPED_ENUM_P (type))
-	warning (OPT_Wabi, "scoped enum %qT will not promote to an integral "
-		 "type in a future version of GCC", type);
-      if (TREE_CODE (type) == ENUMERAL_TYPE)
-	type = ENUM_UNDERLYING_TYPE (type);
-      if (TYPE_UNSIGNED (type)
-	  && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype))
-	type = c_common_type_for_size (precision, 1);
+	{
+	  if (abi_version_crosses (6)
+	      && TYPE_MODE (prom) != TYPE_MODE (type))
+	    warning (OPT_Wabi, "scoped enum %qT passed through ... as "
+		     "%qT before -fabi-version=6, %qT after",
+		     type, prom, ENUM_UNDERLYING_TYPE (type));
+	  if (!abi_version_at_least (6))
+	    type = prom;
+	}
       else
-	type = totype;
+	type = prom;
     }
   else if (c_promoting_integer_type_p (type))
     {
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 86319c6..ac1c1da 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -225,7 +225,6 @@  static int local_class_index (tree);
 /* Control functions.  */
 
 static inline void start_mangling (const tree);
-static inline const char *finish_mangling (const bool);
 static tree mangle_special_for_type (const tree, const char *);
 
 /* Foreign language functions.  */
@@ -786,6 +785,11 @@  write_name (tree decl, const int ignore_local_scope)
 
   gcc_assert (context != NULL_TREE);
 
+  if (abi_version_crosses (7)
+      && ignore_local_scope
+      && TREE_CODE (context) == PARM_DECL)
+    G.need_abi_warning = 1;
+
   /* A decl in :: or ::std scope is treated specially.  The former is
      mangled using <unscoped-name> or <unscoped-template-name>, the
      latter with a special substitution.  Also, a name that is
@@ -1865,6 +1869,8 @@  write_type (tree type)
 	    write_function_type (t);
 	  else
 	    write_type (t);
+	  if (abi_version_crosses (8))
+	    G.need_abi_warning = 1;
 	}
       else
 	write_type (t);
@@ -1970,9 +1976,14 @@  write_type (tree type)
 		   a typedef or template argument can have function type
 		   with function-cv-quals (that use the same representation),
 		   but you can't have a pointer/reference to such a type.  */
-		if (abi_version_at_least (5)
-		    && TREE_CODE (target) == FUNCTION_TYPE)
-		  target = build_qualified_type (target, TYPE_UNQUALIFIED);
+		if (TREE_CODE (target) == FUNCTION_TYPE)
+		  {
+		    if (abi_version_crosses (5)
+			&& TYPE_QUALS (target) != TYPE_UNQUALIFIED)
+		      G.need_abi_warning = 1;
+		    if (abi_version_at_least (5))
+		      target = build_qualified_type (target, TYPE_UNQUALIFIED);
+		  }
 		write_type (target);
 	      }
 	      break;
@@ -2012,10 +2023,9 @@  write_type (tree type)
 		  write_char ('_');
 		}
 	      else
-		{
-		  G.need_abi_warning = 1;
-		  write_string ("U8__vector");
-		}
+		write_string ("U8__vector");
+	      if (abi_version_crosses (4))
+		G.need_abi_warning = 1;
 	      write_type (TREE_TYPE (type));
 	      break;
 
@@ -2030,8 +2040,7 @@  write_type (tree type)
 			  && !DECLTYPE_FOR_LAMBDA_PROXY (type));
 
 	      /* In ABI <5, we stripped decltype of a plain decl.  */
-	      if (!abi_version_at_least (5)
-		  && DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
+	      if (DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
 		{
 		  tree expr = DECLTYPE_TYPE_EXPR (type);
 		  tree etype = NULL_TREE;
@@ -2052,9 +2061,13 @@  write_type (tree type)
 
 		  if (etype && !type_uses_auto (etype))
 		    {
-		      G.need_abi_warning = 1;
-		      write_type (etype);
-		      return;
+		      if (abi_version_crosses (5))
+			G.need_abi_warning = 1;
+		      if (!abi_version_at_least (5))
+			{
+			  write_type (etype);
+			  return;
+			}
 		    }
 		}
 
@@ -2073,6 +2086,8 @@  write_type (tree type)
 	      write_string ("Dn");
 	      if (abi_version_at_least (7))
 		++is_builtin_type;
+	      if (abi_version_crosses (7))
+		G.need_abi_warning = 1;
 	      break;
 
 	    case TYPEOF_TYPE:
@@ -2621,7 +2636,7 @@  write_expression (tree expr)
 	      write_char ('L');
 	      write_unsigned_number (delta - 1);
 	    }
-	  else
+	  if (abi_version_crosses (5))
 	    G.need_abi_warning = true;
 	}
       write_char ('p');
@@ -2853,12 +2868,13 @@  write_expression (tree expr)
       name = operator_name_info[(int) code].mangled_name;
 
       /* We used to mangle const_cast and static_cast like a C cast.  */
-      if (!abi_version_at_least (6)
-	  && (code == CONST_CAST_EXPR
-	      || code == STATIC_CAST_EXPR))
+      if (code == CONST_CAST_EXPR
+	  || code == STATIC_CAST_EXPR)
 	{
-	  name = operator_name_info[CAST_EXPR].mangled_name;
-	  G.need_abi_warning = 1;
+	  if (abi_version_crosses (6))
+	    G.need_abi_warning = 1;
+	  if (!abi_version_at_least (6))
+	    name = operator_name_info[CAST_EXPR].mangled_name;
 	}
 
       if (name == NULL)
@@ -2929,7 +2945,7 @@  write_expression (tree expr)
 	case PREDECREMENT_EXPR:
 	  if (abi_version_at_least (6))
 	    write_char ('_');
-	  else
+	  if (abi_version_crosses (6))
 	    G.need_abi_warning = 1;
 	  /* Fall through.  */
 
@@ -3064,7 +3080,7 @@  write_template_arg (tree node)
     {
       if (abi_version_at_least (6))
 	node = BASELINK_FUNCTIONS (node);
-      else
+      if (abi_version_crosses (6))
 	/* We wrongly wrapped a class-scope function in X/E.  */
 	G.need_abi_warning = 1;
     }
@@ -3077,10 +3093,9 @@  write_template_arg (tree node)
       if (abi_version_at_least (6))
 	write_char ('J');
       else
-	{
-	  write_char ('I');
-	  G.need_abi_warning = 1;
-	}
+	write_char ('I');
+      if (abi_version_crosses (6))
+	G.need_abi_warning = 1;
       for (i = 0; i < length; ++i)
         write_template_arg (TREE_VEC_ELT (args, i));
       write_char ('E');
@@ -3100,12 +3115,11 @@  write_template_arg (tree node)
       /* Until ABI version 3, the underscore before the mangled name
 	 was incorrectly omitted.  */
       if (!abi_version_at_least (3))
-	{
-	  G.need_abi_warning = 1;
-	  write_char ('Z');
-	}
+	write_char ('Z');
       else
 	write_string ("_Z");
+      if (abi_version_crosses (3))
+	G.need_abi_warning = 1;
       write_encoding (node);
       write_char ('E');
     }
@@ -3286,13 +3300,8 @@  start_mangling (const tree entity)
    warning.  */
 
 static void
-finish_mangling_internal (const bool warn)
+finish_mangling_internal (void)
 {
-  if (warn_abi && warn && G.need_abi_warning)
-    warning (OPT_Wabi, "the mangled name of %qD will change in a future "
-	     "version of GCC",
-	     G.entity);
-
   /* Clear all the substitutions.  */
   vec_safe_truncate (G.substitutions, 0);
 
@@ -3304,18 +3313,18 @@  finish_mangling_internal (const bool warn)
 /* Like finish_mangling_internal, but return the mangled string.  */
 
 static inline const char *
-finish_mangling (const bool warn)
+finish_mangling (void)
 {
-  finish_mangling_internal (warn);
+  finish_mangling_internal ();
   return (const char *) obstack_finish (mangle_obstack);
 }
 
 /* Like finish_mangling_internal, but return an identifier.  */
 
 static tree
-finish_mangling_get_identifier (const bool warn)
+finish_mangling_get_identifier (void)
 {
-  finish_mangling_internal (warn);
+  finish_mangling_internal ();
   /* Don't obstack_finish here, and the next start_mangling will
      remove the identifier.  */
   return get_identifier ((const char *) obstack_base (mangle_obstack));
@@ -3373,7 +3382,7 @@  mangle_decl_string (const tree decl)
   else
     write_mangled_name (decl, true);
 
-  result = finish_mangling_get_identifier (/*warn=*/true);
+  result = finish_mangling_get_identifier ();
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_decl_string = '%s'\n\n",
 	     IDENTIFIER_POINTER (result));
@@ -3425,26 +3434,47 @@  mangle_decl (const tree decl)
       && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
     {
-#ifdef ASM_OUTPUT_DEF
       /* If the mangling will change in the future, emit an alias with the
 	 future mangled name for forward-compatibility.  */
       int save_ver;
-      tree id2, alias;
-#endif
+      tree id2;
 
       SET_IDENTIFIER_GLOBAL_VALUE (id, decl);
       if (IDENTIFIER_GLOBAL_VALUE (id) != decl)
-	inform (DECL_SOURCE_LOCATION (decl), "-fabi-version=6 (or =0) "
+	inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) "
 		"avoids this error with a change in mangling");
 
-#ifdef ASM_OUTPUT_DEF
       save_ver = flag_abi_version;
-      flag_abi_version = 0;
+      flag_abi_version = flag_abi_compat_version;
       id2 = mangle_decl_string (decl);
       id2 = targetm.mangle_decl_assembler_name (decl, id2);
       flag_abi_version = save_ver;
 
-      alias = make_alias_for (decl, id2);
+      if (id2 == id)
+	return;
+
+      if (warn_abi)
+	{
+	  if (flag_abi_compat_version != 0
+	      && abi_version_at_least (flag_abi_compat_version))
+	    warning (OPT_Wabi, "the mangled name of %q+D changed between "
+		     "-fabi-version=%d (%D) and -fabi-version=%d (%D)",
+		     G.entity, flag_abi_compat_version, id2,
+		     flag_abi_version, id);
+	  else
+	    warning (OPT_Wabi, "the mangled name of %q+D changes between "
+		     "-fabi-version=%d (%D) and -fabi-version=%d (%D)",
+		     G.entity, flag_abi_version, id,
+		     flag_abi_compat_version, id2);
+	}
+
+#ifdef ASM_OUTPUT_DEF
+      if (flag_abi_compat_version != 0
+	  && IDENTIFIER_GLOBAL_VALUE (id2))
+	return;
+
+      tree alias = make_alias_for (decl, id2);
+      SET_IDENTIFIER_GLOBAL_VALUE (id2, alias);
       DECL_IGNORED_P (alias) = 1;
       TREE_PUBLIC (alias) = TREE_PUBLIC (decl);
       DECL_VISIBILITY (alias) = DECL_VISIBILITY (decl);
@@ -3471,7 +3501,7 @@  mangle_type_string (const tree type)
 
   start_mangling (type);
   write_type (type);
-  result = finish_mangling (/*warn=*/false);
+  result = finish_mangling ();
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_type_string = '%s'\n\n", result);
   return result;
@@ -3496,7 +3526,7 @@  mangle_special_for_type (const tree type, const char *code)
 
   /* Add the type.  */
   write_type (type);
-  result = finish_mangling_get_identifier (/*warn=*/false);
+  result = finish_mangling_get_identifier ();
 
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_special_for_type = %s\n\n",
@@ -3567,7 +3597,7 @@  mangle_ctor_vtbl_for_type (const tree type, const tree binfo)
   write_char ('_');
   write_type (BINFO_TYPE (binfo));
 
-  result = finish_mangling_get_identifier (/*warn=*/false);
+  result = finish_mangling_get_identifier ();
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_ctor_vtbl_for_type = %s\n\n",
 	     IDENTIFIER_POINTER (result));
@@ -3646,7 +3676,7 @@  mangle_thunk (tree fn_decl, const int this_adjusting, tree fixed_offset,
   /* Scoped name.  */
   write_encoding (fn_decl);
 
-  result = finish_mangling_get_identifier (/*warn=*/false);
+  result = finish_mangling_get_identifier ();
   if (DEBUG_MANGLE)
     fprintf (stderr, "mangle_thunk = %s\n\n", IDENTIFIER_POINTER (result));
   return result;
@@ -3739,7 +3769,7 @@  mangle_guard_variable (const tree variable)
   start_mangling (variable);
   write_string ("_ZGV");
   write_guarded_var_name (variable);
-  return finish_mangling_get_identifier (/*warn=*/false);
+  return finish_mangling_get_identifier ();
 }
 
 /* Return an identifier for the name of a thread_local initialization
@@ -3751,7 +3781,7 @@  mangle_tls_init_fn (const tree variable)
   start_mangling (variable);
   write_string ("_ZTH");
   write_guarded_var_name (variable);
-  return finish_mangling_get_identifier (/*warn=*/false);
+  return finish_mangling_get_identifier ();
 }
 
 /* Return an identifier for the name of a thread_local wrapper
@@ -3765,7 +3795,7 @@  mangle_tls_wrapper_fn (const tree variable)
   start_mangling (variable);
   write_string (TLS_WRAPPER_PREFIX);
   write_guarded_var_name (variable);
-  return finish_mangling_get_identifier (/*warn=*/false);
+  return finish_mangling_get_identifier ();
 }
 
 /* Return true iff FN is a thread_local wrapper function.  */
@@ -3795,7 +3825,7 @@  mangle_ref_init_variable (const tree variable)
   /* Avoid name clashes with aggregate initialization of multiple
      references at once.  */
   write_unsigned_number (temp_count++);
-  return finish_mangling_get_identifier (/*warn=*/false);
+  return finish_mangling_get_identifier ();
 }
 
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4efd3e2..3c02341 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -195,7 +195,7 @@  in the following sections.
 -fvtv-counts -fvtv-debug @gol
 -fvisibility-ms-compat @gol
 -fext-numeric-literals @gol
--Wabi  -Wconversion-null  -Wctor-dtor-privacy @gol
+-Wabi=@var{n}  -Wconversion-null  -Wctor-dtor-privacy @gol
 -Wdelete-non-virtual-dtor -Wliteral-suffix -Wnarrowing @gol
 -Wnoexcept -Wnon-virtual-dtor  -Wreorder @gol
 -Weffc++  -Wstrict-null-sentinel @gol
@@ -2023,7 +2023,7 @@  Here is a list of options that are @emph{only} for compiling C++ programs:
 
 @item -fabi-version=@var{n}
 @opindex fabi-version
-Use version @var{n} of the C++ ABI@.  The default is version 2.
+Use version @var{n} of the C++ ABI@.  The default is version 0.
 
 Version 0 refers to the version conforming most closely to
 the C++ ABI specification.  Therefore, the ABI obtained using version 0
@@ -2031,7 +2031,8 @@  will change in different versions of G++ as ABI bugs are fixed.
 
 Version 1 is the version of the C++ ABI that first appeared in G++ 3.2.  
 
-Version 2 is the version of the C++ ABI that first appeared in G++ 3.4.  
+Version 2 is the version of the C++ ABI that first appeared in G++
+3.4, and was the default through G++ 4.9.
 
 Version 3 corrects an error in mangling a constant address as a
 template argument.
@@ -2049,8 +2050,27 @@  behavior of C++11 scoped enums and the mangling of template argument
 packs, const/static_cast, prefix ++ and --, and a class scope function
 used as a template argument.
 
+Version 7, which first appeared in G++ 4.8, that treats nullptr_t as a
+builtin type and corrects the mangling of lambdas in default argument
+scope.
+
+Version 8, which first appeared in G++ 4.9, corrects the substitution
+behavior of function types with function-cv-qualifiers.
+
 See also @option{-Wabi}.
 
+@item -fabi-compat-version=@var{n}
+@opindex fabi-compat-version
+Starting with GCC 4.5, on targets that support strong aliases, G++
+works around mangling changes by creating an alias with the correct
+mangled name when defining a symbol with an incorrect mangled name.
+This switch specifies which ABI version to use for the alias.
+
+With @option{-fabi-version=0} (the default), this defaults to 2.  If
+another ABI version is explicitly selected, this defaults to 0.
+
+The compatibility version is also set by @option{-Wabi=@var{n}}.
+
 @item -fno-access-control
 @opindex fno-access-control
 Turn off all access checking.  This switch is mainly useful for working
@@ -2445,8 +2465,15 @@  have meanings only for C++ programs:
 @item -Wabi @r{(C, Objective-C, C++ and Objective-C++ only)}
 @opindex Wabi
 @opindex Wno-abi
-Warn when G++ generates code that is probably not compatible with the
-vendor-neutral C++ ABI@.  Although an effort has been made to warn about
+When an explicit @option{-fabi-version=@var{n}} option is used, causes
+G++ to warn when it generates code that is probably not compatible with the
+vendor-neutral C++ ABI@.  Since G++ now defaults to
+@option{-fabi-version=0}, @option{-Wabi} has no effect unless either
+an older ABI version is selected (with @option{-fabi-version=@var{n}})
+or an older compatibility version is selected (with
+@option{-Wabi=@var{n}} or @option{-fabi-compat-version=@var{n}}).
+
+Although an effort has been made to warn about
 all such cases, there are probably some cases that are not warned about,
 even though G++ is generating incompatible code.  There may also be
 cases where warnings are emitted even though the code that is generated
@@ -2456,12 +2483,19 @@  You should rewrite your code to avoid these warnings if you are
 concerned about the fact that code generated by G++ may not be binary
 compatible with code generated by other compilers.
 
-The known incompatibilities in @option{-fabi-version=2} (the default) include:
+@option{-Wabi} can also be used with an explicit version number to
+warn about compatibility with a particular @option{-fabi-version}
+level, e.g. @option{-Wabi=2} to warn about changes relative to
+@option{-fabi-version=2}.  Specifying a version number also sets
+@option{-fabi-compat-version=@var{n}}.
+
+The known incompatibilities in @option{-fabi-version=2} (which was the
+default from GCC 3.4 to 4.9) include:
 
 @itemize @bullet
 
 @item
-A template with a non-type template parameter of reference type is
+A template with a non-type template parameter of reference type was
 mangled incorrectly:
 @smallexample
 extern int N;
@@ -2469,14 +2503,45 @@  template <int &> struct S @{@};
 void n (S<N>) @{2@}
 @end smallexample
 
-This is fixed in @option{-fabi-version=3}.
+This was fixed in @option{-fabi-version=3}.
 
 @item
-SIMD vector types declared using @code{__attribute ((vector_size))} are
+SIMD vector types declared using @code{__attribute ((vector_size))} were
 mangled in a non-standard way that does not allow for overloading of
 functions taking vectors of different sizes.
 
-The mangling is changed in @option{-fabi-version=4}.
+The mangling was changed in @option{-fabi-version=4}.
+
+@item
+@code{__attribute ((const))} and @code{noreturn} were mangled as type
+qualifiers, and @code{decltype} of a plain declaration was folded away.
+
+These mangling issues were fixed in @option{-fabi-version=5}.
+
+@item
+Scoped enumerators passed as arguments to a variadic function are
+promoted like unscoped enumerators, causing @samp{va_arg} to complain.
+On most targets this does not actually affect the parameter passing
+ABI, as there is no way to pass an argument smaller than @samp{int}.
+
+Also, the ABI changed the mangling of template argument packs,
+@code{const_cast}, @code{static_cast}, prefix increment/decrement, and
+a class scope function used as a template argument.
+
+These issues were corrected in @option{-fabi-version=6}.
+
+@item
+Lambdas in default argument scope were mangled incorrectly, and the
+ABI changed the mangling of nullptr_t.
+
+These issues were corrected in @option{-fabi-version=7}.
+
+@item
+When mangling a function type with function-cv-qualifiers, the
+un-qualified function type was incorrectly treated as a substitution
+candidate.
+
+This was fixed in @option{-fabi-version=8}.
 @end itemize
 
 It also warns about psABI-related changes.  The known psABI changes at this
diff --git a/gcc/testsuite/g++.dg/abi/mangle19-1.C b/gcc/testsuite/g++.dg/abi/mangle19-1.C
index 1463d03..a888173 100644
--- a/gcc/testsuite/g++.dg/abi/mangle19-1.C
+++ b/gcc/testsuite/g++.dg/abi/mangle19-1.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile }
-// { dg-options "-fabi-version=2 -Wno-abi" }
+// { dg-options "-fabi-version=2 -Wabi" }
 
 // Copyright (C) 2003 Free Software Foundation, Inc.
 // Contributed by Nathan Sidwell 15 Dec 2003 <nathan@codesourcery.com>
@@ -9,5 +9,5 @@ 
 
 extern int N;
 template <int &> struct S {};
-void n (S<N>) {}
+void n (S<N>) {}		// { dg-warning "mangle" }
 // { dg-final { scan-assembler "\n_?_Z1n1SILZ1NEE\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle3-2.C b/gcc/testsuite/g++.dg/abi/mangle3-2.C
index ac85fb0..538c5cb 100644
--- a/gcc/testsuite/g++.dg/abi/mangle3-2.C
+++ b/gcc/testsuite/g++.dg/abi/mangle3-2.C
@@ -1,12 +1,12 @@ 
 // Test mangling of type casts
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=5" }
 // { dg-do compile }
 
 template<int i> class A {};
 template<bool b> class B {};
 
 template<int i> void f(A<i> &, B<bool(i)> &) {}
-template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {}
+template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} // { dg-warning "mangle" }
 
 int main()
 {
diff --git a/gcc/testsuite/g++.dg/abi/mangle3.C b/gcc/testsuite/g++.dg/abi/mangle3.C
index 5f44f76..42f8dea 100644
--- a/gcc/testsuite/g++.dg/abi/mangle3.C
+++ b/gcc/testsuite/g++.dg/abi/mangle3.C
@@ -1,12 +1,12 @@ 
 // Test mangling of type casts
-// { dg-options "-fabi-version=2" }
+// { dg-options "-fabi-version=2 -Wabi" }
 // { dg-do compile }
 
 template<int i> class A {};
 template<bool b> class B {};
 
 template<int i> void f(A<i> &, B<bool(i)> &) {}
-template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {}
+template<int i> void g(A<i> &, B<static_cast<bool>(i)> &) {} // { dg-warning "mangle" }
 
 int main()
 {
diff --git a/gcc/testsuite/g++.dg/abi/mangle45.C b/gcc/testsuite/g++.dg/abi/mangle45.C
index 5e202a2..bdedb0a 100644
--- a/gcc/testsuite/g++.dg/abi/mangle45.C
+++ b/gcc/testsuite/g++.dg/abi/mangle45.C
@@ -1,26 +1,26 @@ 
 // Testcase for mangling of parameters used other than in a trailing return type
 // { dg-do compile { target c++11 } }
-// { dg-options "-fabi-version=5" }
+// { dg-options "-fabi-version=5 -Wabi=4" }
 
-template<class T> void f(T p, decltype(p)) { }                // L = 1
-template<class T> void g(T p, decltype(p) (*)()) { }          // L = 1
+template<class T> void f(T p, decltype(p)) { }	     // L = 1 { dg-warning "mangle" }
+template<class T> void g(T p, decltype(p) (*)()) { } // L = 1 { dg-warning "mangle" }
 // G++ incorrectly rejects these currently.
 // template<class T> void h(T p, auto (*)()->decltype(p));    // L = 1
 // template<class T> void i(T p, auto (*)(T q)->decltype(q)); // L = 0
 // template<class T> void j(T p, auto (*)(decltype(p))->T);   // L = 2
-template<class T> void k(T p, int (*(*)(T* p))[sizeof(p)]) {} // L = 1
+template<class T> void k(T p, int (*(*)(T* p))[sizeof(p)]) {} // L = 1 { dg-warning "mangle" }
 
 int garg();
 int (*karg (int*))[sizeof(int)];
 int main()
 {
-  // { dg-final { scan-assembler  "_Z1fIiEvT_DtfL0p_E" } }
+  // { dg-final { scan-assembler  "\n_?_Z1fIiEvT_DtfL0p_E\[: \t\n\]" } }
   f (1,0);
-  // { dg-final { scan-assembler  "_Z1gIiEvT_PFDtfL0p_EvE" } }
+  // { dg-final { scan-assembler  "\n_?_Z1gIiEvT_PFDtfL0p_EvE\[: \t\n\]" } }
   g (1,garg);
   // h (1,0);
   // i (1,0);
   // j (1,0);
-  // { dg-final { scan-assembler  "_Z1kIiEvT_PFPAszfL0p__iPS0_E" } }
+  // { dg-final { scan-assembler  "\n_?_Z1kIiEvT_PFPAszfL0p__iPS0_E\[: \t\n\]" } }
   k (1,karg);
 }
diff --git a/gcc/testsuite/g++.dg/abi/mangle49.C b/gcc/testsuite/g++.dg/abi/mangle49.C
index 3795c55..fae013a 100644
--- a/gcc/testsuite/g++.dg/abi/mangle49.C
+++ b/gcc/testsuite/g++.dg/abi/mangle49.C
@@ -1,10 +1,10 @@ 
 // PR c++/49932
 // { dg-do compile { target c++11 } }
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=2" }
 
 template < typename T >
 auto
-f1( T x ) // ICE on here
+f1( T x )			// { dg-warning "mangle" }
   -> typename decltype( x )::type {}
 
 template < typename T >
@@ -19,5 +19,5 @@  void g()
   f2( S() );
 }
 
-// { dg-final { scan-assembler "_Z2f1I1SENDtfp_E4typeET_" } }
-// { dg-final { scan-assembler "_Z2f2I1SENDTcvT__EE4typeES1_" } }
+// { dg-final { scan-assembler "\n_?_Z2f1I1SENDtfp_E4typeET_\[: \t\n\]" } }
+// { dg-final { scan-assembler "\n_?_Z2f2I1SENDTcvT__EE4typeES1_\[: \t\n\]" } }
diff --git a/gcc/testsuite/g++.dg/abi/mangle52.C b/gcc/testsuite/g++.dg/abi/mangle52.C
index 2c46341..0b9a72f 100644
--- a/gcc/testsuite/g++.dg/abi/mangle52.C
+++ b/gcc/testsuite/g++.dg/abi/mangle52.C
@@ -1,13 +1,13 @@ 
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=2" }
 
 template <unsigned int> struct helper {};
-// { dg-final { scan-assembler "_Z6check1IiEvP6helperIXszscT_Li1EEE" } }
-template <class T> void check1( helper<sizeof(static_cast<T>(1))> * ) { }
-// { dg-final { scan-assembler "_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE" } }
-template <class T, T* p> void check2( helper<sizeof(const_cast<T*>(p))> * ) { }
-// { dg-final { scan-assembler "_Z6check3IiEvP6helperIXszrcPT_Li0EEE" } }
+// { dg-final { scan-assembler "\n_?_Z6check1IiEvP6helperIXszscT_Li1EEE\[: \t\n\]" } }
+template <class T> void check1( helper<sizeof(static_cast<T>(1))> * ) { } // { dg-warning "mangle" }
+// { dg-final { scan-assembler "\n_?_Z6check2IiXadL_Z1iEEEvP6helperIXszccPT_T0_EE\[: \t\n\]" } }
+template <class T, T* p> void check2( helper<sizeof(const_cast<T*>(p))> * ) { } // { dg-warning "mangle" }
+// { dg-final { scan-assembler "\n_?_Z6check3IiEvP6helperIXszrcPT_Li0EEE\[: \t\n\]" } }
 template <class T> void check3( helper<sizeof(reinterpret_cast<T*>(0))> * ) { }
-// { dg-final { scan-assembler "_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE" } }
+// { dg-final { scan-assembler "\n_?_Z6check4I1AXadL_Z1aEEEvP6helperIXszdcPT_T0_EE\[: \t\n\]" } }
 template <class T, T* p> void check4( helper<sizeof(dynamic_cast<T*>(p))> * ) { }
 
 struct A{} a;
diff --git a/gcc/testsuite/g++.dg/abi/mangle54.C b/gcc/testsuite/g++.dg/abi/mangle54.C
index 926275c..ba1d3bc 100644
--- a/gcc/testsuite/g++.dg/abi/mangle54.C
+++ b/gcc/testsuite/g++.dg/abi/mangle54.C
@@ -1,15 +1,15 @@ 
 // { dg-do compile { target c++11 } }
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=2" }
 
 int i;
 // { dg-final { scan-assembler "_Z2f1IiEDTppfp_ET_" } }
 template <class T> auto f1 (T t) -> decltype(t++) { return i; }
 // { dg-final { scan-assembler "_Z2f2IiEDTpp_fp_ET_" } }
-template <class T> auto f2 (T t) -> decltype(++t) { return i; }
+template <class T> auto f2 (T t) -> decltype(++t) { return i; } // { dg-warning "mangle" }
 // { dg-final { scan-assembler "_Z2f3IiEDTmmfp_ET_" } }
 template <class T> auto f3 (T t) -> decltype(t--) { return i; }
 // { dg-final { scan-assembler "_Z2f4IiEDTmm_fp_ET_" } }
-template <class T> auto f4 (T t) -> decltype(--t) { return i; }
+template <class T> auto f4 (T t) -> decltype(--t) { return i; } // { dg-warning "mangle" }
 
 int main()
 {
diff --git a/gcc/testsuite/g++.dg/abi/mangle57.C b/gcc/testsuite/g++.dg/abi/mangle57.C
index cd59cb8..46cf377 100644
--- a/gcc/testsuite/g++.dg/abi/mangle57.C
+++ b/gcc/testsuite/g++.dg/abi/mangle57.C
@@ -1,13 +1,13 @@ 
 // { dg-do compile { target c++11 } }
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=2" }
 
 template<typename T> int cmp1(T a, T b);
 int cmp2(char a, char b);
 template<typename T, int (*cmp)(T, T)> struct A { };
-// { dg-final { scan-assembler "_Z1fIcEvR1AIT_X4cmp1EE" } }
-template <typename T> void f (A<T,cmp1> &);
-// { dg-final { scan-assembler "_Z1fIcEvR1AIT_L_Z4cmp2ccEE" } }
-template <typename T> void f (A<T,cmp2> &);
+// { dg-final { scan-assembler "\n_?_Z1fIcEvR1AIT_X4cmp1EE\[: \t\n\]" } }
+template <typename T> void f (A<T,cmp1> &) {}
+// { dg-final { scan-assembler "\n_?_Z1fIcEvR1AIT_L_Z4cmp2ccEE\[: \t\n\]" } }
+template <typename T> void f (A<T,cmp2> &) {} // { dg-warning "mangle" }
 void g()
 {
   A<char,cmp1> a;
diff --git a/gcc/testsuite/g++.dg/abi/mangle58.C b/gcc/testsuite/g++.dg/abi/mangle58.C
index abcb3ca..f9aadc2 100644
--- a/gcc/testsuite/g++.dg/abi/mangle58.C
+++ b/gcc/testsuite/g++.dg/abi/mangle58.C
@@ -1,5 +1,5 @@ 
 // { dg-do compile { target c++11 } }
-// { dg-options "-fabi-version=0" }
+// { dg-options "-fabi-version=0 -Wabi=2" }
 
 template<typename T, int (*cmp)(T, T)> struct A { };
 struct B {
@@ -10,9 +10,9 @@  struct B {
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_XsrS_4cmp1EE" } }
   template <typename T> static void g (A<T,B::cmp1> &);
   // { dg-final { scan-assembler "_ZN1B1fIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void f (A<T,cmp2> &);
+  template <typename T> static void f (A<T,cmp2> &); // { dg-warning "mangle" }
   // { dg-final { scan-assembler "_ZN1B1gIcEEvR1AIT_L_ZNS_4cmp2EccEE" } }
-  template <typename T> static void g (A<T,B::cmp2> &);
+  template <typename T> static void g (A<T,B::cmp2> &); // { dg-warning "mangle" }
 };
 
 void g()
diff --git a/gcc/testsuite/g++.dg/abi/mangle62.C b/gcc/testsuite/g++.dg/abi/mangle62.C
index 6dbfd78..db541ca 100644
--- a/gcc/testsuite/g++.dg/abi/mangle62.C
+++ b/gcc/testsuite/g++.dg/abi/mangle62.C
@@ -2,10 +2,10 @@ 
 // as a substitution candidate for a function type with function-cv-quals.
 // Test for the conformant behavior.
 
-// { dg-options -fabi-version=0 }
+// { dg-options "-fabi-version=0 -Wabi=7" }
 
 template <class T, class U> struct A { };
-// { dg-final { scan-assembler "_Z1fP1AIKFvvEFvvEE" } }
-void f (A<void()const, void()> *){}
-// { dg-final { scan-assembler "_Z1gP1AIFvvEKFvvEE" } }
-void g (A<void(), void()const> *){}
+// { dg-final { scan-assembler "\n_?_Z1fP1AIKFvvEFvvEE\[: \t\n\]" } }
+void f (A<void()const, void()> *){} // { dg-warning "mangled name" }
+// { dg-final { scan-assembler "\n_?_Z1gP1AIFvvEKFvvEE\[: \t\n\]" } }
+void g (A<void(), void()const> *){} // { dg-warning "mangled name" }
diff --git a/gcc/testsuite/g++.dg/abi/mangle62a.C b/gcc/testsuite/g++.dg/abi/mangle62a.C
index fca1cb6..a48efd0 100644
--- a/gcc/testsuite/g++.dg/abi/mangle62a.C
+++ b/gcc/testsuite/g++.dg/abi/mangle62a.C
@@ -2,10 +2,10 @@ 
 // as a substitution candidate for a function type with function-cv-quals.
 // Test for that for backward compatibility.
 
-// { dg-options -fabi-version=7 }
+// { dg-options "-fabi-version=7 -Wabi" }
 
 template <class T, class U> struct A { };
-// { dg-final { scan-assembler "_Z1fP1AIKFvvES0_E" } }
-void f (A<void()const, void()> *){}
-// { dg-final { scan-assembler "_Z1gP1AIFvvEKS0_E" } }
-void g (A<void(), void()const> *){}
+// { dg-final { scan-assembler "\n_?_Z1fP1AIKFvvES0_E\[: \t\n\]" } }
+void f (A<void()const, void()> *){} // { dg-warning "mangle" }
+// { dg-final { scan-assembler "\n_?_Z1gP1AIFvvEKS0_E\[: \t\n\]" } }
+void g (A<void(), void()const> *){} // { dg-warning "mangle" }
diff --git a/gcc/testsuite/g++.dg/abi/scoped1.C b/gcc/testsuite/g++.dg/abi/scoped1.C
new file mode 100644
index 0000000..7589ed4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/scoped1.C
@@ -0,0 +1,23 @@ 
+// { dg-do run { target c++11 } }
+// { dg-options "-fabi-version=0 -Wabi=2" }
+
+enum class A: short { a1, a2, a3 };
+void f(int i, ...)
+{
+  __builtin_va_list ap;
+  __builtin_va_start (ap, i);
+  if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a1) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a2) __builtin_abort(); // { dg-warning "passed" }
+  if (__builtin_va_arg (ap, A) != A::a3) __builtin_abort(); // { dg-warning "passed" }
+}
+
+int main()
+{
+  f(9, A::a1, A::a2, A::a3, A::a1, A::a2, A::a3, A::a1, A::a2, A::a3);	// { dg-warning "passed" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum13.C b/gcc/testsuite/g++.dg/cpp0x/enum13.C
index 5e4a532..8335fad 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum13.C
@@ -10,12 +10,10 @@  enum struct A : short { X };
 void foo(int x, ...) {
    va_list vl;
    __builtin_va_start(vl, x);
-   enum A t = __builtin_va_arg(vl, enum A); // { dg-warning "promote" }
+   enum A t = __builtin_va_arg(vl, enum A); // { dg-warning "scoped|promote" }
    __builtin_va_end(vl);
 }
 
 int main() {
-   foo(0, A::X);		// { dg-warning "will not promote" }
+   foo(0, A::X);		// { dg-warning "scoped" }
 }
-
-// { dg-prune-output "note" }