@@ -3110,3 +3110,137 @@ def test_malloc_implicit(self):
3110
3110
Popen ([PYTHON , EMCC , 'src.cpp' ]).communicate ()
3111
3111
self .assertContained ('ok' , run_js ('a.out.js' ))
3112
3112
3113
+ def test_switch64phi (self ):
3114
+ # issue 2539, fastcomp segfault on phi-i64 interaction
3115
+ self .clear ()
3116
+ open ('src.cpp' , 'w' ).write (r'''
3117
+ #include <cstdint>
3118
+ #include <limits>
3119
+ #include <cstdio>
3120
+
3121
+ //============================================================================
3122
+
3123
+ namespace
3124
+ {
3125
+ class int_adapter {
3126
+ public:
3127
+ typedef ::int64_t int_type;
3128
+
3129
+ int_adapter(int_type v = 0)
3130
+ : value_(v)
3131
+ {}
3132
+ static const int_adapter pos_infinity()
3133
+ {
3134
+ return (::std::numeric_limits<int_type>::max)();
3135
+ }
3136
+ static const int_adapter neg_infinity()
3137
+ {
3138
+ return (::std::numeric_limits<int_type>::min)();
3139
+ }
3140
+ static const int_adapter not_a_number()
3141
+ {
3142
+ return (::std::numeric_limits<int_type>::max)()-1;
3143
+ }
3144
+ static bool is_neg_inf(int_type v)
3145
+ {
3146
+ return (v == neg_infinity().as_number());
3147
+ }
3148
+ static bool is_pos_inf(int_type v)
3149
+ {
3150
+ return (v == pos_infinity().as_number());
3151
+ }
3152
+ static bool is_not_a_number(int_type v)
3153
+ {
3154
+ return (v == not_a_number().as_number());
3155
+ }
3156
+
3157
+ bool is_infinity() const
3158
+ {
3159
+ return (value_ == neg_infinity().as_number() ||
3160
+ value_ == pos_infinity().as_number());
3161
+ }
3162
+ bool is_special() const
3163
+ {
3164
+ return(is_infinity() || value_ == not_a_number().as_number());
3165
+ }
3166
+ bool operator<(const int_adapter& rhs) const
3167
+ {
3168
+ if(value_ == not_a_number().as_number()
3169
+ || rhs.value_ == not_a_number().as_number()) {
3170
+ return false;
3171
+ }
3172
+ if(value_ < rhs.value_) return true;
3173
+ return false;
3174
+ }
3175
+ int_type as_number() const
3176
+ {
3177
+ return value_;
3178
+ }
3179
+
3180
+ int_adapter operator-(const int_adapter& rhs)const
3181
+ {
3182
+ if(is_special() || rhs.is_special())
3183
+ {
3184
+ if (rhs.is_pos_inf(rhs.as_number()))
3185
+ {
3186
+ return int_adapter(1);
3187
+ }
3188
+ if (rhs.is_neg_inf(rhs.as_number()))
3189
+ {
3190
+ return int_adapter();
3191
+ }
3192
+ }
3193
+ return int_adapter();
3194
+ }
3195
+
3196
+
3197
+ private:
3198
+ int_type value_;
3199
+ };
3200
+
3201
+ class time_iterator {
3202
+ public:
3203
+ time_iterator(int_adapter t, int_adapter d)
3204
+ : current_(t),
3205
+ offset_(d)
3206
+ {}
3207
+
3208
+ time_iterator& operator--()
3209
+ {
3210
+ current_ = int_adapter(current_ - offset_);
3211
+ return *this;
3212
+ }
3213
+
3214
+ bool operator>=(const int_adapter& t)
3215
+ {
3216
+ return not (current_ < t);
3217
+ }
3218
+
3219
+ private:
3220
+ int_adapter current_;
3221
+ int_adapter offset_;
3222
+ };
3223
+
3224
+ void iterate_backward(const int_adapter *answers, const int_adapter& td)
3225
+ {
3226
+ int_adapter end = answers[0];
3227
+ time_iterator titr(end, td);
3228
+
3229
+ std::puts("");
3230
+ for (; titr >= answers[0]; --titr) {
3231
+ }
3232
+ }
3233
+ }
3234
+
3235
+ int
3236
+ main()
3237
+ {
3238
+ const int_adapter answer1[] = {};
3239
+ iterate_backward(NULL, int_adapter());
3240
+ iterate_backward(answer1, int_adapter());
3241
+ }
3242
+ ''' )
3243
+ Popen ([PYTHON , EMCC , 'src.cpp' , '-O2' , '-s' , 'SAFE_HEAP=1' ]).communicate ()
3244
+ assert os .path .exists ('a.out.js' ) # build should succeed
3245
+ self .assertContained ('segmentation fault loading 4 bytes from address 0' , run_js ('a.out.js' , assert_returncode = None , stderr = PIPE )) # program should segfault
3246
+
0 commit comments