Coverage Report

Created: 2024-01-17 10:31

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