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