This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/64603 (wrong error with sizeof and constexpr)


For some reason, when converting sizeof("Main")-1 to int, we end up with (unsigned)5UL + -1U, which fold fails to fold to 4U, but initializer_constant_valid_p is happy to accept. I'm dealing with this by always reprocessing expressions in the constexpr code.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit e8254e33cb727aebc874d1508b13386a6cbd093b
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jan 21 07:45:02 2015 -0500

    	PR c++/64603
    	* constexpr.c (cxx_eval_constant_expression): Only shortcut
    	constant CONSTRUCTORs.

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index decc84d..7853d37 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -2943,9 +2943,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
 	*overflow_p = true;
       return t;
     }
-  if (TREE_CODE (t) != NOP_EXPR
-      && reduced_constant_expression_p (t))
-    return fold (t);
 
   switch (TREE_CODE (t))
     {
@@ -3315,6 +3312,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
       break;
 
     case CONSTRUCTOR:
+      if (TREE_CONSTANT (t))
+	/* Don't re-process a constant CONSTRUCTOR, but do fold it to
+	   VECTOR_CST if applicable.  */
+	return fold (t);
       r = cxx_eval_bare_aggregate (ctx, t, lval,
 				   non_constant_p, overflow_p);
       break;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof1.C
new file mode 100644
index 0000000..d9a032b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-sizeof1.C
@@ -0,0 +1,15 @@
+// PR c++/64603
+// { dg-do compile { target c++11 } }
+
+template <int i> constexpr int find_longest_name()
+{
+  return sizeof("Main") - 1;
+}
+
+template <int i, int l = find_longest_name<i>()> void create_all_loggers()
+{}
+
+int main()
+{
+  create_all_loggers<1>();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]