aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2002-09-23 09:22:17 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2002-09-23 09:22:17 +0000
commit2d3e278d62b7568a5a4b775dc42c74f051cd1edb (patch)
tree1a0a4c88a7ec146d17c908d2c4246c6c718372b8
parentd4e81c8598c969b31734b38a2f1dfcf563725c5b (diff)
downloadgcc-2d3e278d62b7568a5a4b775dc42c74f051cd1edb.zip
gcc-2d3e278d62b7568a5a4b775dc42c74f051cd1edb.tar.gz
gcc-2d3e278d62b7568a5a4b775dc42c74f051cd1edb.tar.bz2
c-common.c (flag_abi_version): New variable.
* 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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-common.c15
-rw-r--r--gcc/c-common.h15
-rw-r--r--gcc/c-opts.c6
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/class.c32
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/doc/invoke.texi26
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield6.C14
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield7.C7
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield8.C20
-rw-r--r--gcc/testsuite/g++.dg/abi/vbase11.C12
13 files changed, 172 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e03260..fd6d5ad4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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
diff --git a/gcc/c-common.c b/gcc/c-common.c
index c85c23c..251a255 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -567,6 +567,21 @@ int flag_permissive;
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. */
diff --git a/gcc/c-common.h b/gcc/c-common.h
index f15dbf1..8cf6aa4 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -737,6 +737,21 @@ extern int flag_permissive;
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. */
diff --git a/gcc/c-opts.c b/gcc/c-opts.c
index ce4b910..4d9e3d2 100644
--- a/gcc/c-opts.c
+++ b/gcc/c-opts.c
@@ -188,6 +188,7 @@ static void sanitize_cpp_opts PARAMS ((void));
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) \
@@ -342,6 +343,7 @@ missing_arg (opt_index)
{
case OPT_Wformat_eq:
case OPT_d:
+ case OPT_fabi_version:
case OPT_fbuiltin_:
case OPT_fdump:
case OPT_fname_mangling:
@@ -1014,6 +1016,10 @@ c_common_decode_option (argc, argv)
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;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 634ccbb..a25c6aa 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 7f365e7..316bc63 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4574,7 +4574,10 @@ layout_virtual_bases (t, offsets)
#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);
@@ -4875,8 +4878,21 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
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);
@@ -4944,8 +4960,14 @@ layout_class_type (t, empty_p, vfuns_p, virtuals_p)
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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 077dec4..b3cee37 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -212,6 +212,12 @@ struct diagnostic_context;
#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))
+
/* Language-dependent contents of an identifier. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f1ddd5d..66aab29 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -174,8 +174,8 @@ in the following sections.
@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
@@ -1249,6 +1249,15 @@ language supported by GCC@.
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
@@ -1522,6 +1531,19 @@ explicitly padding @code{A} so that its size is a multiple of its
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)}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 83843fe..19d87b3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+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
diff --git a/gcc/testsuite/g++.dg/abi/bitfield6.C b/gcc/testsuite/g++.dg/abi/bitfield6.C
new file mode 100644
index 0000000..50f76ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/bitfield6.C
@@ -0,0 +1,14 @@
+// { 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;
+}
+
diff --git a/gcc/testsuite/g++.dg/abi/bitfield7.C b/gcc/testsuite/g++.dg/abi/bitfield7.C
new file mode 100644
index 0000000..9868cfc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/bitfield7.C
@@ -0,0 +1,7 @@
+// { dg-do compile }
+// { dg-options "-Wabi" }
+
+union U { // { dg-warning "ABI" }
+ int i: 4096; // { dg-warning "exceeds" }
+};
+
diff --git a/gcc/testsuite/g++.dg/abi/bitfield8.C b/gcc/testsuite/g++.dg/abi/bitfield8.C
new file mode 100644
index 0000000..8195fda
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/bitfield8.C
@@ -0,0 +1,20 @@
+// { 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;
+}
+
diff --git a/gcc/testsuite/g++.dg/abi/vbase11.C b/gcc/testsuite/g++.dg/abi/vbase11.C
new file mode 100644
index 0000000..3755773
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/vbase11.C
@@ -0,0 +1,12 @@
+// { 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;
+}
+