llvm.org GIT mirror llvm / 806052b
[APSInt][OpenMP] Fix isNegative, etc. for unsigned types Without this patch, APSInt inherits APInt::isNegative, which merely checks the sign bit without regard to whether the type is actually signed. isNonNegative and isStrictlyPositive call isNegative and so are also affected. This patch adjusts APSInt to override isNegative, isNonNegative, and isStrictlyPositive with implementations that consider whether the type is signed. A large set of Clang OpenMP tests are affected. Without this patch, these tests assume that `true` is not a valid argument for clauses like `collapse`. Indeed, `true` fails APInt::isStrictlyPositive but not APSInt::isStrictlyPositive. This patch adjusts those tests to assume `true` should be accepted. This patch also adds tests revealing various other similar fixes due to APSInt::isNegative calls in Clang's ExprConstant.cpp and SemaExpr.cpp: `++` and `--` overflow in `constexpr`, evaluated object size based on `alloc_size`, `<<` and `>>` shift count validation, and OpenMP array section validation. Reviewed By: lebedev.ri, ABataev, hfinkel Differential Revision: https://reviews.llvm.org/D59712 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@359012 91177308-0d34-0410-b5e6-96231b3b80d8 Joel E. Denny 3 months ago
2 changed file(s) with 104 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
4141 /// \param Str the string to be interpreted.
4242 explicit APSInt(StringRef Str);
4343
44 /// Determine sign of this APSInt.
45 ///
46 /// \returns true if this APSInt is negative, false otherwise
47 bool isNegative() const { return isSigned() && APInt::isNegative(); }
48
49 /// Determine if this APSInt Value is non-negative (>= 0)
50 ///
51 /// \returns true if this APSInt is non-negative, false otherwise
52 bool isNonNegative() const { return !isNegative(); }
53
54 /// Determine if this APSInt Value is positive.
55 ///
56 /// This tests if the value of this APSInt is positive (> 0). Note
57 /// that 0 is not a positive value.
58 ///
59 /// \returns true if this APSInt is positive.
60 bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
61
4462 APSInt &operator=(APInt RHS) {
4563 // Retain our current sign.
4664 APInt::operator=(std::move(RHS));
158158
159159 #endif
160160
161 TEST(APSIntTest, SignedHighBit) {
162 APSInt False(APInt(1, 0), false);
163 APSInt True(APInt(1, 1), false);
164 APSInt CharMin(APInt(8, 0), false);
165 APSInt CharSmall(APInt(8, 0x13), false);
166 APSInt CharBoundaryUnder(APInt(8, 0x7f), false);
167 APSInt CharBoundaryOver(APInt(8, 0x80), false);
168 APSInt CharLarge(APInt(8, 0xd9), false);
169 APSInt CharMax(APInt(8, 0xff), false);
170
171 EXPECT_FALSE(False.isNegative());
172 EXPECT_TRUE(False.isNonNegative());
173 EXPECT_FALSE(False.isStrictlyPositive());
174
175 EXPECT_TRUE(True.isNegative());
176 EXPECT_FALSE(True.isNonNegative());
177 EXPECT_FALSE(True.isStrictlyPositive());
178
179 EXPECT_FALSE(CharMin.isNegative());
180 EXPECT_TRUE(CharMin.isNonNegative());
181 EXPECT_FALSE(CharMin.isStrictlyPositive());
182
183 EXPECT_FALSE(CharSmall.isNegative());
184 EXPECT_TRUE(CharSmall.isNonNegative());
185 EXPECT_TRUE(CharSmall.isStrictlyPositive());
186
187 EXPECT_FALSE(CharBoundaryUnder.isNegative());
188 EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
189 EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
190
191 EXPECT_TRUE(CharBoundaryOver.isNegative());
192 EXPECT_FALSE(CharBoundaryOver.isNonNegative());
193 EXPECT_FALSE(CharBoundaryOver.isStrictlyPositive());
194
195 EXPECT_TRUE(CharLarge.isNegative());
196 EXPECT_FALSE(CharLarge.isNonNegative());
197 EXPECT_FALSE(CharLarge.isStrictlyPositive());
198
199 EXPECT_TRUE(CharMax.isNegative());
200 EXPECT_FALSE(CharMax.isNonNegative());
201 EXPECT_FALSE(CharMax.isStrictlyPositive());
202 }
203
204 TEST(APSIntTest, UnsignedHighBit) {
205 APSInt False(APInt(1, 0));
206 APSInt True(APInt(1, 1));
207 APSInt CharMin(APInt(8, 0));
208 APSInt CharSmall(APInt(8, 0x13));
209 APSInt CharBoundaryUnder(APInt(8, 0x7f));
210 APSInt CharBoundaryOver(APInt(8, 0x80));
211 APSInt CharLarge(APInt(8, 0xd9));
212 APSInt CharMax(APInt(8, 0xff));
213
214 EXPECT_FALSE(False.isNegative());
215 EXPECT_TRUE(False.isNonNegative());
216 EXPECT_FALSE(False.isStrictlyPositive());
217
218 EXPECT_FALSE(True.isNegative());
219 EXPECT_TRUE(True.isNonNegative());
220 EXPECT_TRUE(True.isStrictlyPositive());
221
222 EXPECT_FALSE(CharMin.isNegative());
223 EXPECT_TRUE(CharMin.isNonNegative());
224 EXPECT_FALSE(CharMin.isStrictlyPositive());
225
226 EXPECT_FALSE(CharSmall.isNegative());
227 EXPECT_TRUE(CharSmall.isNonNegative());
228 EXPECT_TRUE(CharSmall.isStrictlyPositive());
229
230 EXPECT_FALSE(CharBoundaryUnder.isNegative());
231 EXPECT_TRUE(CharBoundaryUnder.isNonNegative());
232 EXPECT_TRUE(CharBoundaryUnder.isStrictlyPositive());
233
234 EXPECT_FALSE(CharBoundaryOver.isNegative());
235 EXPECT_TRUE(CharBoundaryOver.isNonNegative());
236 EXPECT_TRUE(CharBoundaryOver.isStrictlyPositive());
237
238 EXPECT_FALSE(CharLarge.isNegative());
239 EXPECT_TRUE(CharLarge.isNonNegative());
240 EXPECT_TRUE(CharLarge.isStrictlyPositive());
241
242 EXPECT_FALSE(CharMax.isNegative());
243 EXPECT_TRUE(CharMax.isNonNegative());
244 EXPECT_TRUE(CharMax.isStrictlyPositive());
245 }
246
161247 } // end anonymous namespace