Tyker added inline comments.

================
Comment at: clang/lib/AST/ExprConstant.cpp:6807-6808
 
+    llvm::SaveAndRestore<bool> InConstantContext(Info.InConstantContext, true);
     return StmtVisitorTy::Visit(E->getSubExpr());
   }
----------------
rsmith wrote:
> I don't think this is really right, but perhaps the difference isn't 
> observable right now. What I'm thinking of is a case like this:
> 
> ```
> consteval int do_stuff() {
>   __builtin_produce_diagnostic("hello world\n");
>   return 42;
> }
> constexpr int f() {
>   int n = do_stuff();
>   return n;
> }
> int k = f();
> ```
> 
> Here, I would expect that when we process the immediate invocation of 
> `do_stuff()` in `f`, we would immediately evaluate it, including issuing its 
> diagnostic. And then for all subsequent calls to `f()`, we would never 
> re-evaluate it.
> 
> I can see a couple of ways this could work:
> 
>  * Whenever we create a `ConstantExpr`, we always evaluate it and fill in the 
> `APValue` result; it's never absent except perhaps in a window of time 
> between forming that AST node and deciding for sure that we want to keep it 
> (for nested immediate invocation handling).
>  * Whenever constant evaluation meets a `ConstantExpr` that doesn't have an 
> associated result yet, it triggers that result to be computed and cached, as 
> a separate evaluation.
> 
> I think the first of those two approaches is much better: lazily evaluating 
> the `ConstantExpr` will require us to save update records if we're writing an 
> AST file, and will mean we don't always have an obvious point where the 
> side-effects from builtin consteval functions (eg, reflection-driven actions) 
> happen.
> 
> So I think the right thing to do is probably to say that a `ConstantExpr` 
> that hasn't yet had its `APValue` result filled in is non-constant for now, 
> and to ensure that everywhere that creates a `ConstantExpr` always eventually 
> either removes it again or fills in the result.
ok seems reasonable.



================
Comment at: clang/lib/CodeGen/CGExprConstant.cpp:1364-1365
+llvm::Constant *ConstantEmitter::tryEmitConstantExpr(const ConstantExpr *CE) {
+  if (!CE->isImmediateInvocation())
+    return nullptr;
+  const Expr *Inner = CE->getSubExpr()->IgnoreImplicit();
----------------
rsmith wrote:
> I'm fine with having this check for now, but eventually I think we should do 
> this for all `ConstantExpr`s, regardless of whether they're immediate 
> invocations.
this can be relaxed to hasAPValueResult without any change in behavior.


================
Comment at: clang/lib/CodeGen/CGExprConstant.cpp:1374
+      emitAbstract(CE->getBeginLoc(), CE->getAPValueResult(), RetType);
+  return Res;
+}
----------------
rsmith wrote:
> Can we assert that we succeeded here? This emission should never fail.
from the comment on emitAbstract's declaration it seems to already be the case.
```
  /// Emit the result of the given expression as an abstract constant,
  /// asserting that it succeeded.  This is only safe to do when the
  /// expression is known to be a constant expression with either a fairly
  /// simple type or a known simple form.
  llvm::Constant *emitAbstract(const Expr *E, QualType T);
  llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
                               QualType T);
``` 


================
Comment at: clang/lib/CodeGen/CGExprScalar.cpp:464-470
+      QualType RetType = cast<CallExpr>(E->getSubExpr()->IgnoreImplicit())
+                             ->getCallReturnType(CGF.getContext());
+      if (RetType->isReferenceType()) {
+        return CGF.Builder.CreateLoad(Address(
+            Result, CGF.getContext().getTypeAlignInChars(
+                        cast<ReferenceType>(RetType)->getPointeeType())));
+      }
----------------
rsmith wrote:
> OK, so this is presumably handling the case where `ScalarExprEmitter` is used 
> to emit an lvalue expression, under the understanding that when it reaches 
> the eventual lvalue a load will be implicitly generated.
> 
> Looking for a `CallExpr` that returns a reference type is not the best way to 
> handle this. It's brittle (it would break if `tryEmitConstantExpr` starts 
> emitting more kinds of `ConstantExpr` or if we start supporting more kinds of 
> immediate invocations) and we don't need to perform such a subtle check: 
> instead, please just check whether `E` is an lvalue, and perform a load if so.
we need to generate a load for rvalue-reference as well so i think we need to 
check wether E is a glvalue instead of just lvalue.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76420/new/

https://reviews.llvm.org/D76420



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to