llvm-project/clang/test/CodeGenCXX/builtin-constant-p.cpp
Timm Baeder d08cf7900d
[clang][bytecode] Implement __builtin_constant_p (#130143)
Use the regular code paths for interpreting.

Add new instructions: `StartSpeculation` will reset the diagnostics
pointers to `nullptr`, which will keep us from reporting any diagnostics
during speculation. `EndSpeculation` will undo this.

The rest depends on what `Emitter` we use.

For `EvalEmitter`, we have no bytecode, so we implement `speculate()` by
simply visiting the first argument of `__builtin_constant_p`. If the
evaluation fails, we push a `0` on the stack, otherwise a `1`.

For `ByteCodeEmitter`, add another instrucion called `BCP`, that
interprets all the instructions following it until the next
`EndSpeculation` instruction. If any of those instructions fails, we
jump to the `EndLabel`, which brings us right before the
`EndSpeculation`. We then push the result on the stack.
2025-03-08 06:06:14 +01:00

50 lines
1.1 KiB
C++

// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s -fexperimental-new-constant-interpreter | FileCheck %s
// Don't crash if the argument to __builtin_constant_p isn't scalar.
template <typename T>
constexpr bool is_constant(const T v) {
return __builtin_constant_p(v);
}
template <typename T>
class numeric {
public:
using type = T;
template <typename S>
constexpr numeric(S value)
: value_(static_cast<T>(value)) {}
private:
const T value_;
};
bool bcp() {
return is_constant(numeric<int>(1));
}
// PR45535
struct with_dtor {
~with_dtor();
};
// CHECK: define {{.*}}bcp_stmt_expr_1
bool bcp_stmt_expr_1() {
// CHECK-NOT: call {{.*}}with_dtorD
return __builtin_constant_p(({with_dtor wd; 123;}));
}
int do_not_call();
// CHECK: define {{.*}}bcp_stmt_expr_2
bool bcp_stmt_expr_2(int n) {
// CHECK-NOT: call {{.*}}do_not_call
return __builtin_constant_p(({
// This has a side-effect due to the VLA bound, so CodeGen should fold it
// to false.
typedef int arr[do_not_call()];
n;
}));
// CHECK-NOT: }
// CHECK: ret i1 false
}