Open
Description
Consider this simple example:
typedef __typeof((int*) 0 - (int*) 0) intptr_t;
int a = 10;
intptr_t s = (intptr_t) &a;
Compiled as C, there are no compilation errors. However, when evaluating the initializer for s
:
CStyleCastExpr 0x7d6799454e40 'intptr_t':'long' <PointerToIntegral>
`-UnaryOperator 0x7d6799454e08 'int *' prefix '&' cannot overflow
`-DeclRefExpr 0x7d6799454de0 'int' lvalue Var 0x7d6799454bf8 'a' 'int'
the current interpreter doesn't actually return an integer value at all, it returns an lvalue pointing to a
:
LValue Base=VarDecl 0x7d6799454bf8, Null=0, Offset=0, HasPath=0
which ultimately means we get the following IR:
@a = dso_local global i32 10, align 4
@s = dso_local global i64 ptrtoint (ptr @a to i64), align 8
that's because the current interpreter takes this code path:
llvm-project/clang/lib/AST/ExprConstant.cpp
Lines 15269 to 15280 in fb00fa5
which means it returns an lvalue from an AST node that returns an integer. That works in the current interpreter where everything is an APValue
an one can check the type of those values, but in a bytecode interpreter, where we expect the computed type to match the node type, it doesn't work.