re PR c++/54946 (ICE on template parameter from cast char-pointer in C++11 constexpr...
authorJason Merrill <jason@redhat.com>
Sun, 17 Mar 2013 02:35:50 +0000 (22:35 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 17 Mar 2013 02:35:50 +0000 (22:35 -0400)
PR c++/54946
* pt.c (convert_nontype_argument): Handle invalid pointer.

From-SVN: r196731

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/constexpr-template5.C [new file with mode: 0644]

index de8f030..45c5d28 100644 (file)
@@ -1,5 +1,8 @@
 2013-03-16  Jason Merrill  <jason@redhat.com>
 
+       PR c++/54946
+       * pt.c (convert_nontype_argument): Handle invalid pointer.
+
        * parser.c (cp_parser_lambda_expression): Use nreverse.
 
        PR c++/56447
index 126e110..c07ed32 100644 (file)
@@ -5553,15 +5553,19 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
      qualification conversion. Let's strip everything.  */
   else if (TREE_CODE (expr) == NOP_EXPR && TYPE_PTROBV_P (type))
     {
-      STRIP_NOPS (expr);
-      gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
-      gcc_assert (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE);
-      /* Skip the ADDR_EXPR only if it is part of the decay for
-        an array. Otherwise, it is part of the original argument
-        in the source code.  */
-      if (TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == ARRAY_TYPE)
-       expr = TREE_OPERAND (expr, 0);
-      expr_type = TREE_TYPE (expr);
+      tree probe = expr;
+      STRIP_NOPS (probe);
+      if (TREE_CODE (probe) == ADDR_EXPR
+         && TREE_CODE (TREE_TYPE (probe)) == POINTER_TYPE)
+       {
+         /* Skip the ADDR_EXPR only if it is part of the decay for
+            an array. Otherwise, it is part of the original argument
+            in the source code.  */
+         if (TREE_CODE (TREE_TYPE (TREE_OPERAND (probe, 0))) == ARRAY_TYPE)
+           probe = TREE_OPERAND (probe, 0);
+         expr = probe;
+         expr_type = TREE_TYPE (expr);
+       }
     }
 
   /* [temp.arg.nontype]/5, bullet 1
@@ -5640,6 +5644,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
                     expr, expr);
              return NULL_TREE;
            }
+         if (POINTER_TYPE_P (expr_type))
+           {
+             error ("%qE is not a valid template argument for %qT"
+                    "because it is not the address of a variable",
+                    expr, type);
+             return NULL_TREE;
+           }
          /* Other values, like integer constants, might be valid
             non-type arguments of some other type.  */
          return error_mark_node;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-template5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-template5.C
new file mode 100644 (file)
index 0000000..aa80658
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/54946
+// { dg-do compile { target c++11 } }
+
+template<const char*s>    static void testfunc();
+constexpr struct testtype { const char* str; } test = { "abc"} ;
+void (*functionpointer)() = testfunc<(const char*) test.str>; // { dg-error "" }