* c-common.c (flag_abi_version): New variable.
* c-common.h (flag_abi_version): Declare it.
* c-opts.c (missing_arg): Add -fabi-version.
(c_common_decode_option): Process -fabi-version.
* doc/invoke.texi (-fabi-version): Document it.
(-Wabi): Add information about bit-fields in unions.
* cp/class.c (layout_virtual_bases): Do not round the size of the
type to a multiple of the alignment before laying out virtual bases.
(layout_class_type): Correct handling of bit-fields that are wider
than their type inside unions. Round the size of the type to a
even number of bytes when computing the size without virtual
bases.
* cp/cp-tree.h (abi_version_at_least): New macro.
* g++.dg/abi/bitfield6.C: New test.
* g++.dg/abi/bitfield7.C: New test.
* g++.dg/abi/bitfield8.C: New test.
* g++.dg/abi/vbase11.C: New test.
From-SVN: r57432
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * c-common.c (flag_abi_version): New variable.
+ * c-common.h (flag_abi_version): Declare it.
+ * c-opts.c (missing_arg): Add -fabi-version.
+ (c_common_decode_option): Process -fabi-version.
+ * doc/invoke.texi (-fabi-version): Document it.
+ (-Wabi): Add information about bit-fields in unions.
+
2002-09-22 Jason Thorpe <thorpej@wasabisystems.com>
* config/mips/netbsd.h (SUBTARGET_ASM_SPEC): Always pass -KPIC
int flag_enforce_eh_specs = 1;
+/* The version of the C++ ABI in use. The following values are
+ allowed:
+
+ 0: The version of the ABI believed most conformant with the
+ C++ ABI specification. This ABI may change as bugs are
+ discovered and fixed. Therefore, 0 will not necessarily
+ indicate the same ABI in different versions of G++.
+
+ 1: The version of the ABI first used in G++ 3.2.
+
+ Additional positive integers will be assigned as new versions of
+ the ABI become the default version of the ABI. */
+
+int flag_abi_version = 1;
+
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
extern int flag_enforce_eh_specs;
+/* The version of the C++ ABI in use. The following values are
+ allowed:
+
+ -1: The version of the ABI believed most conformant with the
+ C++ ABI specification. This ABI may change as bugs are
+ discovered and fixed. Therefore, -1 will not necessarily
+ indicate the same ABI in different versions of G++.
+
+ 0: The version of the ABI first used in G++ 3.2.
+
+ Additional positive integers will be assigned as new versions of
+ the ABI become the default version of the ABI. */
+
+extern int flag_abi_version;
+
/* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */
OPT("Wwrite-strings", CL_ALL, OPT_Wwrite_strings) \
OPT("ansi", CL_ALL, OPT_ansi) \
OPT("d", CL_ALL | CL_JOINED, OPT_d) \
+ OPT("fabi-version=", CL_CXX | CL_JOINED, OPT_fabi_version) \
OPT("faccess-control", CL_CXX, OPT_faccess_control) \
OPT("fall-virtual", CL_CXX, OPT_fall_virtual) \
OPT("falt-external-templates",CL_CXX, OPT_falt_external_templates) \
{
case OPT_Wformat_eq:
case OPT_d:
+ case OPT_fabi_version:
case OPT_fbuiltin_:
case OPT_fdump:
case OPT_fname_mangling:
warning ("switch \"%s\" is no longer supported", argv[0]);
break;
+ case OPT_fabi_version:
+ flag_abi_version = read_integral_parameter (arg, argv[0], 1);
+ break;
+
case OPT_faccess_control:
flag_access_control = on;
break;
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * cp/class.c (layout_virtual_bases): Do not round the size of the
+ type to a multiple of the alignment before laying out virtual bases.
+ (layout_class_type): Correct handling of bit-fields that are wider
+ than their type inside unions. Round the size of the type to a
+ even number of bytes when computing the size without virtual
+ bases.
+ * cp/cp-tree.h (abi_version_at_least): New macro.
+
2002-09-21 Kazu Hirata <kazu@cs.umass.edu>
* ChangeLog: Follow spelling conventions.
#endif
/* DSIZE is the size of the class without the virtual bases. */
- dsize = TYPE_SIZE (t);
+ if (abi_version_at_least(2))
+ dsize = CLASSTYPE_SIZE (t);
+ else
+ dsize = TYPE_SIZE (t);
/* Make every class have alignment of at least one. */
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
field. We have to back up by one to find the largest
type that fits. */
integer_type = integer_types[itk - 1];
- padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
- TYPE_SIZE (integer_type));
+
+ if (abi_version_at_least (2) && TREE_CODE (t) == UNION_TYPE)
+ /* In a union, the padding field must have the full width
+ of the bit-field; all fields start at offset zero. */
+ padding = DECL_SIZE (field);
+ else
+ {
+ if (warn_abi && TREE_CODE (t) == UNION_TYPE)
+ warning ("size assigned to `%T' may not be "
+ "ABI-compliant and may change in a future "
+ "version of GCC",
+ t);
+ padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+ TYPE_SIZE (integer_type));
+ }
DECL_SIZE (field) = TYPE_SIZE (integer_type);
DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
DECL_USER_ALIGN (field) = TYPE_USER_ALIGN (integer_type);
padding = build_decl (FIELD_DECL, NULL_TREE, char_type_node);
place_field (rli, padding);
- }
-
+ }
+ else if (abi_version_at_least (2)
+ && !integer_zerop (rli->bitpos))
+ /* Make sure that we are on a byte boundary so that the size of
+ the class without virtual bases will always be a round number
+ of bytes. */
+ rli->bitpos = round_up (rli->bitpos, BITS_PER_UNIT);
+
/* Let the back-end lay out the type. Note that at this point we
have only included non-virtual base-classes; we will lay out the
virtual base classes later. So, the TYPE_SIZE/TYPE_ALIGN after
#endif
+/* Returns TRUE if generated code should match ABI version N or
+ greater is in use. */
+
+#define abi_version_at_least(N) \
+ (flag_abi_version == 0 || flag_abi_version >= (N))
+
\f
/* Language-dependent contents of an identifier. */
@item C++ Language Options
@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@gccoptlist{
--fno-access-control -fcheck-new -fconserve-space @gol
--fno-const-strings -fdollars-in-identifiers @gol
+-fabi-version=@var{n} -fno-access-control -fcheck-new @gol
+-fconserve-space -fno-const-strings -fdollars-in-identifiers @gol
-fno-elide-constructors @gol
-fno-enforce-eh-specs -fexternal-templates @gol
-falt-external-templates @gol
Here is a list of options that are @emph{only} for compiling C++ programs:
@table @gcctabopt
+
+@item -fabi-version=@var{n}
+@opindex fabi-version
+Use version @var{n} of the C++ ABI. Version 1 is the version of the C++
+ABI that first appeared in G++ 3.2. Version 0 will always be the
+version that conforms most closely to the C++ ABI specification.
+Therefore, the ABI obtained using version 0 will change as ABI bugs are
+fixed.
+
@item -fno-access-control
@opindex fno-access-control
Turn off all access checking. This switch is mainly useful for working
alignment (ignoring virtual base classes); that will cause G++ and other
compilers to layout @code{C} identically.
+@item
+Incorrect handling of bit-fields with declared widths greater than that
+of their underlying types, when the bit-fields appear in a union. For
+example:
+
+@smallexample
+union U @{ int i : 4096; @};
+@end smallexample
+
+@noindent
+Assuming that an @code{int} does not have 4096 bits, G++ will make the
+union too small by the number of bits in an @code{int}.
+
@end itemize
@item -Wctor-dtor-privacy @r{(C++ only)}
+2002-09-23 Mark Mitchell <mark@codesourcery.com>
+
+ * g++.dg/abi/bitfield6.C: New test.
+ * g++.dg/abi/bitfield7.C: New test.
+ * g++.dg/abi/bitfield8.C: New test.
+ * g++.dg/abi/vbase11.C: New test.
+
2002-09-22 John David Anglin <dave@hiauly1.hia.nrc.ca>
* gcc.dg/20020219-1.c: Add "-mdisable-indexing" option for target
--- /dev/null
+// { dg-do run }
+// { dg-options "-w -fabi-version=0" }
+
+#include <limits>
+
+union U {
+ int i: 4096;
+};
+
+int main () {
+ if (sizeof (U) * std::numeric_limits<unsigned char>::digits != 4096)
+ return 1;
+}
+
--- /dev/null
+// { dg-do compile }
+// { dg-options "-Wabi" }
+
+union U { // { dg-warning "ABI" }
+ int i: 4096; // { dg-warning "exceeds" }
+};
+
--- /dev/null
+// { dg-do run { target i?86-*-* } }
+// { dg-options "-fabi-version=0" }
+
+struct A {
+ virtual void f() {}
+ int f1 : 1;
+};
+
+struct B : public A {
+ int f2 : 31;
+ int f3 : 4;
+ int f4 : 3;
+};
+
+int main ()
+{
+ if (sizeof (B) != 16)
+ return 1;
+}
+
--- /dev/null
+// { dg-do run { target i?86-*-* } }
+// { dg-options "-fabi-version=0" }
+
+struct A { virtual void f(); char c1; };
+struct B { B(); char c2; };
+struct C : public A, public virtual B { };
+
+int main () {
+ if (sizeof (C) != 8)
+ return 1;
+}
+