diff mbox

C++ PATCH for c++/69688 (bogus error with -Wsign-compare)

Message ID 20160208152559.GA3289@redhat.com
State New
Headers show

Commit Message

Marek Polacek Feb. 8, 2016, 3:25 p.m. UTC
On Fri, Feb 05, 2016 at 05:36:21PM -0500, Jason Merrill wrote:
> On 02/05/2016 05:32 PM, Marek Polacek wrote:
> >   if (TREE_CODE (type) == ERROR_MARK)
> >     return NULL_TREE;
> >
> >+  /* Here, DECL may change value; purge caches.  */
> >+  clear_fold_cache ();
> >+  clear_cv_cache ();
> >+
> >   if (MAYBE_CLASS_TYPE_P (type))
> 
> This should happen after computing the value to be stored, not before. Also,
> could you combine those two functions into one?  There's no reason for
> callers such as this to need to call two different functions.

Okay.  So like this?

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2016-02-08  Marek Polacek  <polacek@redhat.com>

	PR c++/69688
	* constexpr.c (clear_cv_and_fold_caches): Renamed from clear_cv_cache.
	Call clear_fold_cache.
	* cp-tree.h: Adjust declaration.
	* decl.c (finish_enum_value_list): Call clear_cv_and_fold_caches
	rather than clear_cv_cache and clear_fold_cache.
	* typeck2.c (store_init_value): Call clear_cv_and_fold_caches.

	* g++.dg/init/const12.C: New test.


	Marek

Comments

Jason Merrill Feb. 8, 2016, 3:34 p.m. UTC | #1
OK, thanks.

Jason
diff mbox

Patch

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 05f6843..85fc64e 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -4098,12 +4098,13 @@  maybe_constant_value (tree t, tree decl)
   return ret;
 }
 
-/* Dispose of the whole CV_CACHE.  */
+/* Dispose of the whole CV_CACHE and FOLD_CACHE.  */
 
 void
-clear_cv_cache (void)
+clear_cv_and_fold_caches (void)
 {
   gt_cleare_cache (cv_cache);
+  clear_fold_cache ();
 }
 
 /* Like maybe_constant_value but first fully instantiate the argument.
diff --git gcc/cp/cp-tree.h gcc/cp/cp-tree.h
index 0aeee57..a67e9b6 100644
--- gcc/cp/cp-tree.h
+++ gcc/cp/cp-tree.h
@@ -6920,7 +6920,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);
+extern void clear_cv_and_fold_caches		(void);
 
 /* In c-family/cilk.c */
 extern bool cilk_valid_spawn                    (tree);
diff --git gcc/cp/decl.c gcc/cp/decl.c
index 2c337bc..11f7ce6 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -13414,8 +13414,7 @@  finish_enum_value_list (tree enumtype)
 
   /* 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 ();
-  clear_fold_cache ();
+  clear_cv_and_fold_caches ();
 }
 
 /* Finishes the enum type. This is called only the first time an
diff --git gcc/cp/typeck2.c gcc/cp/typeck2.c
index 419faa2..2a76c96 100644
--- gcc/cp/typeck2.c
+++ gcc/cp/typeck2.c
@@ -837,6 +837,9 @@  store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
     /* Handle aggregate NSDMI in non-constant initializers, too.  */
     value = replace_placeholders (value, decl);
 
+  /* DECL may change value; purge caches.  */
+  clear_cv_and_fold_caches ();
+
   /* If the initializer is not a constant, fill in DECL_INITIAL with
      the bits that are constant, and then return an expression that
      will perform the dynamic initialization.  */
diff --git gcc/testsuite/g++.dg/init/const12.C gcc/testsuite/g++.dg/init/const12.C
index e69de29..2f6f9b2 100644
--- gcc/testsuite/g++.dg/init/const12.C
+++ gcc/testsuite/g++.dg/init/const12.C
@@ -0,0 +1,20 @@ 
+// PR c++/69688
+// { dg-do compile }
+// { dg-options "-Wsign-compare" }
+
+struct S
+{
+  static const int s;
+  static const char c[];
+  static wchar_t w[];
+
+  S ()
+    {
+      for (int i = 0; i < s; i++)
+	w[i] = 0;
+    }
+};
+
+const char S::c[] = "x";
+const int S::s = sizeof (S::c) - 1;
+wchar_t S::w[S::s];