From 5017c39da23644228b7f44f84f4c0051947dfeb6 Mon Sep 17 00:00:00 2001 From: Iain Sandoe Date: Tue, 24 Dec 2019 15:37:13 +0000 Subject: [PATCH] [C] Allow const vars to be used in array sizes [PR93082]. This allows us to consume some MacOS headers that expect this clang extension to be present. PR target/93082 gcc/c-family/ChangeLog: * c.opt (flag_allow_const_var_array_size): New. gcc/c/ChangeLog: * c-decl.cc (grokdeclarator): Allow const vars to be used as array sizes. gcc/ChangeLog: * config/darwin.cc (darwin_override_options): Default flag_allow_const_var_array_size on. gcc/testsuite/ChangeLog: * c-c++-common/pr58346-3.c: Disable const var array size extension on Darwin. * gcc.dg/vla-init-2.c: Likewise. * gcc.dg/vla-init-4.c: Likewise. * gcc.dg/vla-init-5.c: Likewise. * gcc.misc-tests/gcov-pr85350.c: Likewise. Signed-off-by: Iain Sandoe t --- gcc/c-family/c.opt | 4 ++++ gcc/c/c-decl.cc | 22 +++++++++++++++++++++ gcc/config/darwin.cc | 4 ++++ gcc/testsuite/c-c++-common/pr58346-3.c | 1 + gcc/testsuite/gcc.dg/vla-init-2.c | 1 + gcc/testsuite/gcc.dg/vla-init-4.c | 1 + gcc/testsuite/gcc.dg/vla-init-5.c | 1 + gcc/testsuite/gcc.misc-tests/gcov-pr85350.c | 1 + 8 files changed, 35 insertions(+) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 75b6531860e..abe758bba24 100644 --- gcc/c-family/c.opt +++ gcc/c-family/c.opt @@ -1806,6 +1806,10 @@ static-libmpxwrappers Driver WarnRemoved Removed in GCC 9. This switch has no effect. +fallow-const-var-array-size +C ObjC C++ ObjC++ LTO Var(flag_allow_const_var_array_size) Init(0) +Allow arrays sizes to be const-qualified vars in C and Objective-C. + fcilkplus C ObjC C++ ObjC++ LTO Undocumented Ignore Removed in GCC 8. This switch has no effect. diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index c778c7febfa..b3da099a2d0 100644 --- gcc/c/c-decl.cc +++ gcc/c/c-decl.cc @@ -7358,6 +7358,25 @@ grokdeclarator (const struct c_declarator *declarator, } size = c_fully_fold (size, false, &size_maybe_const); + bool size_const_var = false; + if (flag_allow_const_var_array_size) + { + tree maybe_const_size = TREE_CODE (size) == NOP_EXPR + ? TREE_OPERAND (size, 0) : size; + size_const_var + = (TREE_CODE (maybe_const_size) == VAR_DECL + && TREE_READONLY (maybe_const_size) + && !TREE_THIS_VOLATILE (maybe_const_size)); + if (size_const_var + && size_maybe_const + && DECL_INITIAL (maybe_const_size)) + { + size = DECL_INITIAL (maybe_const_size); + size = c_fully_fold (size, false, &size_maybe_const); + size_int_const = (TREE_CODE (size) == INTEGER_CST + && !TREE_OVERFLOW (size)); + } + } if (pedantic && size_maybe_const && integer_zerop (size)) { @@ -7399,6 +7418,9 @@ grokdeclarator (const struct c_declarator *declarator, this_size_varies = size_varies = true; warn_variable_length_array (name, size); } + if (flag_allow_const_var_array_size && size_const_var) + pedwarn (input_location, OPT_Wpedantic, + "variably modified %qE at file scope", name); } else if ((decl_context == NORMAL || decl_context == FIELD) && current_scope == file_scope) diff --git a/gcc/config/darwin.cc b/gcc/config/darwin.cc index be2daed4f66..56247e579bc 100644 --- gcc/config/darwin.cc +++ gcc/config/darwin.cc @@ -3592,6 +3592,10 @@ darwin_override_options (void) /* The c_dialect...() macros are not available to us here. */ darwin_running_cxx = (strstr (lang_hooks.name, "C++") != 0); + + /* Allow the clang extension to permit const vars used in array sizes. */ + if (!OPTION_SET_P (flag_allow_const_var_array_size)) + flag_allow_const_var_array_size = true; } #if DARWIN_PPC diff --git a/gcc/testsuite/c-c++-common/pr58346-3.c b/gcc/testsuite/c-c++-common/pr58346-3.c index 41627ed953c..b3d35ce0d31 100644 --- gcc/testsuite/c-c++-common/pr58346-3.c +++ gcc/testsuite/c-c++-common/pr58346-3.c @@ -1,5 +1,6 @@ /* PR c/58346 */ /* { dg-do compile } */ +/* { dg-additional-options "-fno-allow-const-var-array-size" { target *-*-darwin* } } */ void foo (void) diff --git a/gcc/testsuite/gcc.dg/vla-init-2.c b/gcc/testsuite/gcc.dg/vla-init-2.c index f23630a3657..b6e6f6eaece 100644 --- gcc/testsuite/gcc.dg/vla-init-2.c +++ gcc/testsuite/gcc.dg/vla-init-2.c @@ -4,6 +4,7 @@ testcase. */ /* { dg-do compile } */ /* { dg-options "" } */ +/* { dg-additional-options "-fno-allow-const-var-array-size" { target *-*-darwin* } } */ const int i = 1; void foo() { char a[][i] = {""}; } /* { dg-error "variable-sized object may not be initialized" } */ diff --git a/gcc/testsuite/gcc.dg/vla-init-4.c b/gcc/testsuite/gcc.dg/vla-init-4.c index 06351d04e03..43d5d8cbfc8 100644 --- gcc/testsuite/gcc.dg/vla-init-4.c +++ gcc/testsuite/gcc.dg/vla-init-4.c @@ -2,6 +2,7 @@ /* Origin: Joseph Myers */ /* { dg-do compile } */ /* { dg-options "" } */ +/* { dg-additional-options "-fno-allow-const-var-array-size" { target *-*-darwin* } } */ const int i = 1; void foo() { char *p = (char [i]){ "" }; } /* { dg-error "compound literal has variable size" } */ diff --git a/gcc/testsuite/gcc.dg/vla-init-5.c b/gcc/testsuite/gcc.dg/vla-init-5.c index aa9f4910ac9..500854d83a3 100644 --- gcc/testsuite/gcc.dg/vla-init-5.c +++ gcc/testsuite/gcc.dg/vla-init-5.c @@ -2,6 +2,7 @@ /* Origin: Joseph Myers */ /* { dg-do compile } */ /* { dg-options "" } */ +/* { dg-additional-options "-fno-allow-const-var-array-size" { target *-*-darwin* } } */ const int i = 1; void foo() { void *p = (char [][i]){ "" }; } /* { dg-error "compound literal has variable size" } */ diff --git a/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c b/gcc/testsuite/gcc.misc-tests/gcov-pr85350.c index 0383b81fdfb..57d4d6a90a7 100644 --- gcc/testsuite/gcc.misc-tests/gcov-pr85350.c +++ gcc/testsuite/gcc.misc-tests/gcov-pr85350.c @@ -1,5 +1,6 @@ /* { dg-options "-fprofile-arcs -ftest-coverage" } */ /* { dg-do run { target native } } */ +/* { dg-additional-options "-fno-allow-const-var-array-size" { target *-*-darwin* } } */ int main (void) {