[PATCH] D13386: PR24115: Don't instantiate constexpr function templates in decltype

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 5 15:06:12 PDT 2015


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





More information about the cfe-commits mailing list