From c579be2ae7a020d6005d84a5b6f24872ba8b1b05 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 22 Aug 2018 15:10:23 -0700
Subject: [PATCH v1 1/4] Require C99 (and thus MSCV 2013 upwards).

Author: Andres Freund
Discussion: https://postgr.es/m/97d4b165-192d-3605-749c-f614a0c4e783@2ndquadrant.com
---
 configure                        | 49 ++++++++++++++++++++++++++++++++
 configure.in                     | 10 +++++++
 doc/src/sgml/sources.sgml        | 33 ++++++++++++++-------
 src/tools/msvc/MSBuildProject.pm |  2 +-
 src/tools/msvc/README            |  6 ++--
 src/tools/msvc/build.pl          |  6 +---
 6 files changed, 86 insertions(+), 20 deletions(-)

diff --git a/configure b/configure
index 836d68dad37..dd439ddd2f6 100755
--- a/configure
+++ b/configure
@@ -4602,6 +4602,13 @@ if test "x$ac_cv_prog_cc_c99" != xno; then :
 fi
 
 
+
+# Error out if the compiler does not support C99, as the codebase
+# relies on that.
+if test "$ac_cv_prog_cc_c99" = no; then
+    as_fn_error $? "C compiler \"$CC\" does not support C99" "$LINENO" 5
+fi
+
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5361,6 +5368,48 @@ fi
 
 
   # -Wdeclaration-after-statement isn't applicable for C++
+  # Really don't want VLAs to be used in our dialect of C
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Werror=vla, for CFLAGS" >&5
+$as_echo_n "checking whether ${CC} supports -Werror=vla, for CFLAGS... " >&6; }
+if ${pgac_cv_prog_CC_cflags__Werror_vla+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_CFLAGS=$CFLAGS
+pgac_save_CC=$CC
+CC=${CC}
+CFLAGS="${CFLAGS} -Werror=vla"
+ac_save_c_werror_flag=$ac_c_werror_flag
+ac_c_werror_flag=yes
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  pgac_cv_prog_CC_cflags__Werror_vla=yes
+else
+  pgac_cv_prog_CC_cflags__Werror_vla=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_c_werror_flag=$ac_save_c_werror_flag
+CFLAGS="$pgac_save_CFLAGS"
+CC="$pgac_save_CC"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Werror_vla" >&5
+$as_echo "$pgac_cv_prog_CC_cflags__Werror_vla" >&6; }
+if test x"$pgac_cv_prog_CC_cflags__Werror_vla" = x"yes"; then
+  CFLAGS="${CFLAGS} -Werror=vla"
+fi
+
+
+  # -Wvla is not applicable for C++
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wendif-labels, for CFLAGS" >&5
 $as_echo_n "checking whether ${CC} supports -Wendif-labels, for CFLAGS... " >&6; }
diff --git a/configure.in b/configure.in
index 6e141064e5c..5869ab7c5bc 100644
--- a/configure.in
+++ b/configure.in
@@ -359,6 +359,13 @@ esac
 
 AC_PROG_CC([$pgac_cc_list])
 AC_PROG_CC_C99()
+
+# Error out if the compiler does not support C99, as the codebase
+# relies on that.
+if test "$ac_cv_prog_cc_c99" = no; then
+    AC_MSG_ERROR([C compiler "$CC" does not support C99])
+fi
+
 AC_PROG_CXX([$pgac_cxx_list])
 
 # Check if it's Intel's compiler, which (usually) pretends to be gcc,
@@ -477,6 +484,9 @@ if test "$GCC" = yes -a "$ICC" = no; then
   # These work in some but not all gcc versions
   PGAC_PROG_CC_CFLAGS_OPT([-Wdeclaration-after-statement])
   # -Wdeclaration-after-statement isn't applicable for C++
+  # Really don't want VLAs to be used in our dialect of C
+  PGAC_PROG_CC_CFLAGS_OPT([-Werror=vla])
+  # -Wvla is not applicable for C++
   PGAC_PROG_CC_CFLAGS_OPT([-Wendif-labels])
   PGAC_PROG_CXX_CFLAGS_OPT([-Wendif-labels])
   PGAC_PROG_CC_CFLAGS_OPT([-Wmissing-format-attribute])
diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml
index e53ee1dc6ad..419f753c7bc 100644
--- a/doc/src/sgml/sources.sgml
+++ b/doc/src/sgml/sources.sgml
@@ -867,19 +867,30 @@ BETTER: unrecognized node type: 42
     <title>C Standard</title>
     <para>
      Code in <productname>PostgreSQL</productname> should only rely on language
-     features available in the C89 standard. That means a conforming
-     C89 compiler has to be able to compile postgres, at least aside
-     from a few platform dependent pieces. Features from later
-     revision of the C standard or compiler specific features can be
-     used, if a fallback is provided.
+     features available in the C99 standard. That means a conforming
+     C99 compiler has to be able to compile postgres, at least aside
+     from a few platform dependent pieces.
     </para>
     <para>
-     For example <literal>static inline</literal> and
-     <literal>_StaticAssert()</literal> are currently used, even
-     though they are from newer revisions of the C standard. If not
-     available we respectively fall back to defining the functions
-     without inline, and to using a C89 compatible replacement that
-     performs the same checks, but emits rather cryptic messages.
+     A few features included in the C99 standard are, at this time, not be
+     permitted to be used in core <productname>PostgreSQL</productname>
+     code. This currently includes variable length arrays, intermingled
+     declarations and code, <literal>//</literal> comments, universal
+     character names. Reasons for that include portability and historical
+     practices.
+    </para>
+    <para>
+     Features from later revision of the C standard or compiler specific
+     features can be used, if a fallback is provided.
+    </para>
+    <para>
+     For example <literal>_StaticAssert()</literal> and
+     <literal>__builtin_constant_p</literal> are currently used, even though
+     they are from newer revisions of the C standard and a
+     <productname>GCC</productname> extension respectively. If not available
+     we respectively fall back to using a C99 compatible replacement that
+     performs the same checks, but emits rather cryptic messages and do not
+     use <literal>__builtin_constant_p</literal>.
     </para>
    </simplesect>
 
diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index 47252533a1b..dd6a610e5b2 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -1,7 +1,7 @@
 package MSBuildProject;
 
 #
-# Package that encapsulates a MSBuild project file (Visual C++ 2010 or greater)
+# Package that encapsulates a MSBuild project file (Visual C++ 2013 or greater)
 #
 # src/tools/msvc/MSBuildProject.pm
 #
diff --git a/src/tools/msvc/README b/src/tools/msvc/README
index bfa98045f22..2827d76b2d1 100644
--- a/src/tools/msvc/README
+++ b/src/tools/msvc/README
@@ -67,7 +67,7 @@ Install.pm             module containing the install logic
 Mkvcbuild.pm           module containing the code to generate the Visual
                        Studio build (project/solution) files
 MSBuildProject.pm      module containing the code to generate MSBuild based
-                       project files (Visual Studio 2010 or greater)
+                       project files (Visual Studio 2013 or greater)
 Project.pm             module containing the common code to generate the
                        Visual Studio project files. Also provides the
                        common interface of all project file generators
@@ -99,5 +99,5 @@ VC2010Project or VC2012Project or VC2013Project or VC2015Project or VC2017Projec
 from MSBuildProject.pm) to it.
 When Solution::Save is called, the implementations of Solution and Project
 save their content in the appropriate format.
-The final step of starting the appropriate build program (msbuild or vcbuild)
-is performed in build.pl again.
+The final step of starting the appropriate build program (msbuild) is
+performed in build.pl again.
diff --git a/src/tools/msvc/build.pl b/src/tools/msvc/build.pl
index 9a234d1cc25..35649fe5a24 100644
--- a/src/tools/msvc/build.pl
+++ b/src/tools/msvc/build.pl
@@ -53,16 +53,12 @@ elsif (uc($ARGV[0]) ne "RELEASE")
 
 # ... and do it
 
-if ($buildwhat and $vcver >= 10.00)
+if ($buildwhat)
 {
 	system(
 		"msbuild $buildwhat.vcxproj /verbosity:normal $msbflags /p:Configuration=$bconf"
 	);
 }
-elsif ($buildwhat)
-{
-	system("vcbuild $msbflags $buildwhat.vcproj $bconf");
-}
 else
 {
 	system(
-- 
2.18.0.rc2.dirty

