aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/d/gdc.texi17
-rw-r--r--gcc/d/implement-d.texi5
-rw-r--r--gcc/d/lang.opt8
-rw-r--r--gcc/d/types.cc15
-rw-r--r--gcc/testsuite/gdc.dg/Wmismatched_enum.d4
5 files changed, 49 insertions, 0 deletions
diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi
index 24b6ee0..6f81967 100644
--- a/gcc/d/gdc.texi
+++ b/gcc/d/gdc.texi
@@ -699,6 +699,23 @@ Do not warn about usage of deprecated features and symbols with
@item -Werror
Turns all warnings into errors.
+@opindex Wextra
+@opindex Wno-extra
+@item -Wextra
+This enables some extra warning flags that are not enabled by
+@option{-Wall}.
+
+@gccoptlist{-Waddress
+-Wcast-result
+-Wmismatched-special-enum
+-Wunknown-pragmas}
+
+@opindex Wmismatched-special-enum
+@opindex Wno-mismatched-special-enum
+@item -Wmismatched-special-enum
+Warn when an enum the compiler recognizes as special is declared with a
+different size to the built-in type it is representing.
+
@opindex Wspeculative
@opindex Wno-speculative
@item -Wspeculative
diff --git a/gcc/d/implement-d.texi b/gcc/d/implement-d.texi
index 039e5fb..6f33bc1 100644
--- a/gcc/d/implement-d.texi
+++ b/gcc/d/implement-d.texi
@@ -2085,6 +2085,11 @@ for convenience: @code{c_complex_double}, @code{c_complex_float},
@code{c_complex_real}, @code{cpp_long}, @code{cpp_longlong},
@code{c_long_double}, @code{cpp_ulong}, @code{cpp_ulonglong}.
+It may cause undefined behavior at runtime if a special enum is declared with a
+base type that has a different size to the target C/C++ type it is
+representing. The GNU D compiler will catch such declarations and emit a
+warning when the @option{-Wmismatched-special-enum} option is seen on the
+command-line.
@c --------------------------------------------------------
diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt
index bb0a3dc..26ca92c 100644
--- a/gcc/d/lang.opt
+++ b/gcc/d/lang.opt
@@ -134,6 +134,14 @@ Werror
D
; Documented in common.opt
+Wextra
+D Warning
+; Documented in common.opt
+
+Wmismatched-special-enum
+D Warning Var(warn_mismatched_special_enum) LangEnabledBy(D, Wextra)
+Warn when a special enum is declared with the wrong base type.
+
Wpsabi
D
; Documented in C
diff --git a/gcc/d/types.cc b/gcc/d/types.cc
index beaf2a6..a4c05bf 100644
--- a/gcc/d/types.cc
+++ b/gcc/d/types.cc
@@ -1067,6 +1067,21 @@ public:
gcc_assert (underlying != NULL);
t->ctype = build_variant_type_copy (build_ctype (underlying));
+
+ /* When the size of the declared enum base type doesn't match the target
+ C type that this enum is being used as a placeholder for, we can't
+ use the generated underlying type as it'll conflict with all sizes
+ the front-end has computed during semantic. */
+ if (TYPE_SIZE (t->ctype) != TYPE_SIZE (basetype))
+ {
+ warning_at (make_location_t (t->sym->loc),
+ OPT_Wmismatched_special_enum,
+ "size of %qs (%wd) differ from its declared size (%wd)",
+ t->sym->ident->toChars (), int_size_in_bytes (t->ctype),
+ int_size_in_bytes (basetype));
+ t->ctype = basetype;
+ }
+
build_type_decl (t->ctype, t->sym);
}
else if (t->sym->ident == NULL
diff --git a/gcc/testsuite/gdc.dg/Wmismatched_enum.d b/gcc/testsuite/gdc.dg/Wmismatched_enum.d
new file mode 100644
index 0000000..54f4798
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/Wmismatched_enum.d
@@ -0,0 +1,4 @@
+// { dg-do compile }
+// { dg-options "-Wmismatched-special-enum" }
+
+enum __c_longlong : byte; // { dg-warning "differ from its declared size" }