On Mon, Jan 18, 2016 at 10:04:12AM -0500, Jason Merrill wrote: > This wouldn't cover cases where this change affects the type or value of > more complicated expressions, so my preference would be to clear the caches > when we finish_enum_value_list.
So like this? Bootstrapped/regtested on x86_64-linux. 2016-01-18 Marek Polacek <pola...@redhat.com> PR c++/68586 * constexpr.c (clear_cv_cache): New. * cp-tree.h (clear_cv_cache): Declare. * decl.c (finish_enum_value_list): Call it. * g++.dg/cpp0x/enum30.C: New test. diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c index 6ab4696..6b0e5a8 100644 --- gcc/cp/constexpr.c +++ gcc/cp/constexpr.c @@ -4027,6 +4027,14 @@ maybe_constant_value (tree t, tree decl) return ret; } +/* Dispose of the whole CV_CACHE. */ + +void +clear_cv_cache (void) +{ + gt_cleare_cache (cv_cache); +} + /* Like maybe_constant_value but first fully instantiate the argument. Note: this is equivalent to instantiate_non_dependent_expr_sfinae diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h index fc9507e..1ae0d5a 100644 --- gcc/cp/cp-tree.h +++ gcc/cp/cp-tree.h @@ -6919,6 +6919,7 @@ extern bool var_in_constexpr_fn (tree); extern void explain_invalid_constexpr_fn (tree); extern vec<tree> cx_error_context (void); extern tree fold_sizeof_expr (tree); +extern void clear_cv_cache (void); /* In c-family/cilk.c */ extern bool cilk_valid_spawn (tree); diff --git gcc/cp/decl.c gcc/cp/decl.c index df95133..d489b87 100644 --- gcc/cp/decl.c +++ gcc/cp/decl.c @@ -13386,6 +13386,10 @@ finish_enum_value_list (tree enumtype) /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, namespace_bindings_p ()); + + /* Each enumerator now has the type of its enumeration. Clear the cache + so that this change in types doesn't confuse us later on. */ + clear_cv_cache (); } /* Finishes the enum type. This is called only the first time an diff --git gcc/testsuite/g++.dg/cpp0x/enum30.C gcc/testsuite/g++.dg/cpp0x/enum30.C index e69de29..cf0c1b5 100644 --- gcc/testsuite/g++.dg/cpp0x/enum30.C +++ gcc/testsuite/g++.dg/cpp0x/enum30.C @@ -0,0 +1,14 @@ +// PR c++/68586 +// { dg-do compile { target c++11 } } + +enum E { x , y = 1 + (x << 1) }; +template<E> struct A {}; +A<x> a; + +enum E2 : int { x2 , y2 = x2 << 1 }; +template<E2> struct A2 {}; +A2<x2> a2; + +enum class E3 { x3 , y3 = x3 << 1 }; +template<E3> struct A3 {}; +A3<E3::x3> a3; Marek