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/OSLog.h" 13 #include "clang/AST/RecordLayout.h" 14 #include "clang/Basic/Builtins.h" 15 #include "clang/Basic/TargetInfo.h" 16 #include "llvm/Support/SipHash.h" 17 18 namespace clang { 19 namespace interp { 20 21 static unsigned callArgSize(const InterpState &S, const CallExpr *C) { 22 unsigned O = 0; 23 24 for (const Expr *E : C->arguments()) { 25 O += align(primSize(*S.getContext().classify(E))); 26 } 27 28 return O; 29 } 30 31 template <typename T> 32 static T getParam(const InterpFrame *Frame, unsigned Index) { 33 assert(Frame->getFunction()->getNumParams() > Index); 34 unsigned Offset = Frame->getFunction()->getParamOffset(Index); 35 return Frame->getParam<T>(Offset); 36 } 37 38 PrimType getIntPrimType(const InterpState &S) { 39 const TargetInfo &TI = S.getCtx().getTargetInfo(); 40 unsigned IntWidth = TI.getIntWidth(); 41 42 if (IntWidth == 32) 43 return PT_Sint32; 44 else if (IntWidth == 16) 45 return PT_Sint16; 46 llvm_unreachable("Int isn't 16 or 32 bit?"); 47 } 48 49 PrimType getLongPrimType(const InterpState &S) { 50 const TargetInfo &TI = S.getCtx().getTargetInfo(); 51 unsigned LongWidth = TI.getLongWidth(); 52 53 if (LongWidth == 64) 54 return PT_Sint64; 55 else if (LongWidth == 32) 56 return PT_Sint32; 57 else if (LongWidth == 16) 58 return PT_Sint16; 59 llvm_unreachable("long isn't 16, 32 or 64 bit?"); 60 } 61 62 /// Peek an integer value from the stack into an APSInt. 63 static APSInt peekToAPSInt(InterpStack &Stk, PrimType T, size_t Offset = 0) { 64 if (Offset == 0) 65 Offset = align(primSize(T)); 66 67 APSInt R; 68 INT_TYPE_SWITCH(T, R = Stk.peek<T>(Offset).toAPSInt()); 69 70 return R; 71 } 72 73 /// Pushes \p Val on the stack as the type given by \p QT. 74 static void pushInteger(InterpState &S, const APSInt &Val, QualType QT) { 75 assert(QT->isSignedIntegerOrEnumerationType() || 76 QT->isUnsignedIntegerOrEnumerationType()); 77 std::optional<PrimType> T = S.getContext().classify(QT); 78 assert(T); 79 80 if (QT->isSignedIntegerOrEnumerationType()) { 81 int64_t V = Val.getSExtValue(); 82 INT_TYPE_SWITCH(*T, { S.Stk.push<T>(T::from(V)); }); 83 } else { 84 assert(QT->isUnsignedIntegerOrEnumerationType()); 85 uint64_t V = Val.getZExtValue(); 86 INT_TYPE_SWITCH(*T, { S.Stk.push<T>(T::from(V)); }); 87 } 88 } 89 90 template <typename T> 91 static void pushInteger(InterpState &S, T Val, QualType QT) { 92 if constexpr (std::is_same_v<T, APInt>) 93 pushInteger(S, APSInt(Val, !std::is_signed_v<T>), QT); 94 else 95 pushInteger(S, 96 APSInt(APInt(sizeof(T) * 8, static_cast<uint64_t>(Val), 97 std::is_signed_v<T>), 98 !std::is_signed_v<T>), 99 QT); 100 } 101 102 static void assignInteger(Pointer &Dest, PrimType ValueT, const APSInt &Value) { 103 INT_TYPE_SWITCH_NO_BOOL( 104 ValueT, { Dest.deref<T>() = T::from(static_cast<T>(Value)); }); 105 } 106 107 static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result, 108 std::optional<PrimType> &T) { 109 if (!T) 110 return RetVoid(S, OpPC, Result); 111 112 #define RET_CASE(X) \ 113 case X: \ 114 return Ret<X>(S, OpPC, Result); 115 switch (*T) { 116 RET_CASE(PT_Ptr); 117 RET_CASE(PT_FnPtr); 118 RET_CASE(PT_Float); 119 RET_CASE(PT_Bool); 120 RET_CASE(PT_Sint8); 121 RET_CASE(PT_Uint8); 122 RET_CASE(PT_Sint16); 123 RET_CASE(PT_Uint16); 124 RET_CASE(PT_Sint32); 125 RET_CASE(PT_Uint32); 126 RET_CASE(PT_Sint64); 127 RET_CASE(PT_Uint64); 128 default: 129 llvm_unreachable("Unsupported return type for builtin function"); 130 } 131 #undef RET_CASE 132 } 133 134 static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC, 135 const InterpFrame *Frame, 136 const CallExpr *Call) { 137 // The current frame is the one for __builtin_is_constant_evaluated. 138 // The one above that, potentially the one for std::is_constant_evaluated(). 139 if (S.inConstantContext() && !S.checkingPotentialConstantExpression() && 140 Frame->Caller && S.getEvalStatus().Diag) { 141 auto isStdCall = [](const FunctionDecl *F) -> bool { 142 return F && F->isInStdNamespace() && F->getIdentifier() && 143 F->getIdentifier()->isStr("is_constant_evaluated"); 144 }; 145 const InterpFrame *Caller = Frame->Caller; 146 147 if (Caller->Caller && isStdCall(Caller->getCallee())) { 148 const Expr *E = Caller->Caller->getExpr(Caller->getRetPC()); 149 S.report(E->getExprLoc(), 150 diag::warn_is_constant_evaluated_always_true_constexpr) 151 << "std::is_constant_evaluated" << E->getSourceRange(); 152 } else { 153 const Expr *E = Frame->Caller->getExpr(Frame->getRetPC()); 154 S.report(E->getExprLoc(), 155 diag::warn_is_constant_evaluated_always_true_constexpr) 156 << "__builtin_is_constant_evaluated" << E->getSourceRange(); 157 } 158 } 159 160 S.Stk.push<Boolean>(Boolean::from(S.inConstantContext())); 161 return true; 162 } 163 164 static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, 165 const InterpFrame *Frame, 166 const CallExpr *Call) { 167 const Pointer &A = getParam<Pointer>(Frame, 0); 168 const Pointer &B = getParam<Pointer>(Frame, 1); 169 170 if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read)) 171 return false; 172 173 if (A.isDummy() || B.isDummy()) 174 return false; 175 176 assert(A.getFieldDesc()->isPrimitiveArray()); 177 assert(B.getFieldDesc()->isPrimitiveArray()); 178 179 unsigned IndexA = A.getIndex(); 180 unsigned IndexB = B.getIndex(); 181 int32_t Result = 0; 182 for (;; ++IndexA, ++IndexB) { 183 const Pointer &PA = A.atIndex(IndexA); 184 const Pointer &PB = B.atIndex(IndexB); 185 if (!CheckRange(S, OpPC, PA, AK_Read) || 186 !CheckRange(S, OpPC, PB, AK_Read)) { 187 return false; 188 } 189 uint8_t CA = PA.deref<uint8_t>(); 190 uint8_t CB = PB.deref<uint8_t>(); 191 192 if (CA > CB) { 193 Result = 1; 194 break; 195 } else if (CA < CB) { 196 Result = -1; 197 break; 198 } 199 if (CA == 0 || CB == 0) 200 break; 201 } 202 203 pushInteger(S, Result, Call->getType()); 204 return true; 205 } 206 207 static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, 208 const InterpFrame *Frame, 209 const CallExpr *Call) { 210 const Pointer &StrPtr = getParam<Pointer>(Frame, 0); 211 212 if (!CheckArray(S, OpPC, StrPtr)) 213 return false; 214 215 if (!CheckLive(S, OpPC, StrPtr, AK_Read)) 216 return false; 217 218 if (!CheckDummy(S, OpPC, StrPtr, AK_Read)) 219 return false; 220 221 assert(StrPtr.getFieldDesc()->isPrimitiveArray()); 222 223 size_t Len = 0; 224 for (size_t I = StrPtr.getIndex();; ++I, ++Len) { 225 const Pointer &ElemPtr = StrPtr.atIndex(I); 226 227 if (!CheckRange(S, OpPC, ElemPtr, AK_Read)) 228 return false; 229 230 uint8_t Val = ElemPtr.deref<uint8_t>(); 231 if (Val == 0) 232 break; 233 } 234 235 pushInteger(S, Len, Call->getType()); 236 237 return true; 238 } 239 240 static bool interp__builtin_nan(InterpState &S, CodePtr OpPC, 241 const InterpFrame *Frame, const Function *F, 242 bool Signaling) { 243 const Pointer &Arg = getParam<Pointer>(Frame, 0); 244 245 if (!CheckLoad(S, OpPC, Arg)) 246 return false; 247 248 assert(Arg.getFieldDesc()->isPrimitiveArray()); 249 250 // Convert the given string to an integer using StringRef's API. 251 llvm::APInt Fill; 252 std::string Str; 253 assert(Arg.getNumElems() >= 1); 254 for (unsigned I = 0;; ++I) { 255 const Pointer &Elem = Arg.atIndex(I); 256 257 if (!CheckLoad(S, OpPC, Elem)) 258 return false; 259 260 if (Elem.deref<int8_t>() == 0) 261 break; 262 263 Str += Elem.deref<char>(); 264 } 265 266 // Treat empty strings as if they were zero. 267 if (Str.empty()) 268 Fill = llvm::APInt(32, 0); 269 else if (StringRef(Str).getAsInteger(0, Fill)) 270 return false; 271 272 const llvm::fltSemantics &TargetSemantics = 273 S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType()); 274 275 Floating Result; 276 if (S.getCtx().getTargetInfo().isNan2008()) { 277 if (Signaling) 278 Result = Floating( 279 llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); 280 else 281 Result = Floating( 282 llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); 283 } else { 284 // Prior to IEEE 754-2008, architectures were allowed to choose whether 285 // the first bit of their significand was set for qNaN or sNaN. MIPS chose 286 // a different encoding to what became a standard in 2008, and for pre- 287 // 2008 revisions, MIPS interpreted sNaN-2008 as qNan and qNaN-2008 as 288 // sNaN. This is now known as "legacy NaN" encoding. 289 if (Signaling) 290 Result = Floating( 291 llvm::APFloat::getQNaN(TargetSemantics, /*Negative=*/false, &Fill)); 292 else 293 Result = Floating( 294 llvm::APFloat::getSNaN(TargetSemantics, /*Negative=*/false, &Fill)); 295 } 296 297 S.Stk.push<Floating>(Result); 298 return true; 299 } 300 301 static bool interp__builtin_inf(InterpState &S, CodePtr OpPC, 302 const InterpFrame *Frame, const Function *F) { 303 const llvm::fltSemantics &TargetSemantics = 304 S.getCtx().getFloatTypeSemantics(F->getDecl()->getReturnType()); 305 306 S.Stk.push<Floating>(Floating::getInf(TargetSemantics)); 307 return true; 308 } 309 310 static bool interp__builtin_copysign(InterpState &S, CodePtr OpPC, 311 const InterpFrame *Frame, 312 const Function *F) { 313 const Floating &Arg1 = getParam<Floating>(Frame, 0); 314 const Floating &Arg2 = getParam<Floating>(Frame, 1); 315 316 APFloat Copy = Arg1.getAPFloat(); 317 Copy.copySign(Arg2.getAPFloat()); 318 S.Stk.push<Floating>(Floating(Copy)); 319 320 return true; 321 } 322 323 static bool interp__builtin_fmin(InterpState &S, CodePtr OpPC, 324 const InterpFrame *Frame, const Function *F) { 325 const Floating &LHS = getParam<Floating>(Frame, 0); 326 const Floating &RHS = getParam<Floating>(Frame, 1); 327 328 Floating Result; 329 330 // When comparing zeroes, return -0.0 if one of the zeroes is negative. 331 if (LHS.isZero() && RHS.isZero() && RHS.isNegative()) 332 Result = RHS; 333 else if (LHS.isNan() || RHS < LHS) 334 Result = RHS; 335 else 336 Result = LHS; 337 338 S.Stk.push<Floating>(Result); 339 return true; 340 } 341 342 static bool interp__builtin_fmax(InterpState &S, CodePtr OpPC, 343 const InterpFrame *Frame, 344 const Function *Func) { 345 const Floating &LHS = getParam<Floating>(Frame, 0); 346 const Floating &RHS = getParam<Floating>(Frame, 1); 347 348 Floating Result; 349 350 // When comparing zeroes, return +0.0 if one of the zeroes is positive. 351 if (LHS.isZero() && RHS.isZero() && LHS.isNegative()) 352 Result = RHS; 353 else if (LHS.isNan() || RHS > LHS) 354 Result = RHS; 355 else 356 Result = LHS; 357 358 S.Stk.push<Floating>(Result); 359 return true; 360 } 361 362 /// Defined as __builtin_isnan(...), to accommodate the fact that it can 363 /// take a float, double, long double, etc. 364 /// But for us, that's all a Floating anyway. 365 static bool interp__builtin_isnan(InterpState &S, CodePtr OpPC, 366 const InterpFrame *Frame, const Function *F, 367 const CallExpr *Call) { 368 const Floating &Arg = S.Stk.peek<Floating>(); 369 370 pushInteger(S, Arg.isNan(), Call->getType()); 371 return true; 372 } 373 374 static bool interp__builtin_issignaling(InterpState &S, CodePtr OpPC, 375 const InterpFrame *Frame, 376 const Function *F, 377 const CallExpr *Call) { 378 const Floating &Arg = S.Stk.peek<Floating>(); 379 380 pushInteger(S, Arg.isSignaling(), Call->getType()); 381 return true; 382 } 383 384 static bool interp__builtin_isinf(InterpState &S, CodePtr OpPC, 385 const InterpFrame *Frame, const Function *F, 386 bool CheckSign, const CallExpr *Call) { 387 const Floating &Arg = S.Stk.peek<Floating>(); 388 bool IsInf = Arg.isInf(); 389 390 if (CheckSign) 391 pushInteger(S, IsInf ? (Arg.isNegative() ? -1 : 1) : 0, Call->getType()); 392 else 393 pushInteger(S, Arg.isInf(), Call->getType()); 394 return true; 395 } 396 397 static bool interp__builtin_isfinite(InterpState &S, CodePtr OpPC, 398 const InterpFrame *Frame, 399 const Function *F, const CallExpr *Call) { 400 const Floating &Arg = S.Stk.peek<Floating>(); 401 402 pushInteger(S, Arg.isFinite(), Call->getType()); 403 return true; 404 } 405 406 static bool interp__builtin_isnormal(InterpState &S, CodePtr OpPC, 407 const InterpFrame *Frame, 408 const Function *F, const CallExpr *Call) { 409 const Floating &Arg = S.Stk.peek<Floating>(); 410 411 pushInteger(S, Arg.isNormal(), Call->getType()); 412 return true; 413 } 414 415 static bool interp__builtin_issubnormal(InterpState &S, CodePtr OpPC, 416 const InterpFrame *Frame, 417 const Function *F, 418 const CallExpr *Call) { 419 const Floating &Arg = S.Stk.peek<Floating>(); 420 421 pushInteger(S, Arg.isDenormal(), Call->getType()); 422 return true; 423 } 424 425 static bool interp__builtin_iszero(InterpState &S, CodePtr OpPC, 426 const InterpFrame *Frame, const Function *F, 427 const CallExpr *Call) { 428 const Floating &Arg = S.Stk.peek<Floating>(); 429 430 pushInteger(S, Arg.isZero(), Call->getType()); 431 return true; 432 } 433 434 /// First parameter to __builtin_isfpclass is the floating value, the 435 /// second one is an integral value. 436 static bool interp__builtin_isfpclass(InterpState &S, CodePtr OpPC, 437 const InterpFrame *Frame, 438 const Function *Func, 439 const CallExpr *Call) { 440 PrimType FPClassArgT = *S.getContext().classify(Call->getArg(1)->getType()); 441 APSInt FPClassArg = peekToAPSInt(S.Stk, FPClassArgT); 442 const Floating &F = 443 S.Stk.peek<Floating>(align(primSize(FPClassArgT) + primSize(PT_Float))); 444 445 int32_t Result = 446 static_cast<int32_t>((F.classify() & FPClassArg).getZExtValue()); 447 pushInteger(S, Result, Call->getType()); 448 449 return true; 450 } 451 452 /// Five int values followed by one floating value. 453 static bool interp__builtin_fpclassify(InterpState &S, CodePtr OpPC, 454 const InterpFrame *Frame, 455 const Function *Func, 456 const CallExpr *Call) { 457 const Floating &Val = S.Stk.peek<Floating>(); 458 459 unsigned Index; 460 switch (Val.getCategory()) { 461 case APFloat::fcNaN: 462 Index = 0; 463 break; 464 case APFloat::fcInfinity: 465 Index = 1; 466 break; 467 case APFloat::fcNormal: 468 Index = Val.isDenormal() ? 3 : 2; 469 break; 470 case APFloat::fcZero: 471 Index = 4; 472 break; 473 } 474 475 // The last argument is first on the stack. 476 assert(Index <= 4); 477 unsigned IntSize = primSize(getIntPrimType(S)); 478 unsigned Offset = 479 align(primSize(PT_Float)) + ((1 + (4 - Index)) * align(IntSize)); 480 481 APSInt I = peekToAPSInt(S.Stk, getIntPrimType(S), Offset); 482 pushInteger(S, I, Call->getType()); 483 return true; 484 } 485 486 // The C standard says "fabs raises no floating-point exceptions, 487 // even if x is a signaling NaN. The returned value is independent of 488 // the current rounding direction mode." Therefore constant folding can 489 // proceed without regard to the floating point settings. 490 // Reference, WG14 N2478 F.10.4.3 491 static bool interp__builtin_fabs(InterpState &S, CodePtr OpPC, 492 const InterpFrame *Frame, 493 const Function *Func) { 494 const Floating &Val = getParam<Floating>(Frame, 0); 495 496 S.Stk.push<Floating>(Floating::abs(Val)); 497 return true; 498 } 499 500 static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC, 501 const InterpFrame *Frame, 502 const Function *Func, 503 const CallExpr *Call) { 504 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 505 APSInt Val = peekToAPSInt(S.Stk, ArgT); 506 pushInteger(S, Val.popcount(), Call->getType()); 507 return true; 508 } 509 510 static bool interp__builtin_parity(InterpState &S, CodePtr OpPC, 511 const InterpFrame *Frame, 512 const Function *Func, const CallExpr *Call) { 513 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 514 APSInt Val = peekToAPSInt(S.Stk, ArgT); 515 pushInteger(S, Val.popcount() % 2, Call->getType()); 516 return true; 517 } 518 519 static bool interp__builtin_clrsb(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 pushInteger(S, Val.getBitWidth() - Val.getSignificantBits(), Call->getType()); 525 return true; 526 } 527 528 static bool interp__builtin_bitreverse(InterpState &S, CodePtr OpPC, 529 const InterpFrame *Frame, 530 const Function *Func, 531 const CallExpr *Call) { 532 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 533 APSInt Val = peekToAPSInt(S.Stk, ArgT); 534 pushInteger(S, Val.reverseBits(), Call->getType()); 535 return true; 536 } 537 538 static bool interp__builtin_classify_type(InterpState &S, CodePtr OpPC, 539 const InterpFrame *Frame, 540 const Function *Func, 541 const CallExpr *Call) { 542 // This is an unevaluated call, so there are no arguments on the stack. 543 assert(Call->getNumArgs() == 1); 544 const Expr *Arg = Call->getArg(0); 545 546 GCCTypeClass ResultClass = 547 EvaluateBuiltinClassifyType(Arg->getType(), S.getLangOpts()); 548 int32_t ReturnVal = static_cast<int32_t>(ResultClass); 549 pushInteger(S, ReturnVal, Call->getType()); 550 return true; 551 } 552 553 // __builtin_expect(long, long) 554 // __builtin_expect_with_probability(long, long, double) 555 static bool interp__builtin_expect(InterpState &S, CodePtr OpPC, 556 const InterpFrame *Frame, 557 const Function *Func, const CallExpr *Call) { 558 // The return value is simply the value of the first parameter. 559 // We ignore the probability. 560 unsigned NumArgs = Call->getNumArgs(); 561 assert(NumArgs == 2 || NumArgs == 3); 562 563 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 564 unsigned Offset = align(primSize(getLongPrimType(S))) * 2; 565 if (NumArgs == 3) 566 Offset += align(primSize(PT_Float)); 567 568 APSInt Val = peekToAPSInt(S.Stk, ArgT, Offset); 569 pushInteger(S, Val, Call->getType()); 570 return true; 571 } 572 573 /// rotateleft(value, amount) 574 static bool interp__builtin_rotate(InterpState &S, CodePtr OpPC, 575 const InterpFrame *Frame, 576 const Function *Func, const CallExpr *Call, 577 bool Right) { 578 PrimType AmountT = *S.getContext().classify(Call->getArg(1)->getType()); 579 PrimType ValueT = *S.getContext().classify(Call->getArg(0)->getType()); 580 581 APSInt Amount = peekToAPSInt(S.Stk, AmountT); 582 APSInt Value = peekToAPSInt( 583 S.Stk, ValueT, align(primSize(AmountT)) + align(primSize(ValueT))); 584 585 APSInt Result; 586 if (Right) 587 Result = APSInt(Value.rotr(Amount.urem(Value.getBitWidth())), 588 /*IsUnsigned=*/true); 589 else // Left. 590 Result = APSInt(Value.rotl(Amount.urem(Value.getBitWidth())), 591 /*IsUnsigned=*/true); 592 593 pushInteger(S, Result, Call->getType()); 594 return true; 595 } 596 597 static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC, 598 const InterpFrame *Frame, const Function *Func, 599 const CallExpr *Call) { 600 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 601 APSInt Value = peekToAPSInt(S.Stk, ArgT); 602 603 uint64_t N = Value.countr_zero(); 604 pushInteger(S, N == Value.getBitWidth() ? 0 : N + 1, Call->getType()); 605 return true; 606 } 607 608 static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC, 609 const InterpFrame *Frame, 610 const Function *Func, 611 const CallExpr *Call) { 612 assert(Call->getArg(0)->isLValue()); 613 PrimType PtrT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr); 614 615 if (PtrT == PT_FnPtr) { 616 const FunctionPointer &Arg = S.Stk.peek<FunctionPointer>(); 617 S.Stk.push<FunctionPointer>(Arg); 618 } else if (PtrT == PT_Ptr) { 619 const Pointer &Arg = S.Stk.peek<Pointer>(); 620 S.Stk.push<Pointer>(Arg); 621 } else { 622 assert(false && "Unsupported pointer type passed to __builtin_addressof()"); 623 } 624 return true; 625 } 626 627 static bool interp__builtin_move(InterpState &S, CodePtr OpPC, 628 const InterpFrame *Frame, const Function *Func, 629 const CallExpr *Call) { 630 631 PrimType ArgT = S.getContext().classify(Call->getArg(0)).value_or(PT_Ptr); 632 633 TYPE_SWITCH(ArgT, const T &Arg = S.Stk.peek<T>(); S.Stk.push<T>(Arg);); 634 635 return Func->getDecl()->isConstexpr(); 636 } 637 638 static bool interp__builtin_eh_return_data_regno(InterpState &S, CodePtr OpPC, 639 const InterpFrame *Frame, 640 const Function *Func, 641 const CallExpr *Call) { 642 PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType()); 643 APSInt Arg = peekToAPSInt(S.Stk, ArgT); 644 645 int Result = 646 S.getCtx().getTargetInfo().getEHDataRegisterNumber(Arg.getZExtValue()); 647 pushInteger(S, Result, Call->getType()); 648 return true; 649 } 650 651 /// Just takes the first Argument to the call and puts it on the stack. 652 static bool noopPointer(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, 653 const Function *Func, const CallExpr *Call) { 654 const Pointer &Arg = S.Stk.peek<Pointer>(); 655 S.Stk.push<Pointer>(Arg); 656 return true; 657 } 658 659 // Two integral values followed by a pointer (lhs, rhs, resultOut) 660 static bool interp__builtin_overflowop(InterpState &S, CodePtr OpPC, 661 const InterpFrame *Frame, 662 const Function *Func, 663 const CallExpr *Call) { 664 Pointer &ResultPtr = S.Stk.peek<Pointer>(); 665 if (ResultPtr.isDummy()) 666 return false; 667 668 unsigned BuiltinOp = Func->getBuiltinID(); 669 PrimType RHST = *S.getContext().classify(Call->getArg(1)->getType()); 670 PrimType LHST = *S.getContext().classify(Call->getArg(0)->getType()); 671 APSInt RHS = peekToAPSInt(S.Stk, RHST, 672 align(primSize(PT_Ptr)) + align(primSize(RHST))); 673 APSInt LHS = peekToAPSInt(S.Stk, LHST, 674 align(primSize(PT_Ptr)) + align(primSize(RHST)) + 675 align(primSize(LHST))); 676 QualType ResultType = Call->getArg(2)->getType()->getPointeeType(); 677 PrimType ResultT = *S.getContext().classify(ResultType); 678 bool Overflow; 679 680 APSInt Result; 681 if (BuiltinOp == Builtin::BI__builtin_add_overflow || 682 BuiltinOp == Builtin::BI__builtin_sub_overflow || 683 BuiltinOp == Builtin::BI__builtin_mul_overflow) { 684 bool IsSigned = LHS.isSigned() || RHS.isSigned() || 685 ResultType->isSignedIntegerOrEnumerationType(); 686 bool AllSigned = LHS.isSigned() && RHS.isSigned() && 687 ResultType->isSignedIntegerOrEnumerationType(); 688 uint64_t LHSSize = LHS.getBitWidth(); 689 uint64_t RHSSize = RHS.getBitWidth(); 690 uint64_t ResultSize = S.getCtx().getTypeSize(ResultType); 691 uint64_t MaxBits = std::max(std::max(LHSSize, RHSSize), ResultSize); 692 693 // Add an additional bit if the signedness isn't uniformly agreed to. We 694 // could do this ONLY if there is a signed and an unsigned that both have 695 // MaxBits, but the code to check that is pretty nasty. The issue will be 696 // caught in the shrink-to-result later anyway. 697 if (IsSigned && !AllSigned) 698 ++MaxBits; 699 700 LHS = APSInt(LHS.extOrTrunc(MaxBits), !IsSigned); 701 RHS = APSInt(RHS.extOrTrunc(MaxBits), !IsSigned); 702 Result = APSInt(MaxBits, !IsSigned); 703 } 704 705 // Find largest int. 706 switch (BuiltinOp) { 707 default: 708 llvm_unreachable("Invalid value for BuiltinOp"); 709 case Builtin::BI__builtin_add_overflow: 710 case Builtin::BI__builtin_sadd_overflow: 711 case Builtin::BI__builtin_saddl_overflow: 712 case Builtin::BI__builtin_saddll_overflow: 713 case Builtin::BI__builtin_uadd_overflow: 714 case Builtin::BI__builtin_uaddl_overflow: 715 case Builtin::BI__builtin_uaddll_overflow: 716 Result = LHS.isSigned() ? LHS.sadd_ov(RHS, Overflow) 717 : LHS.uadd_ov(RHS, Overflow); 718 break; 719 case Builtin::BI__builtin_sub_overflow: 720 case Builtin::BI__builtin_ssub_overflow: 721 case Builtin::BI__builtin_ssubl_overflow: 722 case Builtin::BI__builtin_ssubll_overflow: 723 case Builtin::BI__builtin_usub_overflow: 724 case Builtin::BI__builtin_usubl_overflow: 725 case Builtin::BI__builtin_usubll_overflow: 726 Result = LHS.isSigned() ? LHS.ssub_ov(RHS, Overflow) 727 : LHS.usub_ov(RHS, Overflow); 728 break; 729 case Builtin::BI__builtin_mul_overflow: 730 case Builtin::BI__builtin_smul_overflow: 731 case Builtin::BI__builtin_smull_overflow: 732 case Builtin::BI__builtin_smulll_overflow: 733 case Builtin::BI__builtin_umul_overflow: 734 case Builtin::BI__builtin_umull_overflow: 735 case Builtin::BI__builtin_umulll_overflow: 736 Result = LHS.isSigned() ? LHS.smul_ov(RHS, Overflow) 737 : LHS.umul_ov(RHS, Overflow); 738 break; 739 } 740 741 // In the case where multiple sizes are allowed, truncate and see if 742 // the values are the same. 743 if (BuiltinOp == Builtin::BI__builtin_add_overflow || 744 BuiltinOp == Builtin::BI__builtin_sub_overflow || 745 BuiltinOp == Builtin::BI__builtin_mul_overflow) { 746 // APSInt doesn't have a TruncOrSelf, so we use extOrTrunc instead, 747 // since it will give us the behavior of a TruncOrSelf in the case where 748 // its parameter <= its size. We previously set Result to be at least the 749 // type-size of the result, so getTypeSize(ResultType) <= Resu 750 APSInt Temp = Result.extOrTrunc(S.getCtx().getTypeSize(ResultType)); 751 Temp.setIsSigned(ResultType->isSignedIntegerOrEnumerationType()); 752 753 if (!APSInt::isSameValue(Temp, Result)) 754 Overflow = true; 755 Result = Temp; 756 } 757 758 // Write Result to ResultPtr and put Overflow on the stacl. 759 assignInteger(ResultPtr, ResultT, Result); 760 ResultPtr.initialize(); 761 assert(Func->getDecl()->getReturnType()->isBooleanType()); 762 S.Stk.push<Boolean>(Overflow); 763 return true; 764 } 765 766 /// Three integral values followed by a pointer (lhs, rhs, carry, carryOut). 767 static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, 768 const InterpFrame *Frame, 769 const Function *Func, 770 const CallExpr *Call) { 771 unsigned BuiltinOp = Func->getBuiltinID(); 772 PrimType LHST = *S.getContext().classify(Call->getArg(0)->getType()); 773 PrimType RHST = *S.getContext().classify(Call->getArg(1)->getType()); 774 PrimType CarryT = *S.getContext().classify(Call->getArg(2)->getType()); 775 APSInt RHS = peekToAPSInt(S.Stk, RHST, 776 align(primSize(PT_Ptr)) + align(primSize(CarryT)) + 777 align(primSize(RHST))); 778 APSInt LHS = 779 peekToAPSInt(S.Stk, LHST, 780 align(primSize(PT_Ptr)) + align(primSize(RHST)) + 781 align(primSize(CarryT)) + align(primSize(LHST))); 782 APSInt CarryIn = peekToAPSInt( 783 S.Stk, LHST, align(primSize(PT_Ptr)) + align(primSize(CarryT))); 784 APSInt CarryOut; 785 786 APSInt Result; 787 // Copy the number of bits and sign. 788 Result = LHS; 789 CarryOut = LHS; 790 791 bool FirstOverflowed = false; 792 bool SecondOverflowed = false; 793 switch (BuiltinOp) { 794 default: 795 llvm_unreachable("Invalid value for BuiltinOp"); 796 case Builtin::BI__builtin_addcb: 797 case Builtin::BI__builtin_addcs: 798 case Builtin::BI__builtin_addc: 799 case Builtin::BI__builtin_addcl: 800 case Builtin::BI__builtin_addcll: 801 Result = 802 LHS.uadd_ov(RHS, FirstOverflowed).uadd_ov(CarryIn, SecondOverflowed); 803 break; 804 case Builtin::BI__builtin_subcb: 805 case Builtin::BI__builtin_subcs: 806 case Builtin::BI__builtin_subc: 807 case Builtin::BI__builtin_subcl: 808 case Builtin::BI__builtin_subcll: 809 Result = 810 LHS.usub_ov(RHS, FirstOverflowed).usub_ov(CarryIn, SecondOverflowed); 811 break; 812 } 813 // It is possible for both overflows to happen but CGBuiltin uses an OR so 814 // this is consistent. 815 CarryOut = (uint64_t)(FirstOverflowed | SecondOverflowed); 816 817 Pointer &CarryOutPtr = S.Stk.peek<Pointer>(); 818 QualType CarryOutType = Call->getArg(3)->getType()->getPointeeType(); 819 PrimType CarryOutT = *S.getContext().classify(CarryOutType); 820 assignInteger(CarryOutPtr, CarryOutT, CarryOut); 821 CarryOutPtr.initialize(); 822 823 assert(Call->getType() == Call->getArg(0)->getType()); 824 pushInteger(S, Result, Call->getType()); 825 return true; 826 } 827 828 static bool interp__builtin_clz(InterpState &S, CodePtr OpPC, 829 const InterpFrame *Frame, const Function *Func, 830 const CallExpr *Call) { 831 unsigned CallSize = callArgSize(S, Call); 832 unsigned BuiltinOp = Func->getBuiltinID(); 833 PrimType ValT = *S.getContext().classify(Call->getArg(0)); 834 const APSInt &Val = peekToAPSInt(S.Stk, ValT, CallSize); 835 836 // When the argument is 0, the result of GCC builtins is undefined, whereas 837 // for Microsoft intrinsics, the result is the bit-width of the argument. 838 bool ZeroIsUndefined = BuiltinOp != Builtin::BI__lzcnt16 && 839 BuiltinOp != Builtin::BI__lzcnt && 840 BuiltinOp != Builtin::BI__lzcnt64; 841 842 if (Val == 0) { 843 if (Func->getBuiltinID() == Builtin::BI__builtin_clzg && 844 Call->getNumArgs() == 2) { 845 // We have a fallback parameter. 846 PrimType FallbackT = *S.getContext().classify(Call->getArg(1)); 847 const APSInt &Fallback = peekToAPSInt(S.Stk, FallbackT); 848 pushInteger(S, Fallback, Call->getType()); 849 return true; 850 } 851 852 if (ZeroIsUndefined) 853 return false; 854 } 855 856 pushInteger(S, Val.countl_zero(), Call->getType()); 857 return true; 858 } 859 860 static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC, 861 const InterpFrame *Frame, const Function *Func, 862 const CallExpr *Call) { 863 unsigned CallSize = callArgSize(S, Call); 864 PrimType ValT = *S.getContext().classify(Call->getArg(0)); 865 const APSInt &Val = peekToAPSInt(S.Stk, ValT, CallSize); 866 867 if (Val == 0) { 868 if (Func->getBuiltinID() == Builtin::BI__builtin_ctzg && 869 Call->getNumArgs() == 2) { 870 // We have a fallback parameter. 871 PrimType FallbackT = *S.getContext().classify(Call->getArg(1)); 872 const APSInt &Fallback = peekToAPSInt(S.Stk, FallbackT); 873 pushInteger(S, Fallback, Call->getType()); 874 return true; 875 } 876 return false; 877 } 878 879 pushInteger(S, Val.countr_zero(), Call->getType()); 880 return true; 881 } 882 883 static bool interp__builtin_bswap(InterpState &S, CodePtr OpPC, 884 const InterpFrame *Frame, 885 const Function *Func, const CallExpr *Call) { 886 PrimType ReturnT = *S.getContext().classify(Call->getType()); 887 PrimType ValT = *S.getContext().classify(Call->getArg(0)); 888 const APSInt &Val = peekToAPSInt(S.Stk, ValT); 889 assert(Val.getActiveBits() <= 64); 890 891 INT_TYPE_SWITCH(ReturnT, 892 { S.Stk.push<T>(T::from(Val.byteSwap().getZExtValue())); }); 893 return true; 894 } 895 896 /// bool __atomic_always_lock_free(size_t, void const volatile*) 897 /// bool __atomic_is_lock_free(size_t, void const volatile*) 898 /// bool __c11_atomic_is_lock_free(size_t) 899 static bool interp__builtin_atomic_lock_free(InterpState &S, CodePtr OpPC, 900 const InterpFrame *Frame, 901 const Function *Func, 902 const CallExpr *Call) { 903 unsigned BuiltinOp = Func->getBuiltinID(); 904 905 PrimType ValT = *S.getContext().classify(Call->getArg(0)); 906 unsigned SizeValOffset = 0; 907 if (BuiltinOp != Builtin::BI__c11_atomic_is_lock_free) 908 SizeValOffset = align(primSize(ValT)) + align(primSize(PT_Ptr)); 909 const APSInt &SizeVal = peekToAPSInt(S.Stk, ValT, SizeValOffset); 910 911 auto returnBool = [&S](bool Value) -> bool { 912 S.Stk.push<Boolean>(Value); 913 return true; 914 }; 915 916 // For __atomic_is_lock_free(sizeof(_Atomic(T))), if the size is a power 917 // of two less than or equal to the maximum inline atomic width, we know it 918 // is lock-free. If the size isn't a power of two, or greater than the 919 // maximum alignment where we promote atomics, we know it is not lock-free 920 // (at least not in the sense of atomic_is_lock_free). Otherwise, 921 // the answer can only be determined at runtime; for example, 16-byte 922 // atomics have lock-free implementations on some, but not all, 923 // x86-64 processors. 924 925 // Check power-of-two. 926 CharUnits Size = CharUnits::fromQuantity(SizeVal.getZExtValue()); 927 if (Size.isPowerOfTwo()) { 928 // Check against inlining width. 929 unsigned InlineWidthBits = 930 S.getCtx().getTargetInfo().getMaxAtomicInlineWidth(); 931 if (Size <= S.getCtx().toCharUnitsFromBits(InlineWidthBits)) { 932 933 // OK, we will inline appropriately-aligned operations of this size, 934 // and _Atomic(T) is appropriately-aligned. 935 if (BuiltinOp == Builtin::BI__c11_atomic_is_lock_free || 936 Size == CharUnits::One()) 937 return returnBool(true); 938 939 // Same for null pointers. 940 assert(BuiltinOp != Builtin::BI__c11_atomic_is_lock_free); 941 const Pointer &Ptr = S.Stk.peek<Pointer>(); 942 if (Ptr.isZero()) 943 return returnBool(true); 944 945 QualType PointeeType = Call->getArg(1) 946 ->IgnoreImpCasts() 947 ->getType() 948 ->castAs<PointerType>() 949 ->getPointeeType(); 950 // OK, we will inline operations on this object. 951 if (!PointeeType->isIncompleteType() && 952 S.getCtx().getTypeAlignInChars(PointeeType) >= Size) 953 return returnBool(true); 954 } 955 } 956 957 if (BuiltinOp == Builtin::BI__atomic_always_lock_free) 958 return returnBool(false); 959 960 return false; 961 } 962 963 /// __builtin_complex(Float A, float B); 964 static bool interp__builtin_complex(InterpState &S, CodePtr OpPC, 965 const InterpFrame *Frame, 966 const Function *Func, 967 const CallExpr *Call) { 968 const Floating &Arg2 = S.Stk.peek<Floating>(); 969 const Floating &Arg1 = S.Stk.peek<Floating>(align(primSize(PT_Float)) * 2); 970 Pointer &Result = S.Stk.peek<Pointer>(align(primSize(PT_Float)) * 2 + 971 align(primSize(PT_Ptr))); 972 973 Result.atIndex(0).deref<Floating>() = Arg1; 974 Result.atIndex(0).initialize(); 975 Result.atIndex(1).deref<Floating>() = Arg2; 976 Result.atIndex(1).initialize(); 977 Result.initialize(); 978 979 return true; 980 } 981 982 /// __builtin_is_aligned() 983 /// __builtin_align_up() 984 /// __builtin_align_down() 985 /// The first parameter is either an integer or a pointer. 986 /// The second parameter is the requested alignment as an integer. 987 static bool interp__builtin_is_aligned_up_down(InterpState &S, CodePtr OpPC, 988 const InterpFrame *Frame, 989 const Function *Func, 990 const CallExpr *Call) { 991 unsigned BuiltinOp = Func->getBuiltinID(); 992 unsigned CallSize = callArgSize(S, Call); 993 994 PrimType AlignmentT = *S.Ctx.classify(Call->getArg(1)); 995 const APSInt &Alignment = peekToAPSInt(S.Stk, AlignmentT); 996 997 if (Alignment < 0 || !Alignment.isPowerOf2()) { 998 S.FFDiag(Call, diag::note_constexpr_invalid_alignment) << Alignment; 999 return false; 1000 } 1001 unsigned SrcWidth = S.getCtx().getIntWidth(Call->getArg(0)->getType()); 1002 APSInt MaxValue(APInt::getOneBitSet(SrcWidth, SrcWidth - 1)); 1003 if (APSInt::compareValues(Alignment, MaxValue) > 0) { 1004 S.FFDiag(Call, diag::note_constexpr_alignment_too_big) 1005 << MaxValue << Call->getArg(0)->getType() << Alignment; 1006 return false; 1007 } 1008 1009 // The first parameter is either an integer or a pointer (but not a function 1010 // pointer). 1011 PrimType FirstArgT = *S.Ctx.classify(Call->getArg(0)); 1012 1013 if (isIntegralType(FirstArgT)) { 1014 const APSInt &Src = peekToAPSInt(S.Stk, FirstArgT, CallSize); 1015 APSInt Align = Alignment.extOrTrunc(Src.getBitWidth()); 1016 if (BuiltinOp == Builtin::BI__builtin_align_up) { 1017 APSInt AlignedVal = 1018 APSInt((Src + (Align - 1)) & ~(Align - 1), Src.isUnsigned()); 1019 pushInteger(S, AlignedVal, Call->getType()); 1020 } else if (BuiltinOp == Builtin::BI__builtin_align_down) { 1021 APSInt AlignedVal = APSInt(Src & ~(Align - 1), Src.isUnsigned()); 1022 pushInteger(S, AlignedVal, Call->getType()); 1023 } else { 1024 assert(*S.Ctx.classify(Call->getType()) == PT_Bool); 1025 S.Stk.push<Boolean>((Src & (Align - 1)) == 0); 1026 } 1027 return true; 1028 } 1029 1030 assert(FirstArgT == PT_Ptr); 1031 const Pointer &Ptr = S.Stk.peek<Pointer>(CallSize); 1032 1033 unsigned PtrOffset = Ptr.getByteOffset(); 1034 PtrOffset = Ptr.getIndex(); 1035 CharUnits BaseAlignment = 1036 S.getCtx().getDeclAlign(Ptr.getDeclDesc()->asValueDecl()); 1037 CharUnits PtrAlign = 1038 BaseAlignment.alignmentAtOffset(CharUnits::fromQuantity(PtrOffset)); 1039 1040 if (BuiltinOp == Builtin::BI__builtin_is_aligned) { 1041 if (PtrAlign.getQuantity() >= Alignment) { 1042 S.Stk.push<Boolean>(true); 1043 return true; 1044 } 1045 // If the alignment is not known to be sufficient, some cases could still 1046 // be aligned at run time. However, if the requested alignment is less or 1047 // equal to the base alignment and the offset is not aligned, we know that 1048 // the run-time value can never be aligned. 1049 if (BaseAlignment.getQuantity() >= Alignment && 1050 PtrAlign.getQuantity() < Alignment) { 1051 S.Stk.push<Boolean>(false); 1052 return true; 1053 } 1054 1055 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_compute) 1056 << Alignment; 1057 return false; 1058 } 1059 1060 assert(BuiltinOp == Builtin::BI__builtin_align_down || 1061 BuiltinOp == Builtin::BI__builtin_align_up); 1062 1063 // For align_up/align_down, we can return the same value if the alignment 1064 // is known to be greater or equal to the requested value. 1065 if (PtrAlign.getQuantity() >= Alignment) { 1066 S.Stk.push<Pointer>(Ptr); 1067 return true; 1068 } 1069 1070 // The alignment could be greater than the minimum at run-time, so we cannot 1071 // infer much about the resulting pointer value. One case is possible: 1072 // For `_Alignas(32) char buf[N]; __builtin_align_down(&buf[idx], 32)` we 1073 // can infer the correct index if the requested alignment is smaller than 1074 // the base alignment so we can perform the computation on the offset. 1075 if (BaseAlignment.getQuantity() >= Alignment) { 1076 assert(Alignment.getBitWidth() <= 64 && 1077 "Cannot handle > 64-bit address-space"); 1078 uint64_t Alignment64 = Alignment.getZExtValue(); 1079 CharUnits NewOffset = 1080 CharUnits::fromQuantity(BuiltinOp == Builtin::BI__builtin_align_down 1081 ? llvm::alignDown(PtrOffset, Alignment64) 1082 : llvm::alignTo(PtrOffset, Alignment64)); 1083 1084 S.Stk.push<Pointer>(Ptr.atIndex(NewOffset.getQuantity())); 1085 return true; 1086 } 1087 1088 // Otherwise, we cannot constant-evaluate the result. 1089 S.FFDiag(Call->getArg(0), diag::note_constexpr_alignment_adjust) << Alignment; 1090 return false; 1091 } 1092 1093 static bool interp__builtin_os_log_format_buffer_size(InterpState &S, 1094 CodePtr OpPC, 1095 const InterpFrame *Frame, 1096 const Function *Func, 1097 const CallExpr *Call) { 1098 analyze_os_log::OSLogBufferLayout Layout; 1099 analyze_os_log::computeOSLogBufferLayout(S.getCtx(), Call, Layout); 1100 pushInteger(S, Layout.size().getQuantity(), Call->getType()); 1101 return true; 1102 } 1103 1104 static bool interp__builtin_ptrauth_string_discriminator( 1105 InterpState &S, CodePtr OpPC, const InterpFrame *Frame, 1106 const Function *Func, const CallExpr *Call) { 1107 const auto &Ptr = S.Stk.peek<Pointer>(); 1108 assert(Ptr.getFieldDesc()->isPrimitiveArray()); 1109 1110 StringRef R(&Ptr.deref<char>(), Ptr.getFieldDesc()->getNumElems() - 1); 1111 uint64_t Result = getPointerAuthStableSipHash(R); 1112 pushInteger(S, Result, Call->getType()); 1113 return true; 1114 } 1115 1116 bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, 1117 const CallExpr *Call) { 1118 const InterpFrame *Frame = S.Current; 1119 APValue Dummy; 1120 1121 std::optional<PrimType> ReturnT = S.getContext().classify(Call); 1122 1123 switch (F->getBuiltinID()) { 1124 case Builtin::BI__builtin_is_constant_evaluated: 1125 if (!interp__builtin_is_constant_evaluated(S, OpPC, Frame, Call)) 1126 return false; 1127 break; 1128 case Builtin::BI__builtin_assume: 1129 case Builtin::BI__assume: 1130 break; 1131 case Builtin::BI__builtin_strcmp: 1132 if (!interp__builtin_strcmp(S, OpPC, Frame, Call)) 1133 return false; 1134 break; 1135 case Builtin::BI__builtin_strlen: 1136 if (!interp__builtin_strlen(S, OpPC, Frame, Call)) 1137 return false; 1138 break; 1139 case Builtin::BI__builtin_nan: 1140 case Builtin::BI__builtin_nanf: 1141 case Builtin::BI__builtin_nanl: 1142 case Builtin::BI__builtin_nanf16: 1143 case Builtin::BI__builtin_nanf128: 1144 if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/false)) 1145 return false; 1146 break; 1147 case Builtin::BI__builtin_nans: 1148 case Builtin::BI__builtin_nansf: 1149 case Builtin::BI__builtin_nansl: 1150 case Builtin::BI__builtin_nansf16: 1151 case Builtin::BI__builtin_nansf128: 1152 if (!interp__builtin_nan(S, OpPC, Frame, F, /*Signaling=*/true)) 1153 return false; 1154 break; 1155 1156 case Builtin::BI__builtin_huge_val: 1157 case Builtin::BI__builtin_huge_valf: 1158 case Builtin::BI__builtin_huge_vall: 1159 case Builtin::BI__builtin_huge_valf16: 1160 case Builtin::BI__builtin_huge_valf128: 1161 case Builtin::BI__builtin_inf: 1162 case Builtin::BI__builtin_inff: 1163 case Builtin::BI__builtin_infl: 1164 case Builtin::BI__builtin_inff16: 1165 case Builtin::BI__builtin_inff128: 1166 if (!interp__builtin_inf(S, OpPC, Frame, F)) 1167 return false; 1168 break; 1169 case Builtin::BI__builtin_copysign: 1170 case Builtin::BI__builtin_copysignf: 1171 case Builtin::BI__builtin_copysignl: 1172 case Builtin::BI__builtin_copysignf128: 1173 if (!interp__builtin_copysign(S, OpPC, Frame, F)) 1174 return false; 1175 break; 1176 1177 case Builtin::BI__builtin_fmin: 1178 case Builtin::BI__builtin_fminf: 1179 case Builtin::BI__builtin_fminl: 1180 case Builtin::BI__builtin_fminf16: 1181 case Builtin::BI__builtin_fminf128: 1182 if (!interp__builtin_fmin(S, OpPC, Frame, F)) 1183 return false; 1184 break; 1185 1186 case Builtin::BI__builtin_fmax: 1187 case Builtin::BI__builtin_fmaxf: 1188 case Builtin::BI__builtin_fmaxl: 1189 case Builtin::BI__builtin_fmaxf16: 1190 case Builtin::BI__builtin_fmaxf128: 1191 if (!interp__builtin_fmax(S, OpPC, Frame, F)) 1192 return false; 1193 break; 1194 1195 case Builtin::BI__builtin_isnan: 1196 if (!interp__builtin_isnan(S, OpPC, Frame, F, Call)) 1197 return false; 1198 break; 1199 case Builtin::BI__builtin_issignaling: 1200 if (!interp__builtin_issignaling(S, OpPC, Frame, F, Call)) 1201 return false; 1202 break; 1203 1204 case Builtin::BI__builtin_isinf: 1205 if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/false, Call)) 1206 return false; 1207 break; 1208 1209 case Builtin::BI__builtin_isinf_sign: 1210 if (!interp__builtin_isinf(S, OpPC, Frame, F, /*Sign=*/true, Call)) 1211 return false; 1212 break; 1213 1214 case Builtin::BI__builtin_isfinite: 1215 if (!interp__builtin_isfinite(S, OpPC, Frame, F, Call)) 1216 return false; 1217 break; 1218 case Builtin::BI__builtin_isnormal: 1219 if (!interp__builtin_isnormal(S, OpPC, Frame, F, Call)) 1220 return false; 1221 break; 1222 case Builtin::BI__builtin_issubnormal: 1223 if (!interp__builtin_issubnormal(S, OpPC, Frame, F, Call)) 1224 return false; 1225 break; 1226 case Builtin::BI__builtin_iszero: 1227 if (!interp__builtin_iszero(S, OpPC, Frame, F, Call)) 1228 return false; 1229 break; 1230 case Builtin::BI__builtin_isfpclass: 1231 if (!interp__builtin_isfpclass(S, OpPC, Frame, F, Call)) 1232 return false; 1233 break; 1234 case Builtin::BI__builtin_fpclassify: 1235 if (!interp__builtin_fpclassify(S, OpPC, Frame, F, Call)) 1236 return false; 1237 break; 1238 1239 case Builtin::BI__builtin_fabs: 1240 case Builtin::BI__builtin_fabsf: 1241 case Builtin::BI__builtin_fabsl: 1242 case Builtin::BI__builtin_fabsf128: 1243 if (!interp__builtin_fabs(S, OpPC, Frame, F)) 1244 return false; 1245 break; 1246 1247 case Builtin::BI__builtin_popcount: 1248 case Builtin::BI__builtin_popcountl: 1249 case Builtin::BI__builtin_popcountll: 1250 case Builtin::BI__builtin_popcountg: 1251 case Builtin::BI__popcnt16: // Microsoft variants of popcount 1252 case Builtin::BI__popcnt: 1253 case Builtin::BI__popcnt64: 1254 if (!interp__builtin_popcount(S, OpPC, Frame, F, Call)) 1255 return false; 1256 break; 1257 1258 case Builtin::BI__builtin_parity: 1259 case Builtin::BI__builtin_parityl: 1260 case Builtin::BI__builtin_parityll: 1261 if (!interp__builtin_parity(S, OpPC, Frame, F, Call)) 1262 return false; 1263 break; 1264 1265 case Builtin::BI__builtin_clrsb: 1266 case Builtin::BI__builtin_clrsbl: 1267 case Builtin::BI__builtin_clrsbll: 1268 if (!interp__builtin_clrsb(S, OpPC, Frame, F, Call)) 1269 return false; 1270 break; 1271 1272 case Builtin::BI__builtin_bitreverse8: 1273 case Builtin::BI__builtin_bitreverse16: 1274 case Builtin::BI__builtin_bitreverse32: 1275 case Builtin::BI__builtin_bitreverse64: 1276 if (!interp__builtin_bitreverse(S, OpPC, Frame, F, Call)) 1277 return false; 1278 break; 1279 1280 case Builtin::BI__builtin_classify_type: 1281 if (!interp__builtin_classify_type(S, OpPC, Frame, F, Call)) 1282 return false; 1283 break; 1284 1285 case Builtin::BI__builtin_expect: 1286 case Builtin::BI__builtin_expect_with_probability: 1287 if (!interp__builtin_expect(S, OpPC, Frame, F, Call)) 1288 return false; 1289 break; 1290 1291 case Builtin::BI__builtin_rotateleft8: 1292 case Builtin::BI__builtin_rotateleft16: 1293 case Builtin::BI__builtin_rotateleft32: 1294 case Builtin::BI__builtin_rotateleft64: 1295 case Builtin::BI_rotl8: // Microsoft variants of rotate left 1296 case Builtin::BI_rotl16: 1297 case Builtin::BI_rotl: 1298 case Builtin::BI_lrotl: 1299 case Builtin::BI_rotl64: 1300 if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/false)) 1301 return false; 1302 break; 1303 1304 case Builtin::BI__builtin_rotateright8: 1305 case Builtin::BI__builtin_rotateright16: 1306 case Builtin::BI__builtin_rotateright32: 1307 case Builtin::BI__builtin_rotateright64: 1308 case Builtin::BI_rotr8: // Microsoft variants of rotate right 1309 case Builtin::BI_rotr16: 1310 case Builtin::BI_rotr: 1311 case Builtin::BI_lrotr: 1312 case Builtin::BI_rotr64: 1313 if (!interp__builtin_rotate(S, OpPC, Frame, F, Call, /*Right=*/true)) 1314 return false; 1315 break; 1316 1317 case Builtin::BI__builtin_ffs: 1318 case Builtin::BI__builtin_ffsl: 1319 case Builtin::BI__builtin_ffsll: 1320 if (!interp__builtin_ffs(S, OpPC, Frame, F, Call)) 1321 return false; 1322 break; 1323 case Builtin::BIaddressof: 1324 case Builtin::BI__addressof: 1325 case Builtin::BI__builtin_addressof: 1326 if (!interp__builtin_addressof(S, OpPC, Frame, F, Call)) 1327 return false; 1328 break; 1329 1330 case Builtin::BIas_const: 1331 case Builtin::BIforward: 1332 case Builtin::BIforward_like: 1333 case Builtin::BImove: 1334 case Builtin::BImove_if_noexcept: 1335 if (!interp__builtin_move(S, OpPC, Frame, F, Call)) 1336 return false; 1337 break; 1338 1339 case Builtin::BI__builtin_eh_return_data_regno: 1340 if (!interp__builtin_eh_return_data_regno(S, OpPC, Frame, F, Call)) 1341 return false; 1342 break; 1343 1344 case Builtin::BI__builtin_launder: 1345 if (!noopPointer(S, OpPC, Frame, F, Call)) 1346 return false; 1347 break; 1348 1349 case Builtin::BI__builtin_add_overflow: 1350 case Builtin::BI__builtin_sub_overflow: 1351 case Builtin::BI__builtin_mul_overflow: 1352 case Builtin::BI__builtin_sadd_overflow: 1353 case Builtin::BI__builtin_uadd_overflow: 1354 case Builtin::BI__builtin_uaddl_overflow: 1355 case Builtin::BI__builtin_uaddll_overflow: 1356 case Builtin::BI__builtin_usub_overflow: 1357 case Builtin::BI__builtin_usubl_overflow: 1358 case Builtin::BI__builtin_usubll_overflow: 1359 case Builtin::BI__builtin_umul_overflow: 1360 case Builtin::BI__builtin_umull_overflow: 1361 case Builtin::BI__builtin_umulll_overflow: 1362 case Builtin::BI__builtin_saddl_overflow: 1363 case Builtin::BI__builtin_saddll_overflow: 1364 case Builtin::BI__builtin_ssub_overflow: 1365 case Builtin::BI__builtin_ssubl_overflow: 1366 case Builtin::BI__builtin_ssubll_overflow: 1367 case Builtin::BI__builtin_smul_overflow: 1368 case Builtin::BI__builtin_smull_overflow: 1369 case Builtin::BI__builtin_smulll_overflow: 1370 if (!interp__builtin_overflowop(S, OpPC, Frame, F, Call)) 1371 return false; 1372 break; 1373 1374 case Builtin::BI__builtin_addcb: 1375 case Builtin::BI__builtin_addcs: 1376 case Builtin::BI__builtin_addc: 1377 case Builtin::BI__builtin_addcl: 1378 case Builtin::BI__builtin_addcll: 1379 case Builtin::BI__builtin_subcb: 1380 case Builtin::BI__builtin_subcs: 1381 case Builtin::BI__builtin_subc: 1382 case Builtin::BI__builtin_subcl: 1383 case Builtin::BI__builtin_subcll: 1384 if (!interp__builtin_carryop(S, OpPC, Frame, F, Call)) 1385 return false; 1386 break; 1387 1388 case Builtin::BI__builtin_clz: 1389 case Builtin::BI__builtin_clzl: 1390 case Builtin::BI__builtin_clzll: 1391 case Builtin::BI__builtin_clzs: 1392 case Builtin::BI__builtin_clzg: 1393 case Builtin::BI__lzcnt16: // Microsoft variants of count leading-zeroes 1394 case Builtin::BI__lzcnt: 1395 case Builtin::BI__lzcnt64: 1396 if (!interp__builtin_clz(S, OpPC, Frame, F, Call)) 1397 return false; 1398 break; 1399 1400 case Builtin::BI__builtin_ctz: 1401 case Builtin::BI__builtin_ctzl: 1402 case Builtin::BI__builtin_ctzll: 1403 case Builtin::BI__builtin_ctzs: 1404 case Builtin::BI__builtin_ctzg: 1405 if (!interp__builtin_ctz(S, OpPC, Frame, F, Call)) 1406 return false; 1407 break; 1408 1409 case Builtin::BI__builtin_bswap16: 1410 case Builtin::BI__builtin_bswap32: 1411 case Builtin::BI__builtin_bswap64: 1412 if (!interp__builtin_bswap(S, OpPC, Frame, F, Call)) 1413 return false; 1414 break; 1415 1416 case Builtin::BI__atomic_always_lock_free: 1417 case Builtin::BI__atomic_is_lock_free: 1418 case Builtin::BI__c11_atomic_is_lock_free: 1419 if (!interp__builtin_atomic_lock_free(S, OpPC, Frame, F, Call)) 1420 return false; 1421 break; 1422 1423 case Builtin::BI__builtin_complex: 1424 if (!interp__builtin_complex(S, OpPC, Frame, F, Call)) 1425 return false; 1426 break; 1427 1428 case Builtin::BI__builtin_is_aligned: 1429 case Builtin::BI__builtin_align_up: 1430 case Builtin::BI__builtin_align_down: 1431 if (!interp__builtin_is_aligned_up_down(S, OpPC, Frame, F, Call)) 1432 return false; 1433 break; 1434 1435 case Builtin::BI__builtin_os_log_format_buffer_size: 1436 if (!interp__builtin_os_log_format_buffer_size(S, OpPC, Frame, F, Call)) 1437 return false; 1438 break; 1439 1440 case Builtin::BI__builtin_ptrauth_string_discriminator: 1441 if (!interp__builtin_ptrauth_string_discriminator(S, OpPC, Frame, F, Call)) 1442 return false; 1443 break; 1444 1445 default: 1446 S.FFDiag(S.Current->getLocation(OpPC), 1447 diag::note_invalid_subexpr_in_const_expr) 1448 << S.Current->getRange(OpPC); 1449 1450 return false; 1451 } 1452 1453 return retPrimValue(S, OpPC, Dummy, ReturnT); 1454 } 1455 1456 bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E, 1457 llvm::ArrayRef<int64_t> ArrayIndices, 1458 int64_t &IntResult) { 1459 CharUnits Result; 1460 unsigned N = E->getNumComponents(); 1461 assert(N > 0); 1462 1463 unsigned ArrayIndex = 0; 1464 QualType CurrentType = E->getTypeSourceInfo()->getType(); 1465 for (unsigned I = 0; I != N; ++I) { 1466 const OffsetOfNode &Node = E->getComponent(I); 1467 switch (Node.getKind()) { 1468 case OffsetOfNode::Field: { 1469 const FieldDecl *MemberDecl = Node.getField(); 1470 const RecordType *RT = CurrentType->getAs<RecordType>(); 1471 if (!RT) 1472 return false; 1473 const RecordDecl *RD = RT->getDecl(); 1474 if (RD->isInvalidDecl()) 1475 return false; 1476 const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD); 1477 unsigned FieldIndex = MemberDecl->getFieldIndex(); 1478 assert(FieldIndex < RL.getFieldCount() && "offsetof field in wrong type"); 1479 Result += S.getCtx().toCharUnitsFromBits(RL.getFieldOffset(FieldIndex)); 1480 CurrentType = MemberDecl->getType().getNonReferenceType(); 1481 break; 1482 } 1483 case OffsetOfNode::Array: { 1484 // When generating bytecode, we put all the index expressions as Sint64 on 1485 // the stack. 1486 int64_t Index = ArrayIndices[ArrayIndex]; 1487 const ArrayType *AT = S.getCtx().getAsArrayType(CurrentType); 1488 if (!AT) 1489 return false; 1490 CurrentType = AT->getElementType(); 1491 CharUnits ElementSize = S.getCtx().getTypeSizeInChars(CurrentType); 1492 Result += Index * ElementSize; 1493 ++ArrayIndex; 1494 break; 1495 } 1496 case OffsetOfNode::Base: { 1497 const CXXBaseSpecifier *BaseSpec = Node.getBase(); 1498 if (BaseSpec->isVirtual()) 1499 return false; 1500 1501 // Find the layout of the class whose base we are looking into. 1502 const RecordType *RT = CurrentType->getAs<RecordType>(); 1503 if (!RT) 1504 return false; 1505 const RecordDecl *RD = RT->getDecl(); 1506 if (RD->isInvalidDecl()) 1507 return false; 1508 const ASTRecordLayout &RL = S.getCtx().getASTRecordLayout(RD); 1509 1510 // Find the base class itself. 1511 CurrentType = BaseSpec->getType(); 1512 const RecordType *BaseRT = CurrentType->getAs<RecordType>(); 1513 if (!BaseRT) 1514 return false; 1515 1516 // Add the offset to the base. 1517 Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl())); 1518 break; 1519 } 1520 case OffsetOfNode::Identifier: 1521 llvm_unreachable("Dependent OffsetOfExpr?"); 1522 } 1523 } 1524 1525 IntResult = Result.getQuantity(); 1526 1527 return true; 1528 } 1529 1530 bool SetThreeWayComparisonField(InterpState &S, CodePtr OpPC, 1531 const Pointer &Ptr, const APSInt &IntValue) { 1532 1533 const Record *R = Ptr.getRecord(); 1534 assert(R); 1535 assert(R->getNumFields() == 1); 1536 1537 unsigned FieldOffset = R->getField(0u)->Offset; 1538 const Pointer &FieldPtr = Ptr.atField(FieldOffset); 1539 PrimType FieldT = *S.getContext().classify(FieldPtr.getType()); 1540 1541 INT_TYPE_SWITCH(FieldT, 1542 FieldPtr.deref<T>() = T::from(IntValue.getSExtValue())); 1543 FieldPtr.initialize(); 1544 return true; 1545 } 1546 1547 bool DoMemcpy(InterpState &S, CodePtr OpPC, const Pointer &Src, Pointer &Dest) { 1548 assert(Src.isLive() && Dest.isLive()); 1549 1550 [[maybe_unused]] const Descriptor *SrcDesc = Src.getFieldDesc(); 1551 const Descriptor *DestDesc = Dest.getFieldDesc(); 1552 1553 assert(!DestDesc->isPrimitive() && !SrcDesc->isPrimitive()); 1554 1555 if (DestDesc->isPrimitiveArray()) { 1556 assert(SrcDesc->isPrimitiveArray()); 1557 assert(SrcDesc->getNumElems() == DestDesc->getNumElems()); 1558 PrimType ET = DestDesc->getPrimType(); 1559 for (unsigned I = 0, N = DestDesc->getNumElems(); I != N; ++I) { 1560 Pointer DestElem = Dest.atIndex(I); 1561 TYPE_SWITCH(ET, { 1562 DestElem.deref<T>() = Src.atIndex(I).deref<T>(); 1563 DestElem.initialize(); 1564 }); 1565 } 1566 return true; 1567 } 1568 1569 if (DestDesc->isRecord()) { 1570 assert(SrcDesc->isRecord()); 1571 assert(SrcDesc->ElemRecord == DestDesc->ElemRecord); 1572 const Record *R = DestDesc->ElemRecord; 1573 for (const Record::Field &F : R->fields()) { 1574 Pointer DestField = Dest.atField(F.Offset); 1575 if (std::optional<PrimType> FT = S.Ctx.classify(F.Decl->getType())) { 1576 TYPE_SWITCH(*FT, { 1577 DestField.deref<T>() = Src.atField(F.Offset).deref<T>(); 1578 DestField.initialize(); 1579 }); 1580 } else { 1581 return Invalid(S, OpPC); 1582 } 1583 } 1584 return true; 1585 } 1586 1587 // FIXME: Composite types. 1588 1589 return Invalid(S, OpPC); 1590 } 1591 1592 } // namespace interp 1593 } // namespace clang 1594