samitolvanen planned changes to this revision.
samitolvanen added a comment.

In D108479#3149297 <https://reviews.llvm.org/D108479#3149297>, @rjmccall wrote:

> In D108479#3149228 <https://reviews.llvm.org/D108479#3149228>, @samitolvanen 
> wrote:
>
>> I worked around this for now by explicitly allowing 
>> `__builtin_function_start` in `CheckLValueConstantExpression`, but this 
>> seems terribly hacky. What would be the correct way to solve this issue?
>
> Try to generalize what we do for `__builtin___CFStringMakeConstantString`.

Thanks, I'll take a look.



================
Comment at: clang/lib/Sema/SemaChecking.cpp:208
+    if (UnaryOp->getOpcode() == UnaryOperator::Opcode::UO_AddrOf)
+      E = UnaryOp->getSubExpr();
+
----------------
rjmccall wrote:
> samitolvanen wrote:
> > rjmccall wrote:
> > > It would be more general to allow any expression that we can 
> > > constant-evaluate to a specific function / member function reference.  
> > > That allows callers to do stuff like `__builtin_function_start((int 
> > > (A::*)() const) &A::x)` to resolve overloaded function references.
> > > 
> > > You should delay this check if the operand is value-dependent.
> > > It would be more general to allow any expression that we can 
> > > constant-evaluate to a specific function / member function reference.  
> > > That allows callers to do stuff like `__builtin_function_start((int 
> > > (A::*)() const) &A::x)` to resolve overloaded function references.
> > 
> > I looked into using `Expr::EvaluateAsConstantExpr` here and while it works, 
> > I'm not sure if allowing arbitrary expressions as the argument provides any 
> > value. We can allow resolving overloaded function references without 
> > constant-evaluating the expression (and I added tests for this). Did you 
> > have any other use cases in mind where this might be useful?
> I don't see what the advantage of limiting the constant expression would be 
> if we can constant-evaluate it.  `switch` doesn't force you to make case 
> values be integer literals and/or references to enumerators.  What are you 
> trying to achieve with a restriction?
> 
> Not having arbitrary restrictions is particularly useful in C++, where 
> templates and `constexpr` machinery can usefully do a lot of abstraction.
> I don't see what the advantage of limiting the constant expression would be 
> if we can constant-evaluate it.  `switch` doesn't force you to make case 
> values be integer literals and/or references to enumerators.  What are you 
> trying to achieve with a restriction?

I'm trying to understand the benefit of allowing arbitrary expressions like 
`__builtin_function_start(100 + a)`, which `EvaluateAsConstantExpr` is happy to 
evaluate into a reference to `a`.

I can obviously understand why these should be allowed for `switch`, but here 
we have a function whose sole purpose is to return the address of a function 
and I'm wondering why someone would want pass anything more complicated to it.

> Not having arbitrary restrictions is particularly useful in C++, where 
> templates and `constexpr` machinery can usefully do a lot of abstraction.

Perhaps I'm just not that familiar with the C++ use cases here. Would you be 
able to provide me an example I could use as a test case?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D108479

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

Reply via email to