===================================================================
@@ -18414,8 +18414,9 @@ documented @code{__attribute__ ((scalar_
of the scalar fields to big-endian.
@item @code{#pragma scalar_storage_order little-endian} sets the storage order
of the scalar fields to little-endian.
-@item @code{#pragma scalar_storage_order default} goes back to the default
-endianness.
+@item @code{#pragma scalar_storage_order default} goes back to the endianness
+that was in effect when compilation started (see also command-line option
+@option{-fsso-struct=@var{endianness}} @pxref{C Dialect Options}).
@end enumerate
@node Weak Pragmas
===================================================================
@@ -169,10 +169,11 @@ in the following sections.
-aux-info @var{filename} -fallow-parameterless-variadic-functions @gol
-fno-asm -fno-builtin -fno-builtin-@var{function} @gol
-fhosted -ffreestanding -fopenacc -fopenmp -fopenmp-simd @gol
--fms-extensions -fplan9-extensions -trigraphs -traditional -traditional-cpp @gol
+-fms-extensions -fplan9-extensions -fsso-struct=@var{endianness}
-fallow-single-precision -fcond-mismatch -flax-vector-conversions @gol
-fsigned-bitfields -fsigned-char @gol
--funsigned-bitfields -funsigned-char}
+-funsigned-bitfields -funsigned-char @gol
+-trigraphs -traditional -traditional-cpp}
@item C++ Language Options
@xref{C++ Dialect Options,,Options Controlling C++ Dialect}.
@@ -2066,6 +2067,17 @@ These options control whether a bit-fiel
declaration does not use either @code{signed} or @code{unsigned}. By
default, such a bit-field is signed, because this is consistent: the
basic integer types such as @code{int} are signed types.
+
+@item -fsso-struct=@var{endianness}
+@opindex fsso-struct
+Set the default scalar storage order of structures, unions and classes to
+the specified endianness. The accepted values are @samp{big-endian} and
+@samp{little-endian}. If the option is not passed, the compiler uses the
+native endianness of the target.
+
+@strong{Warning:} the @option{-fsso-struct} switch causes GCC to generate
+code that is not binary compatible with code generated without it if the
+specified endianness is not the native endianness of the target.
@end table
@node C++ Dialect Options
===================================================================
@@ -1402,6 +1402,19 @@ Enable C++14 sized deallocation support
fsquangle
C++ ObjC++ Ignore Warn(switch %qs is no longer supported)
+fsso-struct=
+C C++ Joined RejectNegative Enum(sso_struct) Var(default_sso) Init(SSO_NATIVE)
+-fsso-struct=[big-endian|little-endian] Set the default scalar storage order
+
+Enum
+Name(sso_struct) Type(enum scalar_storage_order_kind) UnknownError(unrecognized scalar storage order value %qs)
+
+EnumValue
+Enum(sso_struct) String(big-endian) Value(SSO_BIG_ENDIAN)
+
+EnumValue
+Enum(sso_struct) String(little-endian) Value(SSO_LITTLE_ENDIAN)
+
fstats
C++ ObjC++ Var(flag_detailed_statistics)
Display statistics accumulated during compilation
===================================================================
@@ -400,19 +400,12 @@ handle_pragma_weak (cpp_reader * ARG_UNU
}
}
-enum scalar_storage_order_kind
-{
- SSO_DEFAULT,
- SSO_BIG_ENDIAN,
- SSO_LITTLE_ENDIAN
-};
-
-static enum scalar_storage_order_kind global_sso_kind = SSO_DEFAULT;
+static enum scalar_storage_order_kind global_sso;
void
maybe_apply_pragma_scalar_storage_order (tree type)
{
- if (global_sso_kind == SSO_DEFAULT)
+ if (global_sso == SSO_NATIVE)
return;
gcc_assert (RECORD_OR_UNION_TYPE_P (type));
@@ -420,9 +413,9 @@ maybe_apply_pragma_scalar_storage_order
if (lookup_attribute ("scalar_storage_order", TYPE_ATTRIBUTES (type)))
return;
- if (global_sso_kind == SSO_BIG_ENDIAN)
+ if (global_sso == SSO_BIG_ENDIAN)
TYPE_REVERSE_STORAGE_ORDER (type) = !BYTES_BIG_ENDIAN;
- else if (global_sso_kind == SSO_LITTLE_ENDIAN)
+ else if (global_sso == SSO_LITTLE_ENDIAN)
TYPE_REVERSE_STORAGE_ORDER (type) = BYTES_BIG_ENDIAN;
else
gcc_unreachable ();
@@ -443,11 +436,11 @@ handle_pragma_scalar_storage_order (cpp_
GCC_BAD ("missing [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
kind_string = IDENTIFIER_POINTER (x);
if (strcmp (kind_string, "default") == 0)
- global_sso_kind = SSO_DEFAULT;
+ global_sso = default_sso;
else if (strcmp (kind_string, "big") == 0)
- global_sso_kind = SSO_BIG_ENDIAN;
+ global_sso = SSO_BIG_ENDIAN;
else if (strcmp (kind_string, "little") == 0)
- global_sso_kind = SSO_LITTLE_ENDIAN;
+ global_sso = SSO_LITTLE_ENDIAN;
else
GCC_BAD ("expected [big-endian|little-endian|default] after %<#pragma scalar_storage_order%>");
}
@@ -1509,8 +1502,6 @@ init_pragma (void)
c_register_pragma (0, "pack", handle_pragma_pack);
#endif
c_register_pragma (0, "weak", handle_pragma_weak);
- c_register_pragma (0, "scalar_storage_order",
- handle_pragma_scalar_storage_order);
c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
@@ -1533,6 +1524,10 @@ init_pragma (void)
REGISTER_TARGET_PRAGMAS ();
#endif
+ global_sso = default_sso;
+ c_register_pragma (0, "scalar_storage_order",
+ handle_pragma_scalar_storage_order);
+
/* Allow plugins to register their own pragmas. */
invoke_plugin_callbacks (PLUGIN_PRAGMAS, NULL);
}
===================================================================
@@ -0,0 +1,44 @@
+/* Test support of scalar_storage_order pragma */
+
+/* { dg-do run } */
+/* { dg-options "-fsso-struct=big-endian" } */
+
+struct S1
+{
+ int i;
+};
+
+#pragma scalar_storage_order little-endian
+
+struct S2
+{
+ int i;
+};
+
+#pragma scalar_storage_order default
+
+struct S3
+{
+ int i;
+};
+
+struct S1 my_s1 = { 0x12345678 };
+struct S2 my_s2 = { 0x12345678 };
+struct S3 my_s3 = { 0x12345678 };
+
+unsigned char big_endian_pattern[4] = { 0x12, 0x34, 0x56, 0x78 };
+unsigned char little_endian_pattern[4] = { 0x78, 0x56, 0x34, 0x12 };
+
+int main (void)
+{
+ if (__builtin_memcmp (&my_s1, &big_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ if (__builtin_memcmp (&my_s2, &little_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ if (__builtin_memcmp (&my_s3, &big_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ return 0;
+}
===================================================================
@@ -0,0 +1,44 @@
+/* Test support of scalar_storage_order pragma */
+
+/* { dg-do run } */
+/* { dg-options "-fsso-struct=little-endian" } */
+
+struct S1
+{
+ int i;
+};
+
+#pragma scalar_storage_order big-endian
+
+struct S2
+{
+ int i;
+};
+
+#pragma scalar_storage_order default
+
+struct S3
+{
+ int i;
+};
+
+struct S1 my_s1 = { 0x12345678 };
+struct S2 my_s2 = { 0x12345678 };
+struct S3 my_s3 = { 0x12345678 };
+
+unsigned char big_endian_pattern[4] = { 0x12, 0x34, 0x56, 0x78 };
+unsigned char little_endian_pattern[4] = { 0x78, 0x56, 0x34, 0x12 };
+
+int main (void)
+{
+ if (__builtin_memcmp (&my_s1, &little_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ if (__builtin_memcmp (&my_s2, &big_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ if (__builtin_memcmp (&my_s3, &little_endian_pattern, 4) != 0)
+ __builtin_abort ();
+
+ return 0;
+}
===================================================================
@@ -171,7 +171,6 @@ enum stack_check_type
/* Names for the different levels of -Wstrict-overflow=N. The numeric
values here correspond to N. */
-
enum warn_strict_overflow_code
{
/* Overflow warning that should be issued with -Wall: a questionable
@@ -201,6 +200,13 @@ enum fp_contract_mode {
FP_CONTRACT_FAST = 2
};
+/* Scalar storage order kind. */
+enum scalar_storage_order_kind {
+ SSO_NATIVE = 0,
+ SSO_BIG_ENDIAN,
+ SSO_LITTLE_ENDIAN
+};
+
/* Vectorizer cost-model. */
enum vect_cost_model {
VECT_COST_MODEL_UNLIMITED = 0,
@@ -209,7 +215,6 @@ enum vect_cost_model {
VECT_COST_MODEL_DEFAULT = 3
};
-
/* Different instrumentation modes. */
enum sanitize_code {
/* AddressSanitizer. */