I'm updating -Wabi to allow for warnings about changes between a
previous ABI version and the currently selected one, and rather than
adjust all the warnings for -fabi-version=1 I'd like to tear it out. It
has now been 10 years since GCC 3.4.
Any thoughts?
commit a1a98ba5d18a57832ea1f3df1cc1f5f9eeb621a1
Author: Jason Merrill <ja...@redhat.com>
Date: Mon Jun 9 16:41:07 2014 -0400
gcc/c-family/
* c.opt (fabi-compat-version): New.
* c-opts.c (c_common_handle_option): Disallow -fabi-compat-version=1.
(c_common_post_options): Set flag_abi_compat_version.
* c-common.h (abi_version_crosses): New.
gcc/cp/
* call.c (convert_arg_to_ellipsis): Use abi_version_crosses.
* mangle.c (write_type, write_expression): Likewise.
(write_template_arg): Likewise.
(finish_mangling_internal): Adjust -Wabi warning.
(mangle_decl): Make alias based on flag_abi_compat_version.
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 4307507..8ff66a6 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -465,6 +465,15 @@ c_common_handle_option (size_t scode, const char *arg, int value,
}
break;
+ case OPT_fabi_compat_version_:
+ if (value == 1)
+ {
+ /* -fabi-version=1 support was removed after GCC 4.9. */
+ warning (0, "%qs is no longer supported", option->opt_text);
+ flag_abi_compat_version = 2;
+ }
+ break;
+
case OPT_fcanonical_system_headers:
cpp_opts->canonical_system_headers = value;
break;
@@ -919,6 +928,10 @@ c_common_post_options (const char **pfilename)
if (flag_declone_ctor_dtor == -1)
flag_declone_ctor_dtor = optimize_size;
+ /* Check compatibility with ABI version 2 (3.4-4.9) by default. */
+ if (flag_abi_compat_version == -1)
+ flag_abi_compat_version = (flag_abi_version == 0 ? 2 : 0);
+
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..de5d555 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -845,6 +845,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..158984e 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6508,12 +6508,14 @@ 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);
+ if (abi_version_crosses (6)
+ && (complain & tf_warning))
+ warning_at (loc, OPT_Wabi, "scoped enum %qT stopped promoting to "
+ "an integral type in -fabi-version=6", arg_type);
+ if (!abi_version_at_least (6))
+ arg = cp_convert (ENUM_UNDERLYING_TYPE (arg_type), arg, complain);
}
arg = cp_perform_integral_promotions (arg, complain);
}
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 86319c6..8ed06f2 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -2012,10 +2012,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,7 +2029,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)
+ if (abi_version_crosses (5)
&& DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type))
{
tree expr = DECLTYPE_TYPE_EXPR (type);
@@ -2053,8 +2052,11 @@ write_type (tree type)
if (etype && !type_uses_auto (etype))
{
G.need_abi_warning = 1;
- write_type (etype);
- return;
+ if (!abi_version_at_least (5))
+ {
+ write_type (etype);
+ return;
+ }
}
}
@@ -2621,7 +2623,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 +2855,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)
+ if (abi_version_crosses (6)
&& (code == CONST_CAST_EXPR
|| code == STATIC_CAST_EXPR))
{
- name = operator_name_info[CAST_EXPR].mangled_name;
G.need_abi_warning = 1;
+ if (!abi_version_at_least (6))
+ name = operator_name_info[CAST_EXPR].mangled_name;
}
if (name == NULL)
@@ -2929,7 +2932,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 +3067,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 +3080,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 +3102,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');
}
@@ -3289,9 +3290,16 @@ static void
finish_mangling_internal (const bool warn)
{
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);
+ {
+ int v1, v2;
+ if (abi_version_at_least (flag_abi_compat_version))
+ v1 = flag_abi_compat_version, v2 = flag_abi_version;
+ else
+ v1 = flag_abi_version, v2 = flag_abi_compat_version;
+ warning (OPT_Wabi, "the mangled name of %qD changes between "
+ "-fabi-version=%d and -fabi-version=%d",
+ G.entity, v1, v2);
+ }
/* Clear all the substitutions. */
vec_safe_truncate (G.substitutions, 0);
@@ -3439,12 +3447,17 @@ mangle_decl (const tree decl)
#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;
+ if (flag_abi_compat_version != 0
+ && IDENTIFIER_GLOBAL_VALUE (id2))
+ return;
+
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);
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum13.C b/gcc/testsuite/g++.dg/cpp0x/enum13.C
index 5e4a532..e399bb5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum13.C
@@ -15,7 +15,5 @@ void foo(int x, ...) {
}
int main() {
- foo(0, A::X); // { dg-warning "will not promote" }
+ foo(0, A::X); // { dg-warning "promot" }
}
-
-// { dg-prune-output "note" }