wchilders marked 2 inline comments as done.
wchilders added inline comments.

================
Comment at: clang/lib/AST/ExprConstant.cpp:7329
+      if (Result.isLValue())
+        return Success(Result, E);
+    }
----------------
rsmith wrote:
> wchilders wrote:
> > rsmith wrote:
> > > wchilders wrote:
> > > > This doesn't seem to be the right answer, and `ConstantExpr`s don't 
> > > > have `LValue` `APValue`s, at least, not that are reaching this case. We 
> > > > had a previous implementation that also, kind of punted on this issue 
> > > > with an override in `TemporaryExprEvaluator`: 
> > > > https://gitlab.com/lock3/clang/-/blob/9fbaeea06fc567ac472264bec2a72661a1e06c73/clang/lib/AST/ExprConstant.cpp#L9753
> > > The base class version seems appropriate to me, even for this case. We 
> > > eventually want to use `ConstantExpr` to store the evaluated initializer 
> > > value of a `constexpr` variable (replacing the existing special-case 
> > > caching on `VarDecl`) and the like, not only for immediate invocations, 
> > > and once we start doing that for reference variables we'll have glvalue 
> > > `ConstantExpr`s.
> > > 
> > > Is there some circumstance under which a glvalue `ConstantExpr`'s 
> > > `APValue` result is not of kind `LValue`?
> > > Is there some circumstance under which a glvalue ConstantExpr's APValue 
> > > result is not of kind LValue?
> > 
> > Good question, the `Sema/switch.c` test fails if you 
> > `assert(Result.isLValue())`.
> > 
> > ```
> > ConstantExpr 0x555562ab8760 'const int' lvalue Int: 3
> > `-DeclRefExpr 0x555562ab8740 'const int' lvalue Var 0x555562ab8230 'a' 
> > 'const int'
> > ```
> > 
> > With an attributed line no. 359: 
> > https://github.com/llvm/llvm-project/blob/4b0029995853fe37d1dc95ef96f46697c743fcad/clang/test/Sema/switch.c#L359
> > 
> > The offending RValue is created in SemaExpr.cpp here: 
> > https://github.com/llvm/llvm-project/blob/f87563661d6661fd4843beb8f391acd077b08dbe/clang/lib/Sema/SemaExpr.cpp#L15190
> > 
> > The issue stems from evaluating this as an RValue to produce an integer, 
> > then caching that RValue in an lvalue constant expression. Do you have any 
> > suggestions? Perhaps an LValue to RValue conversion should be performed on 
> > the expression if it folds correctly, so that the ConstantExpr is actually 
> > an RValue?
> I think we should be inserting the lvalue-to-rvalue conversion before we even 
> try evaluating the expression. Does this go wrong along both the C++11 and 
> pre-C++11 codepaths? (They do rather different conversions to the 
> expression.) In any case, we're likely missing a call to 
> `DefaultLvalueConversion` on whichever side is failing.
> 
> Judging by the fact that `struct X { void f() { switch (0) case f: ; } };` 
> misses the "non-static member function must be called" diagnostic only in 
> C++98 mode, I'd imagine it's just the pre-C++11 codepath that's broken here.
This is a C test, the C++ language level is actually irrelevant as best I can 
tell. I added the missing LValue -> RValue conversion so that the APValue is 
generated correctly. With that things function as you'd expect, I added an 
assertion to the LValue base evaluator to detect this case early in 
development, otherwise, the logic is now shared across evaluator classes.


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

https://reviews.llvm.org/D76438



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

Reply via email to