if (t == error_mark_node)
return error_mark_node;
+ /* In "sizeof(X<I>)" we need to evaluate "I". */
+ cp_evaluated ev;
+
const int len = TREE_VEC_LENGTH (t);
tree *elts = XALLOCAVEC (tree, len);
int expanded_len_adjust = 0;
tree argvec;
tree r;
- /* In "sizeof(X<I>)" we need to evaluate "I". */
- cp_evaluated ev;
-
/* Figure out what arguments are appropriate for the
type we are trying to find. For example, given:
--- /dev/null
+// PR c++/101906
+// Verify the template arguments of an alias template-id are evaluated even
+// in an unevaluated context.
+// { dg-do compile { target c++11 } }
+
+template<int, class T> using skip = T;
+
+template<class T>
+constexpr unsigned sizeof_() {
+ return sizeof(skip<(T(), 0), T>);
+}
+
+struct A {
+ int m = -1;
+};
+
+static_assert(sizeof_<A>() == sizeof(A), "");
--- /dev/null
+// PR c++/101906
+// Like unevaluated1.C, but where the unevaluated context is a
+// constraint instead of sizeof.
+// { dg-do compile { target c++20 } }
+
+template<int> using voidify = void;
+
+template<class T>
+concept constant_value_initializable
+ = requires { typename voidify<(T(), 0)>; };
+
+struct A {
+ int m = -1;
+};
+
+static_assert(constant_value_initializable<A>);
--- /dev/null
+// PR c++/101906
+// Like unevaluated1.C, but using a function template instead of an
+// alias template.
+// { dg-do compile { target c++14 } }
+
+template<int, class T> T skip();
+
+template<class T>
+constexpr unsigned sizeof_() {
+ return sizeof(skip<(T(), 0), T>());
+}
+
+struct A {
+ int m = -1;
+};
+
+static_assert(sizeof_<A>() == sizeof(A), "");
--- /dev/null
+// PR c++/101906
+// Like unevaluated1b.C, but using a variable template instead of a
+// function template.
+// { dg-do compile { target c++14 } }
+
+template<int, class T> T skip;
+
+template<class T>
+constexpr unsigned sizeof_() {
+ return sizeof(skip<(T(), 0), T>);
+}
+
+struct A {
+ int m = -1;
+};
+
+static_assert(sizeof_<A>() == sizeof(A), "");