Patchwork C++ PATCH for c++/55931 (ICE with non-dependent constexpr call in template)

login
register
mail settings
Submitter Jason Merrill
Date March 17, 2013, 2:08 a.m.
Message ID <514525B2.6090104@redhat.com>
Download mbox | patch
Permalink /patch/228268/
State New
Headers show

Comments

Jason Merrill - March 17, 2013, 2:08 a.m.
We were calling fold_non_dependent_expr twice on the template argument, 
which leads to chaos.  In general we try to fold close to the use, so 
let's stop folding in the parser.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 4240d0bfcd28f4a822ae0fff3f045e2eda46f55c
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Feb 12 23:40:45 2013 -0500

    	PR c++/55931
    	* parser.c (cp_parser_template_argument): Don't
    	fold_non_dependent_expr.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8b6dbe1..0222e90 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -13335,7 +13335,6 @@  cp_parser_template_argument (cp_parser* parser)
   argument = cp_parser_constant_expression (parser,
 					    /*allow_non_constant_p=*/false,
 					    /*non_constant_p=*/NULL);
-  argument = fold_non_dependent_expr (argument);
   if (!maybe_type_id)
     return argument;
   if (!cp_parser_next_token_ends_template_argument_p (parser))
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-template4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-template4.C
new file mode 100644
index 0000000..7adcae8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-template4.C
@@ -0,0 +1,26 @@ 
+// PR c++/55931
+// { dg-do compile { target c++11 } }
+
+#include <type_traits>
+
+template<typename Type>
+class Test
+{
+    public:
+        constexpr Test(const Type val) : _value(val) {}
+        constexpr Type get() const {return _value;}
+        static void test()
+        {
+            static constexpr Test<int> x(42);
+            std::integral_constant<int, x.get()> i; // This is not working
+        }
+    protected:
+        Type _value;
+};
+
+int main()
+{
+    static constexpr Test<int> x(42);
+    std::integral_constant<int, x.get()> i; // This is working
+    Test<double>::test();
+}