================ @@ -119,12 +121,26 @@ template <PrimType OpType> bool EvalEmitter::emitRet(const SourceInfo &Info) { template <> bool EvalEmitter::emitRet<PT_Ptr>(const SourceInfo &Info) { if (!isActive()) return true; - EvalResult.setPointer(S.Stk.pop<Pointer>()); + + const Pointer &Ptr = S.Stk.pop<Pointer>(); + // Implicitly convert lvalue to rvalue, if requested. + if (ConvertResultToRValue) { + if (std::optional<APValue> V = Ptr.toRValue(Ctx)) { + EvalResult.setValue(*V); + } else { + return false; + } + } else { + EvalResult.setPointer(Ptr); + } + return true; } template <> bool EvalEmitter::emitRet<PT_FnPtr>(const SourceInfo &Info) { if (!isActive()) return true; + // Function pointers are always lvalues to us and cannot be converted + // to rvalues, so don't do any conversion here. ---------------- AaronBallman wrote:
Well, there's a difference between a function designator and a function pointer... Given: ``` void func(int); int main() { func(0); } ``` `func` is a function designator, the `func(0)` decays the function designator `void(int)` into a function pointer `void (*)(int)` which is then used by the call expression and passed the integer literal `0`. In terms of our AST: ``` `-CallExpr <line:4:3, col:9> 'void' |-ImplicitCastExpr <col:3> 'void (*)(int)' <FunctionToPointerDecay> | `-DeclRefExpr <col:3> 'void (int)' Function 0xc59b980 'func' 'void (int)' `-IntegerLiteral <col:8> 'int' 0 ``` The `DeclRefExpr` is using the function designator, the `ImplicitCastExpr` is what turns that into a function pointer, which is then the first operand of the `CallExpr`, and the `IntegerLiteral` is the first formal argument to the `CallExpr`. I think we evaluate function designators as-if they are lvalues because they're a `DeclRefExpr` in terms of the call expression and those are lvalues until there's a conversion on them. https://github.com/llvm/llvm-project/pull/80662 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits