]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c/39564
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Apr 2009 18:55:50 +0000 (18:55 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Apr 2009 18:55:50 +0000 (18:55 +0000)
* c-decl.c (grokdeclarator): Diagnose declarations of functions
with variably modified return type and no storage class
specifiers, except for the case of nested functions.  Distinguish
extern declarations of functions with variably modified return
types from those of objects with variably modified types.

testsuite:
* gcc.dg/vla-19.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146778 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vla-19.c [new file with mode: 0644]

index 47f98fa95cca95733f65dd03d8c861737ba397b8..c3a2d00dab76e469d4e674fbe173cb9cfa8e430c 100644 (file)
@@ -1,3 +1,12 @@
+2009-04-25  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/39564
+       * c-decl.c (grokdeclarator): Diagnose declarations of functions
+       with variably modified return type and no storage class
+       specifiers, except for the case of nested functions.  Distinguish
+       extern declarations of functions with variably modified return
+       types from those of objects with variably modified types.
+
 2009-04-25  Jan Hubicka  <jh@suse.cz>
 
        * tree.c (list_equal_p): New function.
index d2dbfbeea81f2bc3bdf30165c65dded9d79d3584..9693a342a8f6602c6f9da2a5d34cc8a2f1099514 100644 (file)
@@ -5012,11 +5012,17 @@ grokdeclarator (const struct c_declarator *declarator,
          DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
       }
 
-    if (storage_class == csc_extern
+    if ((storage_class == csc_extern
+        || (storage_class == csc_none
+            && TREE_CODE (type) == FUNCTION_TYPE
+            && !funcdef_flag))
        && variably_modified_type_p (type, NULL_TREE))
       {
        /* C99 6.7.5.2p2 */
-       error ("object with variably modified type must have no linkage");
+       if (TREE_CODE (type) == FUNCTION_TYPE)
+         error ("non-nested function with variably modified type");
+       else
+         error ("object with variably modified type must have no linkage");
       }
 
     /* Record `register' declaration for warnings on &
index f2fdc93c4bde4dcae3f097fde867624d42e323e1..c9cfd92fa3a1230a01f5259366c8f4c732291ec2 100644 (file)
@@ -1,3 +1,8 @@
+2009-04-25  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/39564
+       * gcc.dg/vla-19.c: New test.
+
 2009-04-25  Joseph Myers  <joseph@codesourcery.com>
 
        PR preprocessor/39559
diff --git a/gcc/testsuite/gcc.dg/vla-19.c b/gcc/testsuite/gcc.dg/vla-19.c
new file mode 100644 (file)
index 0000000..83093c9
--- /dev/null
@@ -0,0 +1,32 @@
+/* Test diagnostics for variably modified function return types.  PR
+   39564.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+int a;
+
+void
+f1 (void)
+{
+  typedef int T[a];
+  extern T *g1 (void); /* { dg-error "non-nested function with variably modified type" } */
+}
+
+void
+f2 (void)
+{
+  extern int (*g2 (void))[a]; /* { dg-error "non-nested function with variably modified type" } */
+}
+
+void
+f3 (void)
+{
+  typedef int T[a];
+  T *g3 (void); /* { dg-error "non-nested function with variably modified type" } */
+}
+
+void
+f4 (void)
+{
+  int (*g4 (void))[a]; /* { dg-error "non-nested function with variably modified type" } */
+}