[clang] [clang][Interp] Do r-to-l conversion immediately when returning (PR #80662)

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 5 08:17:02 PST 2024


================
@@ -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


More information about the cfe-commits mailing list