N3639 C++1y VLA diagnostics
authorJason Merrill <jason@redhat.com>
Thu, 9 May 2013 16:43:43 +0000 (12:43 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 9 May 2013 16:43:43 +0000 (12:43 -0400)
* decl.c (grokdeclarator): Complain about reference, pointer, or
typedef to VLA.
(create_array_type_for_decl): Complain about array of VLA.
* pt.c (tsubst): Likewise.
* rtti.c (get_tinfo_decl): Talk about "array of runtime bound".
* semantics.c (finish_decltype_type): Complain about decltype of VLA.
* typeck.c (cp_build_addr_expr_1): Complain about VLA.
(cxx_sizeof_or_alignof_type): Likewise.

From-SVN: r198746

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/pt.c
gcc/cp/rtti.c
gcc/cp/semantics.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/cpp1y/vla1.C [new file with mode: 0644]

index 57d6a0a67e38f4991aab9dd5e9a55ef8cc327952..74480f65339f69fceb926682b8a09bb5185fdea8 100644 (file)
@@ -1,5 +1,15 @@
 2013-05-09  Jason Merrill  <jason@redhat.com>
 
+       N3639 C++1y VLA diagnostics
+       * decl.c (grokdeclarator): Complain about reference, pointer, or
+       typedef to VLA.
+       (create_array_type_for_decl): Complain about array of VLA.
+       * pt.c (tsubst): Likewise.
+       * rtti.c (get_tinfo_decl): Talk about "array of runtime bound".
+       * semantics.c (finish_decltype_type): Complain about decltype of VLA.
+       * typeck.c (cp_build_addr_expr_1): Complain about VLA.
+       (cxx_sizeof_or_alignof_type): Likewise.
+
        N3639 C++1y VLA support
        * decl.c (compute_array_index_type): Allow VLAs in C++1y mode.
        (check_array_initializer): Allow VLA init.
index cebd36103b79580f90e7ebbe3f8557efb947d735..438d27de1bd96c3ec1da878d346fdaa527f33375 100644 (file)
@@ -8479,6 +8479,9 @@ create_array_type_for_decl (tree name, tree type, tree size)
       return error_mark_node;
     }
 
+  if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+    pedwarn (input_location, OPT_Wvla, "array of array of runtime bound");
+
   /* Figure out the index type for the array.  */
   if (size)
     itype = compute_array_index_type (name, size, tf_warning_or_error);
@@ -9720,6 +9723,12 @@ grokdeclarator (const cp_declarator *declarator,
                    : G_("cannot declare pointer to qualified function type %qT"),
                   type);
 
+         if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+           pedwarn (input_location, OPT_Wvla,
+                    declarator->kind == cdk_reference
+                    ? G_("reference to array of runtime bound")
+                    : G_("pointer to array of runtime bound"));
+
          /* When the pointed-to type involves components of variable size,
             care must be taken to ensure that the size evaluation code is
             emitted early enough to dominate all the possible later uses
@@ -10074,6 +10083,10 @@ grokdeclarator (const cp_declarator *declarator,
          type = error_mark_node;
        }
 
+      if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+       pedwarn (input_location, OPT_Wvla,
+                "typedef naming array of runtime bound");
+
       if (decl_context == FIELD)
        decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
       else
index dca34073d3eea823d39dc7324da53a016d420d8c..2cb2abd213fb78744b85960572c3e707bc246014 100644 (file)
@@ -11560,6 +11560,18 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
          r = cp_build_reference_type (type, TYPE_REF_IS_RVALUE (t));
        r = cp_build_qualified_type_real (r, cp_type_quals (t), complain);
 
+       if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+         {
+           if (complain & tf_warning_or_error)
+             pedwarn
+               (input_location, OPT_Wvla,
+                code == REFERENCE_TYPE
+                ? G_("cannot declare reference to array of runtime bound")
+                : G_("cannot declare pointer to array of runtime bound"));
+           else
+             r = error_mark_node;
+         }
+
        if (r != error_mark_node)
          /* Will this ever be needed for TYPE_..._TO values?  */
          layout_type (r);
index 4e7316560ec9d4c936265148c346087a3930f392..90104406dff28db4c2d1d41b44115f92644d41c1 100644 (file)
@@ -393,9 +393,12 @@ get_tinfo_decl (tree type)
 
   if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
     {
-      error ("cannot create type information for type %qT because "
-            "it involves types of variable size",
-            type);
+      if (array_of_runtime_bound_p (type))
+       error ("typeid of array of runtime bound");
+      else
+       error ("cannot create type information for type %qT because "
+              "it involves types of variable size",
+              type);
       return error_mark_node;
     }
 
index 591750315eb9c283acd48798daff661a2c4cf9ce..3e1a0bf281d48124085c8e3432e0ec278663a896 100644 (file)
@@ -5456,6 +5456,15 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p,
        }
     }
 
+  if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+    {
+      if (complain & tf_warning_or_error)
+       pedwarn (input_location, OPT_Wvla,
+                "taking decltype of array of runtime bound");
+      else
+       return error_mark_node;
+    }
+
   return type;
 }
 
index 47670f2a5d886af0d7219521e5315bdd27d2ea3a..df5fc4a880a10d70c1cd2237c12b357633a0fa7d 100644 (file)
@@ -1547,6 +1547,15 @@ cxx_sizeof_or_alignof_type (tree type, enum tree_code op, bool complain)
       return value;
     }
 
+  if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (type))
+    {
+      if (complain & tf_warning_or_error)
+       pedwarn (input_location, OPT_Wvla,
+                "taking sizeof array of runtime bound");
+      else
+       return error_mark_node;
+    }
+
   return c_sizeof_or_alignof_type (input_location, complete_type (type),
                                   op == SIZEOF_EXPR,
                                   complain);
@@ -5316,7 +5325,17 @@ cp_build_addr_expr_1 (tree arg, bool strict_lvalue, tsubst_flags_t complain)
     }
 
   if (argtype != error_mark_node)
-    argtype = build_pointer_type (argtype);
+    {
+      if (cxx_dialect >= cxx1y && array_of_runtime_bound_p (argtype))
+       {
+         if (complain & tf_warning_or_error)
+           pedwarn (input_location, OPT_Wvla,
+                    "taking address of array of runtime bound");
+         else
+           return error_mark_node;
+       }
+      argtype = build_pointer_type (argtype);
+    }
 
   /* In a template, we are processing a non-dependent expression
      so we can just form an ADDR_EXPR with the correct type.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/vla1.C b/gcc/testsuite/g++.dg/cpp1y/vla1.C
new file mode 100644 (file)
index 0000000..29a59ed
--- /dev/null
@@ -0,0 +1,40 @@
+// { dg-options "-std=c++1y -pedantic-errors" }
+
+#include <typeinfo>
+
+void f(int n)
+{
+  int a[n];
+  int aa[n][n];                        // { dg-error "" }
+  &a;                          // { dg-error "" }
+  sizeof a;                    // { dg-error "" }
+  typeid(a);                   // { dg-error "" }
+  decltype(a) a2;              // { dg-error "" }
+  typedef int at[n];           // { dg-error "" }
+  int (*p)[n];                 // { dg-error "" }
+  int (&r)[n] = a;             // { dg-error "" }
+  struct A
+  {
+    int a[n];                  // { dg-error "" }
+  };
+}
+
+template <class T>
+void g(int n)
+{
+  int a[n];
+  int aa[n][n];                        // { dg-error "" }
+  &a;                          // { dg-error "" }
+  sizeof a;                    // { dg-error "" }
+  typeid(a);                   // { dg-error "" }
+  decltype(a) a2;              // { dg-error "" }
+  typedef int at[n];           // { dg-error "" }
+  int (*p)[n];                 // { dg-error "" }
+  int (&r)[n] = a;             // { dg-error "" }
+  struct A
+  {
+    int a[n];                  // { dg-error "" }
+  };
+}
+
+template void g<int>(int);