summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-25 18:55:50 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2009-04-25 18:55:50 +0000
commit1d9b9611bc178377b246f471c651ffe80b631e0d (patch)
tree37e3ee9a7eeffd28c6d57a7ad6c934131c358b1b
parent9c6183ddd1c8f33f9994bfc954c0ecc1e638b5cc (diff)
downloadgcc-1d9b9611bc178377b246f471c651ffe80b631e0d.tar.gz
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. 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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-decl.c10
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/vla-19.c32
4 files changed, 54 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 47f98fa95cc..c3a2d00dab7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index d2dbfbeea81..9693a342a8f 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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 &
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f2fdc93c4bd..c9cfd92fa3a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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
* gcc.dg/c99-intconst-2.c: New test.
diff --git a/gcc/testsuite/gcc.dg/vla-19.c b/gcc/testsuite/gcc.dg/vla-19.c
new file mode 100644
index 00000000000..83093c9291a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vla-19.c
@@ -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" } */
+}