rsmith added a comment.

Sorry, this is not OK; we need to eagerly instantiate within a `decltype` 
expression in some cases, and we should not be treating `decltype` as being 
different from any other unevaluated operand here. Example:

  template<typename T> constexpr T f() { return 0; }
  decltype(char{f<int>()}) x;

... will be rejected due to a narrowing conversion unless `f<int>()` is 
instantiated. As far as I'm aware, GCC gets around this by triggering 
instantiation from within the constant expression evaluator, but that is a 
significant layering / phases of translation violation, and we don't want to do 
that.

In discussion with Jason Merrill, the front-runner approach for handling this 
is to separate 'unevaluated contexts' into 'unevaluated contexts' and 
'constant-evaluated contexts' (clang already somewhat has this distinction -- 
see `Sema::ExpressionEvaluationContext`'s `Unevaluated` versus 
`ConstantEvaluated` -- but it doesn't quite line up with what we'd want here). 
The latter would cover things like:

- a template argument,
- an expression within a //braced-init-list//,
- an expression inside an array declarator

... and so on (these are the contexts that can occur within an unevaluated 
context, and where constant evaluation is necessary). We would then trigger 
instantiation of a `constexpr` function if it's either odr-used or referenced 
in a constant-evaluated context.


http://reviews.llvm.org/D13386



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

Reply via email to