1 // Copyright 2005-2006 Alexander Nasonov.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 
6 // Status of some compilers:
7 //
8 // Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
9 // /Za (disable extentions) is totally broken.
10 // /Ze (enable extentions) promotes UIntEnum incorrectly to int.
11 // See http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx?feedbackid=22b0a6b7-120f-4ca0-9136-fa1b25b26efe
12 //
13 // Intel 9.0.028 for Windows has a similar problem:
14 // https://premier.intel.com/IssueDetail.aspx?IssueID=365073
15 //
16 // gcc 3.4.4 with -fshort-enums option on x86
17 // Dummy value is required, otherwise gcc promotes Enum1
18 // to unsigned int although USHRT_MAX <= INT_MAX.
19 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24063
20 //
21 // CC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-20 2004/03/19
22 // on SPARC V9 64-bit processor (-xarch=v9 flag)
23 // Dummy values are required for LongEnum3 and LongEnum4.
24 //
25 // CC: Sun C++ 5.7 Patch 117830-03 2005/07/21
26 // ICE in boost/type_traits/is_enum.hpp at line 67.
27 
28 
29 #include <climits>
30 
31 #include "promote_util.hpp"
32 #include <boost/detail/workaround.hpp>
33 
34 #ifdef BOOST_INTEL
35 //  remark #1418: external function definition with no prior declaration
36 #pragma warning(disable:1418)
37 #endif
38 
39 enum IntEnum1 { IntEnum1_min = -5      , IntEnum1_max = 5        };
40 enum IntEnum2 { IntEnum2_min = SHRT_MIN, IntEnum2_max = SHRT_MAX };
41 enum IntEnum3 { IntEnum3_min = INT_MIN , IntEnum3_max = INT_MAX  };
42 enum IntEnum4 { IntEnum4_value = INT_MAX };
43 enum IntEnum5 { IntEnum5_value = INT_MIN };
44 
test_promote_to_int()45 void test_promote_to_int()
46 {
47     test_cv<IntEnum1,int>();
48     test_cv<IntEnum2,int>();
49     test_cv<IntEnum3,int>();
50     test_cv<IntEnum4,int>();
51     test_cv<IntEnum5,int>();
52 }
53 
54 
55 #if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ == 4 && USHRT_MAX <= INT_MAX)
56 
57 enum Enum1 { Enum1_value = USHRT_MAX };
58 
59 #else
60 
61 // workaround for bug #24063 in gcc 3.4
62 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24063
63 namespace gcc_short_enums_workaround {
64 
65 enum short_enum { value = 1 };
66 
67 template<bool ShortEnumsIsOn>
68 struct select
69 {
70     // Adding negative dummy value doesn't change
71     // promoted type because USHRT_MAX <= INT_MAX.
72     enum type { dummy = -1, value = USHRT_MAX };
73 };
74 
75 template<>
76 struct select<false>
77 {
78     // No dummy value
79     enum type { value = USHRT_MAX };
80 };
81 
82 } // namespace gcc_short_enums_workaround
83 
84 typedef gcc_short_enums_workaround::select<
85     sizeof(gcc_short_enums_workaround::short_enum) != sizeof(int)
86   >::type Enum1;
87 
88 #endif
89 
test_promote_to_int_or_uint()90 void test_promote_to_int_or_uint()
91 {
92 #if USHRT_MAX <= INT_MAX
93     test_cv<Enum1, int>();
94 #else
95     test_cv<Enum1, unsigned int>();
96 #endif
97 }
98 
99 #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1500) ) || \
100     BOOST_WORKAROUND(BOOST_INTEL_WIN, BOOST_TESTED_AT(1000))
101 // Don't test UIntEnum on VC++ 8.0 and Intel for Windows 9.0,
102 // they are broken. More info is on top of this file.
103 #else
104 
105 enum UIntEnum { UIntEnum_max = UINT_MAX };
106 
test_promote_to_uint()107 void test_promote_to_uint()
108 {
109     test_cv< UIntEnum, unsigned int >();
110 }
111 
112 #endif
113 
114 // Enums can't be promoted to [unsigned] long if sizeof(int) == sizeof(long).
115 #if INT_MAX < LONG_MAX
116 
117 enum LongEnum1 { LongEnum1_min = -1      , LongEnum1_max  = UINT_MAX };
118 enum LongEnum2 { LongEnum2_min = LONG_MIN, LongEnum2_max  = LONG_MAX };
119 
120 enum LongEnum3
121 {
122    LongEnum3_value = LONG_MAX
123 #if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x530
124  , LongEnum3_dummy = -1
125 #endif
126 };
127 
128 enum LongEnum4
129 {
130     LongEnum4_value = LONG_MIN
131 #if defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x530
132   , LongEnum4_dummy = 1
133 #endif
134 };
135 
test_promote_to_long()136 void test_promote_to_long()
137 {
138     test_cv< LongEnum1, long >();
139     test_cv< LongEnum2, long >();
140     test_cv< LongEnum3, long >();
141     test_cv< LongEnum4, long >();
142 }
143 
144 enum ULongEnum { ULongEnum_value = ULONG_MAX };
145 
test_promote_to_ulong()146 void test_promote_to_ulong()
147 {
148     test_cv< ULongEnum, unsigned long >();
149 }
150 
151 #endif // #if INT_MAX < LONG_MAX
152 
main()153 int main()
154 {
155     return 0;
156 }
157 
158