Visual Studio 2015 version "14.0.25431.01 Update 3" has an apparent compiler
bug that causes the build to fail with "readfuncs.switch.c(522): fatal error
C1026: parser stack overflow, program too complex (compiling source file
src/backend/nodes/readfuncs.c)".  While I wouldn't mind revoking support for
Visual Studio 2015, changing the code to cope is easy.  See attached.
https://stackoverflow.com/a/34266725/16371536 asserts having confirmation of
the compiler bug, but its reference is now a dead link.  This became a problem
in v16 due to the 135% increase in node types known to parseNodeString().

https:/postgr.es/m/20221124004144.iosgze2qnmcct...@awork3.anarazel.de
previously reported this error message when overriding USE_READLINE in a
Visual Studio build, for tab-complete.c.  If that combination ever becomes
supported, we may face a similar decision there.
Author:     Noah Misch <n...@leadboat.com>
Commit:     Noah Misch <n...@leadboat.com>

    Make parseNodeString() C idiom compatible with Visual Studio 2015.
    
    Between v15 and now, this function's "else if" chain grew from 252 lines
    to 592 lines, exceeding a compiler limit that manifests as "fatal error
    C1026: parser stack overflow, program too complex (compiling source file
    src/backend/nodes/readfuncs.c)".  Use "if (...)  return ...;" instead.
    
    Reviewed by FIXME.
    
    Discussion: https://postgr.es/m/FIXME

diff --git a/src/backend/nodes/gen_node_support.pl 
b/src/backend/nodes/gen_node_support.pl
index b89b491..72c7963 100644
--- a/src/backend/nodes/gen_node_support.pl
+++ b/src/backend/nodes/gen_node_support.pl
@@ -924,9 +924,9 @@ foreach my $n (@node_types)
          . "\t\t\t\t_out${n}(str, obj);\n"
          . "\t\t\t\tbreak;\n";
 
-       print $rfs "\telse if (MATCH(\"$N\", "
+       print $rfs "\tif (MATCH(\"$N\", "
          . length($N) . "))\n"
-         . "\t\treturn_value = _read${n}();\n"
+         . "\t\treturn (Node *) _read${n}();\n"
          unless $no_read;
 
        next if elem $n, @custom_read_write;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 597e5b3..df72dc3 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -696,8 +696,6 @@ _readExtensibleNode(void)
 Node *
 parseNodeString(void)
 {
-       void       *return_value;
-
        READ_TEMP_LOCALS();
 
        /* Guard against stack overflow due to overly complex expressions */
@@ -708,16 +706,10 @@ parseNodeString(void)
 #define MATCH(tokname, namelen) \
        (length == namelen && memcmp(token, tokname, namelen) == 0)
 
-       if (false)
-               ;
 #include "readfuncs.switch.c"
-       else
-       {
-               elog(ERROR, "badly formatted node string \"%.32s\"...", token);
-               return_value = NULL;    /* keep compiler quiet */
-       }
 
-       return (Node *) return_value;
+       elog(ERROR, "badly formatted node string \"%.32s\"...", token);
+       return NULL;                            /* keep compiler quiet */
 }
 
 

Reply via email to