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