1 //===--- InterpBuiltin.cpp - Interpreter for the constexpr VM ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #include "../ExprConstShared.h" 9 #include "Boolean.h" 10 #include "Interp.h" 11 #include "PrimType.h" 12 #include "clang/AST/RecordLayout.h" 13 #include "clang/Basic/Builtins.h" 14 #include "clang/Basic/TargetInfo.h" 15 16 namespace clang { 17 namespace interp { 18 19 template <typename T> 20 static T getParam(const InterpFrame *Frame, unsigned Index) { 21 assert(Frame->getFunction()->getNumParams() > Index); 22 unsigned Offset = Frame->getFunction()->getParamOffset(Index); 23 return Frame->getParam<T>(Offset); 24 } 25 26 PrimType getIntPrimType(const InterpState &S) { 27 const TargetInfo &TI = S.getCtx().getTargetInfo(); 28 unsigned IntWidth = TI.getIntWidth(); 29 30 if (IntWidth == 32) 31 return PT_Sint32; 32 else if (IntWidth == 16) 33 return PT_Sint16; 34 llvm_unreachable("Int isn't 16 or 32 bit?"); 35 } 36 37 PrimType getLongPrimType(const InterpState &S) { 38 const TargetInfo &TI = S.getCtx().getTargetInfo(); 39 unsigned LongWidth = TI.getLongWidth(); 40 41 if (LongWidth == 64) 42 return PT_Sint64; 43 else if (LongWidth == 32) 44 return PT_Sint32; 45 else if (LongWidth == 16) 46 return PT_Sint16; 47 llvm_unreachable("long isn't 16, 32 or 64 bit?"); 48 } 49 50 /// Peek an integer value from the stack into an APSInt. 51 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { 52 if (Offset == 0) 53 Offset = align(primSize(T)); 54 55 APSInt R; 56 INT_TYPE_SWITCH(T, { 57 T Val = Stk.peek<T>(Offset); 58 R = APSInt( 59 APInt(Val.bitWidth(), static_cast<uint64_t>(Val), T::isSigned())); 60 }); 61 62 return R; 63 } 64 65 /// Pushes \p Val to the stack, as a target-dependent 'int'. 66 static void pushInt(InterpState &S, int32_t Val) { 67 PrimType IntType = getIntPrimType(S); 68 if (IntType == PT_Sint32) 69 S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val)); 70 else if (IntType == PT_Sint16) 71 S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val)); 72 else 73 llvm_unreachable("Int isn't 16 or 32 bit?"); 74 } 75 76 static void pushAPSInt(InterpState &S, const APSInt &Val) { 77 bool Signed = Val.isSigned(); 78 79 if (Signed) { 80 switch (Val.getBitWidth()) { 81 case 64: 82 S.Stk.push<Integral<64, true>>( 83 Integral<64, true>::from(Val.getSExtValue())); 84 break; 85 case 32: 86 S.Stk.push<Integral<32, true>>( 87 Integral<32, true>::from(Val.getSExtValue())); 88 break; 89 case 16: 90 S.Stk.push<Integral<16, true>>( 91 Integral<16, true>::from(Val.getSExtValue())); 92 break; 93 case 8: 94 S.Stk.push<Integral<8, true>>( 95 Integral<8, true>::from(Val.getSExtValue())); 96 break; 97 default: 98 llvm_unreachable("Invalid integer bitwidth"); 99 } 100 return; 101 } 102 103 // Unsigned. 104 switch (Val.getBitWidth()) { 105 case 64: 106 S.Stk.push<Integral<64, false>>( 107 Integral<64, false>::from(Val.getZExtValue())); 108 break; 109 case 32: 110 S.Stk.push<Integral<32, false>>( 111 Integral<32, false>::from(Val.getZExtValue())); 112 break; 113 case 16: 114 S.Stk.push<Integral<16, false>>( 115 Integral<16, false>::from(Val.getZExtValue())); 116 break; 117 case 8: 118 S.Stk.push<Integral<8, false>>( 119 Integral<8, false>::from(Val.getZExtValue())); 120 break; 121 default: 122 llvm_unreachable("Invalid integer bitwidth"); 123 } 124 } 125 126 /// Pushes \p Val to the stack, as a target-dependent 'long'. 127 static void pushLong(InterpState &S, int64_t Val) { 128 PrimType LongType = getLongPrimType(S); 129 if (LongType == PT_Sint64) 130 S.Stk.push<Integral<64, true>>(Integral<64, true>::from(Val)); 131 else if (LongType == PT_Sint32) 132 S.Stk.push<Integral<32, true>>(Integral<32, true>::from(Val)); 133 else if (LongType == PT_Sint16) 134 S.Stk.push<Integral<16, true>>(Integral<16, true>::from(Val)); 135 else 136 llvm_unreachable("Long isn't 16, 32 or 64 bit?"); 137 } 138 139 static void pushSizeT(InterpState &S, uint64_t Val) { 140 const TargetInfo &TI = S.getCtx().getTargetInfo(); 141 unsigned SizeTWidth = TI.getTypeWidth(TI.getSizeType()); 142 143 switch (SizeTWidth) { 144 case 64: 145 S.Stk.push<Integral<64, false>>(Integral<64, false>::from(Val)); 146 break; 147 case 32: 148 S.Stk.push<Integral<32, false>>(Integral<32, false>::from(Val)); 149 break; 150 case 16: 151 S.Stk.push<Integral<16, false>>(Integral<16, false>::from(Val)); 152 break; 153 default: 154 llvm_unreachable("We don't handle this size_t size."); 155 } 156 } 157 158 static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, 159 std::optional<PrimType> &T) { 160 if (!T) 161 return RetVoid(S, OpPC, Result); 162 163 #define RET_CASE(X) \ 164 case X: \ 165 return Ret<X>(S, OpPC, Result); 166 switch (*T) { 167 RET_CASE(PT_Float); 168 RET_CASE(PT_Bool); 169 RET_CASE(PT_Sint8); 170 RET_CASE(PT_Uint8); 171 RET_CASE(PT_Sint16); 172 RET_CASE(PT_Uint16); 173 RET_CASE(PT_Sint32); 174 RET_CASE(PT_Uint32); 175 RET_CASE(PT_Sint64); 176 RET_CASE(PT_Uint64); 177 default: 178 llvm_unreachable("Unsupported return type for builtin function"); 179 } 180 #undef RET_CASE 181 } 182 183 static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, 184 const InterpFrame *Frame) { 185 const Pointer &A = getParam<Pointer>(Frame, 0); 186 const Pointer &B = getParam<Pointer>(Frame, 1); 187 188 if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read)) 189 return false; 190 191 assert(A.getFieldDesc()->isPrimitiveArray()); 192 assert(B.getFieldDesc()->isPrimitiveArray()); 193 194 unsigned IndexA = A.getIndex(); 195 unsigned IndexB = B.getIndex(); 196 int32_t Result = 0; 197 for (;; ++IndexA, ++IndexB) { 198 const Pointer &PA = A.atIndex(IndexA); 199 const Pointer &PB = B.atIndex(IndexB); 200 if (!CheckRange(S, OpPC, PA, AK_Read) || 201 !CheckRange(S, OpPC, PB, AK_Read)) { 202 return false; 203 } 204 uint8_t CA = PA.deref<uint8_t>(); 205 uint8_t CB = PB.deref<uint8_t>(); 206 207 if (CA > CB) { 208 Result = 1; 209 break; 210 } else if (CA < CB) { 211 Result = -1; 212 break; 213 } 214 if (CA == 0 || CB == 0) 215 break; 216 } 217 218 pushInt(S, Result); 219 return true; 220 } 221 222 static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, 223 const InterpFrame *Frame) { 224 const Pointer &StrPtr = getParam<Pointer>(Frame, 0); 225 226 if (!CheckArray(S, OpPC, StrPtr)) 227 return false; 228 229 if (!CheckLive(S, OpPC, StrPtr, AK_Read)) 230 return false; 231 232 if (!CheckDummy(S, OpPC, StrPtr)) 233 return false; 234 235 assert(StrPtr.getFieldDesc()->isPrimitiveArray()); 236 237 size_t Len = 0; 238 for (size_t I = StrPtr.getIndex();; ++I, ++Len) { 239 const Pointer &ElemPtr = StrPtr.atIndex(I); 240 241 if (!CheckRange(S, OpPC, ElemPtr, AK_Read)) 242 return false; 243 244 uint8_t Val = ElemPtr.deref<uint8_t>(); 245 if (Val == 0) 246 break; 247 } 248 249 pushSizeT(S, Len); 250 return true; 251 } 252 253 static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, 254 const InterpFrame *Frame, const Function *F, 255 bool Signaling) { 256 const Pointer &Arg = getParam<Pointer>(Frame, 0); 257 258 if (!CheckLoad(S, OpPC, Arg)) 259 return false; 260 261 assert(Arg.getFieldDesc()->isPrimitiveArray()); 262 263 // Convert the given string to an integer using StringRef's API. 264 llvm::APInt Fill; 265 std::string Str; 266 assert(Arg.getNumElems() >= 1); 267 for (unsigned I = 0;; ++I) { 268 const Pointer &Elem = Arg.atIndex(I); 269 270 if (!CheckLoad(S, OpPC, Elem)) 271 return false; 272 273 if (Elem.deref<int8_t>() == 0) 274 break; 275 276 Str += Elem.deref<char>(); 277 } 278 279 // Treat empty strings as if they were zero. 280 if (Str.empty()) 281 Fill = llvm::APInt(32, 0); 282 else if (StringRef(Str).getAsInteger(0, Fill)) 283 return false; 284 285 const llvm::fltSemantics &TargetSemantics = 286 S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType()); 287 288 Floating Result; 289 if (S.getCtx().getTargetInfo().isNan2008()) { 290 if (Signaling) 291 Result = Floating( 292 llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); 293 else 294 Result = Floating( 295 llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); 296 } else { 297 // Prior to IEEE 754-2008, architectures were allowed to choose whether 298 // the first bit of their significand was set for qNaN or sNaN. MIPS chose 299 // a different encoding to what became a standard in 2008, and for pre- 300 // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as 301 // sNaN. This is now known as "legacy NaN" encoding. 302 if (Signaling) 303 Result = Floating( 304 llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); 305 else 306 Result = Floating( 307 llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); 308 } 309 310 S.Stk.push<Floating>(Result); 311 return true; 312 } 313 314 static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, 315 const InterpFrame *Frame, const Function *F) { 316 const llvm::fltSemantics &TargetSemantics = 317 S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType()); 318 319 S.Stk.push<Floating>(Floating::getInf(TargetSemantics)); 320 return true; 321 } 322 323 static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, 324 const InterpFrame *Frame, 325 const Function *F) { 326 const Floating &Arg1 = getParam<Floating>(Frame, 0); 327 const Floating &Arg2 = getParam<Floating>(Frame, 1); 328 329 APFloat Copy = Arg1.getAPFloat(); 330 Copy.copySign(Arg2.getAPFloat()); 331 S.Stk.push<Floating>(Floating(Copy)); 332 333 return true; 334 } 335 336 static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, 337 const InterpFrame *Frame, const Function *F) { 338 const Floating &LHS = getParam<Floating>(Frame, 0); 339 const Floating &RHS = getParam<Floating>(Frame, 1); 340 341 Floating Result; 342 343 // When comparing zeroes, return -0.0 if one of the zeroes is negative. 344 if (LHS.isZero() && RHS.isZero() && RHS.isNegative()) 345 Result = RHS; 346 else if (LHS.isNan() || RHS < LHS) 347 Result = RHS; 348 else 349 Result = LHS; 350 351 S.Stk.push<Floating>(Result); 352 return true; 353 } 354 355 static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, 356 const InterpFrame *Frame, 357 const Function *Func) { 358 const Floating &LHS = getParam<Floating>(Frame, 0); 359 const Floating &RHS = getParam<Floating>(Frame, 1); 360 361 Floating Result; 362 363 // When comparing zeroes, return +0.0 if one of the zeroes is positive. 364 if (LHS.isZero() && RHS.isZero() && LHS.isNegative()) 365 Result = RHS; 366 else if (LHS.isNan() || RHS > LHS) 367 Result = RHS; 368 else 369 Result = LHS; 370 371 S.Stk.push<Floating>(Result); 372 return true; 373 } 374 375 /// Defined as __builtin_isnan(...), to accommodate the fact that it can 376 /// take a float, double, long double, etc. 377 /// But for us, that's all a Floating anyway. 378 static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, 379 const InterpFrame *Frame, const Function *F) { 380 const Floating &Arg = S.Stk.peek<Floating>(); 381 382 pushInt(S, Arg.isNan()); 383 return true; 384 } 385 386 static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, 387 const InterpFrame *Frame, 388 const Function *F) { 389 const Floating &Arg = S.Stk.peek<Floating>(); 390 391 pushInt(S, Arg.isSignaling()); 392 return true; 393 } 394 395 static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, 396 const InterpFrame *Frame, const Function *F, 397 bool CheckSign) { 398 const Floating &Arg = S.Stk.peek<Floating>(); 399 bool IsInf = Arg.isInf(); 400 401 if (CheckSign) 402 pushInt(S, IsInf ? (Arg.isNegative() ? -1 : 1) : 0); 403 else 404 pushInt(S, Arg.isInf()); 405 return true; 406 } 407 408 static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, 409 const InterpFrame *Frame, 410 const Function *F) { 411 const Floating &Arg = S.Stk.peek<Floating>(); 412 413 pushInt(S, Arg.isFinite()); 414 return true; 415 } 416 417 static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, 418 const InterpFrame *Frame, 419 const Function *F) { 420 const Floating &Arg = S.Stk.peek<Floating>(); 421 422 pushInt(S, Arg.isNormal()); 423 return true; 424 } 425 426 static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, 427 const InterpFrame *Frame, 428 const Function *F) { 429 const Floating &Arg = S.Stk.peek<Floating>(); 430 431 pushInt(S, Arg.isDenormal()); 432 return true; 433 } 434 435 static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, 436 const InterpFrame *Frame, 437 const Function *F) { 438 const Floating &Arg = S.Stk.peek<Floating>(); 439 440 pushInt(S, Arg.isZero()); 441 return true; 442 } 443 444 /// First parameter to __builtin_isfpclass is the floating value, the 445 /// second one is an integral value. 446 static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, 447 const InterpFrame *Frame, 448 const Function *Func, 449 const CallExpr *Call) { 450 PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType()); 451 APSInt FPClassArg = peekToAPSInt(S.Stk, FPClassArgT); 452 const Floating &F = 453 S.Stk.peek<Floating>(align(primSize(FPClassArgT) + primSize(PT_Float))); 454 455 int32_t Result = 456 static_cast<int32_t>((F.classify() & FPClassArg).getZExtValue()); 457 pushInt(S, Result); 458 459 return true; 460 } 461 462 /// Five int values followed by one floating value. 463 static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, 464 const InterpFrame *Frame, 465 const Function *Func) { 466 const Floating &Val = S.Stk.peek<Floating>(); 467 468 unsigned Index; 469 switch (Val.getCategory()) { 470 case APFloat::fcNaN: 471 Index = 0; 472 break; 473 case APFloat::fcInfinity: 474 Index = 1; 475 break; 476 case APFloat::fcNormal: 477 Index = Val.isDenormal() ? 3 : 2; 478 break; 479 case APFloat::fcZero: 480 Index = 4; 481 break; 482 } 483 484 // The last argument is first on the stack. 485 assert(Index <= 4); 486 unsigned IntSize = primSize(getIntPrimType(S)); 487 unsigned Offset = 488 align(primSize(PT_Float)) + ((1 + (4 - Index)) * align(IntSize)); 489 490 APSInt I = peekToAPSInt(S.Stk, getIntPrimType(S), Offset); 491 pushInt(S, I.getZExtValue()); 492 return true; 493 } 494 495 // The C standard says "fabs raises no floating-point exceptions, 496 // even if x is a signaling NaN. The returned value is independent of 497 // the current rounding direction mode." Therefore constant folding can 498 // proceed without regard to the floating point settings. 499 // Reference, WG14 N2478 F.10.4.3 500 static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, 501 const InterpFrame *Frame, 502 const Function *Func) { 503 const Floating &Val = getParam<Floating>(Frame, 0); 504 505 S.Stk.push<Floating>(Floating::abs(Val)); 506 return true; 507 } 508 509 static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, 510 const InterpFrame *Frame, 511 const Function *Func, 512 const CallExpr *Call) { 513 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 514 APSInt Val = peekToAPSInt(S.Stk, ArgT); 515 pushInt(S, Val.popcount()); 516 return true; 517 } 518 519 static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, 520 const InterpFrame *Frame, 521 const Function *Func, const CallExpr *Call) { 522 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 523 APSInt Val = peekToAPSInt(S.Stk, ArgT); 524 pushInt(S, Val.popcount() % 2); 525 return true; 526 } 527 528 static bool interp__builtin_clrsb(InterpState &S, CodePtr OpPC, 529 const InterpFrame *Frame, 530 const Function *Func, const CallExpr *Call) { 531 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 532 APSInt Val = peekToAPSInt(S.Stk, ArgT); 533 pushInt(S, Val.getBitWidth() - Val.getSignificantBits()); 534 return true; 535 } 536 537 static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, 538 const InterpFrame *Frame, 539 const Function *Func, 540 const CallExpr *Call) { 541 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 542 APSInt Val = peekToAPSInt(S.Stk, ArgT); 543 pushAPSInt(S, APSInt(Val.reverseBits(), /*IsUnsigned=*/true)); 544 return true; 545 } 546 547 static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, 548 const InterpFrame *Frame, 549 const Function *Func, 550 const CallExpr *Call) { 551 // This is an unevaluated call, so there are no arguments on the stack. 552 assert(Call->getNumArgs() == 1); 553 const Expr *Arg = Call->getArg(0); 554 555 GCCTypeClass ResultClass = 556 EvaluateBuiltinClassifyType(Arg->getType(), S.getLangOpts()); 557 int32_t ReturnVal = static_cast<int32_t>(ResultClass); 558 pushInt(S, ReturnVal); 559 return true; 560 } 561 562 // __builtin_expect(long, long) 563 // __builtin_expect_with_probability(long, long, double) 564 static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, 565 const InterpFrame *Frame, 566 const Function *Func, const CallExpr *Call) { 567 // The return value is simply the value of the first parameter. 568 // We ignore the probability. 569 unsigned NumArgs = Call->getNumArgs(); 570 assert(NumArgs == 2 || NumArgs == 3); 571 572 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 573 unsigned Offset = align(primSize(getLongPrimType(S))) * 2; 574 if (NumArgs == 3) 575 Offset += align(primSize(PT_Float)); 576 577 APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset); 578 pushLong(S, Val.getSExtValue()); 579 return true; 580 } 581 582 /// rotateleft(value, amount) 583 static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, 584 const InterpFrame *Frame, 585 const Function *Func, const CallExpr *Call, 586 bool Right) { 587 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 588 assert(ArgT == *S.getContext().classify(Call->getArg(1)->getType())); 589 590 APSInt Amount = peekToAPSInt(S.Stk, ArgT); 591 APSInt Value = peekToAPSInt(S.Stk, ArgT, align(primSize(ArgT)) * 2); 592 593 APSInt Result; 594 if (Right) 595 Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())), 596 /*IsUnsigned=*/true); 597 else // Left. 598 Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())), 599 /*IsUnsigned=*/true); 600 601 pushAPSInt(S, Result); 602 return true; 603 } 604 605 static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, 606 const InterpFrame *Frame, const Function *Func, 607 const CallExpr *Call) { 608 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 609 APSInt Value = peekToAPSInt(S.Stk, ArgT); 610 611 uint64_t N = Value.countr_zero(); 612 pushInt(S, N == Value.getBitWidth() ? 0 : N + 1); 613 return true; 614 } 615 616 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, 617 const CallExpr *Call) { 618 InterpFrame *Frame = S.Current; 619 APValue Dummy; 620 621 QualType ReturnType = Call->getCallReturnType(S.getCtx()); 622 std::optional<PrimType> ReturnT = S.getContext().classify(ReturnType); 623 // If classify failed, we assume void. 624 assert(ReturnT || ReturnType->isVoidType()); 625 626 switch (F->getBuiltinID()) { 627 case Builtin::BI__builtin_is_constant_evaluated: 628 S.Stk.push<Boolean>(Boolean::from(S.inConstantContext())); 629 break; 630 case Builtin::BI__builtin_assume: 631 break; 632 case Builtin::BI__builtin_strcmp: 633 if (!interp__builtin_strcmp(S, OpPC, Frame)) 634 return false; 635 break; 636 case Builtin::BI__builtin_strlen: 637 if (!interp__builtin_strlen(S, OpPC, Frame)) 638 return false; 639 break; 640 case Builtin::BI__builtin_nan: 641 case Builtin::BI__builtin_nanf: 642 case Builtin::BI__builtin_nanl: 643 case Builtin::BI__builtin_nanf16: 644 case Builtin::BI__builtin_nanf128: 645 if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/false)) 646 return false; 647 break; 648 case Builtin::BI__builtin_nans: 649 case Builtin::BI__builtin_nansf: 650 case Builtin::BI__builtin_nansl: 651 case Builtin::BI__builtin_nansf16: 652 case Builtin::BI__builtin_nansf128: 653 if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/true)) 654 return false; 655 break; 656 657 case Builtin::BI__builtin_huge_val: 658 case Builtin::BI__builtin_huge_valf: 659 case Builtin::BI__builtin_huge_vall: 660 case Builtin::BI__builtin_huge_valf16: 661 case Builtin::BI__builtin_huge_valf128: 662 case Builtin::BI__builtin_inf: 663 case Builtin::BI__builtin_inff: 664 case Builtin::BI__builtin_infl: 665 case Builtin::BI__builtin_inff16: 666 case Builtin::BI__builtin_inff128: 667 if (!interp__builtin_inf(S, OpPC, Frame, F)) 668 return false; 669 break; 670 case Builtin::BI__builtin_copysign: 671 case Builtin::BI__builtin_copysignf: 672 case Builtin::BI__builtin_copysignl: 673 case Builtin::BI__builtin_copysignf128: 674 if (!interp__builtin_copysign(S, OpPC, Frame, F)) 675 return false; 676 break; 677 678 case Builtin::BI__builtin_fmin: 679 case Builtin::BI__builtin_fminf: 680 case Builtin::BI__builtin_fminl: 681 case Builtin::BI__builtin_fminf16: 682 case Builtin::BI__builtin_fminf128: 683 if (!interp__builtin_fmin(S, OpPC, Frame, F)) 684 return false; 685 break; 686 687 case Builtin::BI__builtin_fmax: 688 case Builtin::BI__builtin_fmaxf: 689 case Builtin::BI__builtin_fmaxl: 690 case Builtin::BI__builtin_fmaxf16: 691 case Builtin::BI__builtin_fmaxf128: 692 if (!interp__builtin_fmax(S, OpPC, Frame, F)) 693 return false; 694 break; 695 696 case Builtin::BI__builtin_isnan: 697 if (!interp__builtin_isnan(S, OpPC, Frame, F)) 698 return false; 699 break; 700 case Builtin::BI__builtin_issignaling: 701 if (!interp__builtin_issignaling(S, OpPC, Frame, F)) 702 return false; 703 break; 704 705 case Builtin::BI__builtin_isinf: 706 if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false)) 707 return false; 708 break; 709 710 case Builtin::BI__builtin_isinf_sign: 711 if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true)) 712 return false; 713 break; 714 715 case Builtin::BI__builtin_isfinite: 716 if (!interp__builtin_isfinite(S, OpPC, Frame, F)) 717 return false; 718 break; 719 case Builtin::BI__builtin_isnormal: 720 if (!interp__builtin_isnormal(S, OpPC, Frame, F)) 721 return false; 722 break; 723 case Builtin::BI__builtin_issubnormal: 724 if (!interp__builtin_issubnormal(S, OpPC, Frame, F)) 725 return false; 726 break; 727 case Builtin::BI__builtin_iszero: 728 if (!interp__builtin_iszero(S, OpPC, Frame, F)) 729 return false; 730 break; 731 case Builtin::BI__builtin_isfpclass: 732 if (!interp__builtin_isfpclass(S, OpPC, Frame, F, Call)) 733 return false; 734 break; 735 case Builtin::BI__builtin_fpclassify: 736 if (!interp__builtin_fpclassify(S, OpPC, Frame, F)) 737 return false; 738 break; 739 740 case Builtin::BI__builtin_fabs: 741 case Builtin::BI__builtin_fabsf: 742 case Builtin::BI__builtin_fabsl: 743 case Builtin::BI__builtin_fabsf128: 744 if (!interp__builtin_fabs(S, OpPC, Frame, F)) 745 return false; 746 break; 747 748 case Builtin::BI__builtin_popcount: 749 case Builtin::BI__builtin_popcountl: 750 case Builtin::BI__builtin_popcountll: 751 case Builtin::BI__popcnt16: // Microsoft variants of popcount 752 case Builtin::BI__popcnt: 753 case Builtin::BI__popcnt64: 754 if (!interp__builtin_popcount(S, OpPC, Frame, F, Call)) 755 return false; 756 break; 757 758 case Builtin::BI__builtin_parity: 759 case Builtin::BI__builtin_parityl: 760 case Builtin::BI__builtin_parityll: 761 if (!interp__builtin_parity(S, OpPC, Frame, F, Call)) 762 return false; 763 break; 764 765 case Builtin::BI__builtin_clrsb: 766 case Builtin::BI__builtin_clrsbl: 767 case Builtin::BI__builtin_clrsbll: 768 if (!interp__builtin_clrsb(S, OpPC, Frame, F, Call)) 769 return false; 770 break; 771 772 case Builtin::BI__builtin_bitreverse8: 773 case Builtin::BI__builtin_bitreverse16: 774 case Builtin::BI__builtin_bitreverse32: 775 case Builtin::BI__builtin_bitreverse64: 776 if (!interp__builtin_bitreverse(S, OpPC, Frame, F, Call)) 777 return false; 778 break; 779 780 case Builtin::BI__builtin_classify_type: 781 if (!interp__builtin_classify_type(S, OpPC, Frame, F, Call)) 782 return false; 783 break; 784 785 case Builtin::BI__builtin_expect: 786 case Builtin::BI__builtin_expect_with_probability: 787 if (!interp__builtin_expect(S, OpPC, Frame, F, Call)) 788 return false; 789 break; 790 791 case Builtin::BI__builtin_rotateleft8: 792 case Builtin::BI__builtin_rotateleft16: 793 case Builtin::BI__builtin_rotateleft32: 794 case Builtin::BI__builtin_rotateleft64: 795 case Builtin::BI_rotl8: // Microsoft variants of rotate left 796 case Builtin::BI_rotl16: 797 case Builtin::BI_rotl: 798 case Builtin::BI_lrotl: 799 case Builtin::BI_rotl64: 800 if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false)) 801 return false; 802 break; 803 804 case Builtin::BI__builtin_rotateright8: 805 case Builtin::BI__builtin_rotateright16: 806 case Builtin::BI__builtin_rotateright32: 807 case Builtin::BI__builtin_rotateright64: 808 case Builtin::BI_rotr8: // Microsoft variants of rotate right 809 case Builtin::BI_rotr16: 810 case Builtin::BI_rotr: 811 case Builtin::BI_lrotr: 812 case Builtin::BI_rotr64: 813 if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true)) 814 return false; 815 break; 816 817 case Builtin::BI__builtin_ffs: 818 case Builtin::BI__builtin_ffsl: 819 case Builtin::BI__builtin_ffsll: 820 if (!interp__builtin_ffs(S, OpPC, Frame, F, Call)) 821 return false; 822 break; 823 824 default: 825 return false; 826 } 827 828 return retPrimValue(S, OpPC, Dummy, ReturnT); 829 } 830 831 bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, 832 llvm::ArrayRef<int64_t> ArrayIndices, 833 int64_t &IntResult) { 834 CharUnits Result; 835 unsigned N = E->getNumComponents(); 836 assert(N > 0); 837 838 unsigned ArrayIndex = 0; 839 QualType CurrentType = E->getTypeSourceInfo()->getType(); 840 for (unsigned I = 0; I != N; ++I) { 841 const OffsetOfNode &Node = E->getComponent(I); 842 switch (Node.getKind()) { 843 case OffsetOfNode::Field: { 844 const FieldDecl *MemberDecl = Node.getField(); 845 const RecordType *RT = CurrentType->getAs<RecordType>(); 846 if (!RT) 847 return false; 848 RecordDecl *RD = RT->getDecl(); 849 if (RD->isInvalidDecl()) 850 return false; 851 const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD); 852 unsigned FieldIndex = MemberDecl->getFieldIndex(); 853 assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type"); 854 Result += S.getCtx().toCharUnitsFromBits(RL.getFieldOffset(FieldIndex)); 855 CurrentType = MemberDecl->getType().getNonReferenceType(); 856 break; 857 } 858 case OffsetOfNode::Array: { 859 // When generating bytecode, we put all the index expressions as Sint64 on 860 // the stack. 861 int64_t Index = ArrayIndices[ArrayIndex]; 862 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType); 863 if (!AT) 864 return false; 865 CurrentType = AT->getElementType(); 866 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType); 867 Result += Index * ElementSize; 868 ++ArrayIndex; 869 break; 870 } 871 case OffsetOfNode::Base: { 872 const CXXBaseSpecifier *BaseSpec = Node.getBase(); 873 if (BaseSpec->isVirtual()) 874 return false; 875 876 // Find the layout of the class whose base we are looking into. 877 const RecordType *RT = CurrentType->getAs<RecordType>(); 878 if (!RT) 879 return false; 880 const RecordDecl *RD = RT->getDecl(); 881 if (RD->isInvalidDecl()) 882 return false; 883 const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD); 884 885 // Find the base class itself. 886 CurrentType = BaseSpec->getType(); 887 const RecordType *BaseRT = CurrentType->getAs<RecordType>(); 888 if (!BaseRT) 889 return false; 890 891 // Add the offset to the base. 892 Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl())); 893 break; 894 } 895 case OffsetOfNode::Identifier: 896 llvm_unreachable("Dependent OffsetOfExpr?"); 897 } 898 } 899 900 IntResult = Result.getQuantity(); 901 902 return true; 903 } 904 905 bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, 906 const Pointer &Ptr, const APSInt &IntValue) { 907 908 const Record *R = Ptr.getRecord(); 909 assert(R); 910 assert(R->getNumFields() == 1); 911 912 unsigned FieldOffset = R->getField(0u)->Offset; 913 const Pointer &FieldPtr = Ptr.atField(FieldOffset); 914 PrimType FieldT = *S.getContext().classify(FieldPtr.getType()); 915 916 INT_TYPE_SWITCH(FieldT, 917 FieldPtr.deref<T>() = T::from(IntValue.getSExtValue())); 918 FieldPtr.initialize(); 919 return true; 920 } 921 922 } // namespace interp 923 } // namespace clang 924