diff --git a/libc/calls/tcgetwinsize.c b/libc/calls/tcgetwinsize.c
index 32eb6f63c..efa1b067f 100644
--- a/libc/calls/tcgetwinsize.c
+++ b/libc/calls/tcgetwinsize.c
@@ -34,7 +34,6 @@
 int tcgetwinsize(int fd, struct winsize *ws) {
   int rc;
   if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) {
-    ws = 0;
     rc = efault();
   } else if (fd >= 0) {
     if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
diff --git a/third_party/gcc/README.cosmo b/third_party/gcc/README.cosmo
index dbe836485..4ec2cb051 100644
--- a/third_party/gcc/README.cosmo
+++ b/third_party/gcc/README.cosmo
@@ -12,17 +12,16 @@ ORIGIN
 
   @ahgamut's musl-cross-make fork
   https://github.com/ahgamut/musl-cross-make/
-  d0f33e2162cf5e5b30cdf3b3accc0d0f7756830c
+  e58abc1110b335a3341e8ad5821ad8e3880d9bb2
 
 MODIFICATIONS
 
   ahgamut's musl-cross-make fork includes a 2kLOC patch that modifies
   GCC so it'll compile C code like `switch(errno){case EINVAL: etc.}`
-
-SEE ALSO
-
-  third_party/gcc/portcosmo.patch
+  see third_party/gcc/portcosmo.patch for GCC 11.2.0 for our changes
 
 NOTES
 
-  My name is Justine Tunney and I approve of these binaries.
+  These binaries were compiled by Justine Tunney. You have the freedom
+  to obtain the original source source code, apply our patch, and enjoy
+  all the freedoms promised to you by the GNU General Public License.
diff --git a/third_party/gcc/portcosmo.patch b/third_party/gcc/portcosmo.patch
index 48480095f..b5f5301f0 100644
--- a/third_party/gcc/portcosmo.patch
+++ b/third_party/gcc/portcosmo.patch
@@ -1,1869 +1,1910 @@
-commit d0f33e2162cf5e5b30cdf3b3accc0d0f7756830c
-Author: Gautham <ahgamut@gmail.com>
-Date:   Sun Jun 4 22:42:41 2023 -0500
-
-    enable patching errno constants with -fportcosmo
-    
-    https://github.com/ahgamut/gcc/tree/portcosmo-11.2
-    
-    diff the above fork with gcc-11.2.0 to get the diff in this commit. the
-    patched gcc allows using Cosmopolitan magic numbers in switch cases and
-    struct initializations in the following way:
-    
-    - build gcc using this patch
-    
-    - if ENOSYS is in your switch case, define a value in a separate header
-      as follows:
-    
-      static const int __tmpcosmo_ENOSYS = -23486391; // any value
-    
-    - pass the -fportcosmo flag when compiling your file, and include the
-      header containing the above temporary values
-    
-    - the patched gcc will do the necessary AST transformation so that the
-      actual ENOSYS value is used.
-
-diff --git a/patches/gcc-11.2.0/0006-portcosmo.diff b/patches/gcc-11.2.0/0006-portcosmo.diff
-new file mode 100644
-index 0000000..1700611
---- /dev/null
-+++ b/patches/gcc-11.2.0/0006-portcosmo.diff
-@@ -0,0 +1,1838 @@
-+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-+index 8a5fb3fd9..3a7498db8 100644
-+--- a/gcc/Makefile.in
-++++ b/gcc/Makefile.in
-+@@ -1231,6 +1231,10 @@ GCC_OBJS = gcc.o gcc-main.o ggc-none.o
-+ 
-+ c-family-warn = $(STRICT_WARN)
-+ 
-++PORTCOSMO_OBJS = c-family/portcosmo.o c-family/subcontext.o\
-++				 c-family/initstruct.o c-family/ifswitch.o \
-++                 c-family/unpatch_int.o c-family/unpatch_ast.o
-++
-+ # Language-specific object files shared by all C-family front ends.
-+ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
-+   c-family/c-format.o c-family/c-gimplify.o c-family/c-indentation.o \
-+@@ -1238,7 +1242,8 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
-+   c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
-+   c-family/c-semantics.o c-family/c-ada-spec.o \
-+   c-family/c-ubsan.o c-family/known-headers.o \
-+-  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o
-++  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o \
-++  $(PORTCOSMO_OBJS)
-+ 
-+ # Analyzer object files
-+ ANALYZER_OBJS = \
-+diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
-+index d227686a0..a1d4c81ec 100644
-+--- a/gcc/c-family/c-common.c
-++++ b/gcc/c-family/c-common.c
-+@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
-+ #include "c-spellcheck.h"
-+ #include "selftest.h"
-+ #include "debug.h"
-++#include "c-family/portcosmo.h"
-+ 
-+ cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
-+ 
-+@@ -2112,8 +2113,16 @@ check_case_value (location_t loc, tree value)
-+     value = perform_integral_promotions (value);
-+   else if (value != error_mark_node)
-+     {
-+-      error_at (loc, "case label does not reduce to an integer constant");
-+-      value = error_mark_node;
-++      if (flag_portcosmo) {
-++          value = patch_case_nonconst(loc, value);
-++          if (value == NULL_TREE) {
-++            error_at (loc, "case label does not reduce to an integer constant");
-++            value = error_mark_node;
-++          }
-++      } else {
-++            error_at (loc, "case label does not reduce to an integer constant");
-++            value = error_mark_node;
-++      }
-+     }
-+ 
-+   constant_expression_warning (value);
-+diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
-+index 89e05a4c5..bf1d8b445 100644
-+--- a/gcc/c-family/c-opts.c
-++++ b/gcc/c-family/c-opts.c
-+@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
-+ #include "mkdeps.h"
-+ #include "dumpfile.h"
-+ #include "file-prefix-map.h"    /* add_*_prefix_map()  */
-++#include "c-family/portcosmo.h"
-+ 
-+ #ifndef DOLLARS_IN_IDENTIFIERS
-+ # define DOLLARS_IN_IDENTIFIERS true
-+@@ -1196,6 +1197,11 @@ c_common_init (void)
-+       return false;
-+     }
-+ 
-++  if (flag_portcosmo)
-++    {
-++        portcosmo_setup();
-++    }
-++
-+   return true;
-+ }
-+ 
-+@@ -1281,6 +1287,10 @@ c_common_finish (void)
-+   /* For performance, avoid tearing down cpplib's internal structures
-+      with cpp_destroy ().  */
-+   cpp_finish (parse_in, deps_stream);
-++  if(flag_portcosmo) 
-++    {
-++        portcosmo_teardown();
-++    }
-+ 
-+   if (deps_stream && deps_stream != out_stream && deps_stream != stdout
-+       && (ferror (deps_stream) || fclose (deps_stream)))
-+@@ -1288,6 +1298,7 @@ c_common_finish (void)
-+ 
-+   if (out_stream && (ferror (out_stream) || fclose (out_stream)))
-+     fatal_error (input_location, "when writing output to %s: %m", out_fname);
-++
-+ }
-+ 
-+ /* Either of two environment variables can specify output of
-+diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
-+index 2005b783c..a69a9a349 100644
-+--- a/gcc/c-family/c.opt
-++++ b/gcc/c-family/c.opt
-+@@ -1881,6 +1881,10 @@ fopenmp-simd
-+ C ObjC C++ ObjC++ Var(flag_openmp_simd)
-+ Enable OpenMP's SIMD directives.
-+ 
-++fportcosmo
-++C C++ RejectNegative Var(flag_portcosmo)
-++Enable AST rewriting for Cosmopolitan Libc magic numbers.
-++
-+ foperator-names
-+ C++ ObjC++
-+ Recognize C++ keywords like \"compl\" and \"xor\".
-+diff --git a/gcc/c-family/ifswitch.cc b/gcc/c-family/ifswitch.cc
-+new file mode 100644
-+index 000000000..148b2c2b4
-+--- /dev/null
-++++ b/gcc/c-family/ifswitch.cc
-+@@ -0,0 +1,236 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/ifswitch.h"
-++
-++static tree get_switch_body(tree swexpr) {
-++  auto body = SWITCH_STMT_BODY(swexpr);
-++  if (TREE_CODE(body) == BIND_EXPR) {
-++    body = BIND_EXPR_BODY(body);
-++  }
-++  return body;
-++}
-++
-++source_range get_switch_bounds(tree sws) {
-++  auto body = get_switch_body(sws);
-++  source_range rng;
-++  rng.m_start = MAX_LOCATION_T;
-++  rng.m_finish = MAX_LOCATION_T;
-++  if (STATEMENT_LIST_HEAD(body) && STATEMENT_LIST_TAIL(body)) {
-++    /* otherwise this is an empty switch statement */
-++    auto rng1 = EXPR_LOCATION_RANGE(STATEMENT_LIST_HEAD(body)->stmt);
-++    auto rng2 = EXPR_LOCATION_RANGE(STATEMENT_LIST_TAIL(body)->stmt);
-++    rng.m_start = rng1.m_start;
-++    rng.m_finish = rng2.m_finish;
-++  }
-++  return rng;
-++}
-++
-++unsigned int count_mods_in_switch(tree swexpr, subu_list *list) {
-++  tree body = get_switch_body(swexpr);
-++  tree t = NULL_TREE;
-++  tree replacement = NULL_TREE;
-++  subu_node *use = NULL;
-++  unsigned int count = 0;
-++  for (auto i = tsi_start(body); !tsi_end_p(i); tsi_next(&i)) {
-++    t = tsi_stmt(i);
-++    if (TREE_CODE(t) == CASE_LABEL_EXPR) {
-++      if (get_subu_elem(list, EXPR_LOCATION(t),
-++                        &use)          /* on a line we substituted */
-++          && CASE_LOW(t) != NULL_TREE  /* not a x..y range */
-++          && CASE_HIGH(t) == NULL_TREE /* not a default */
-++          && arg_should_be_unpatched(CASE_LOW(t), use, &replacement)
-++          /* the case is the one we substituted */) {
-++        DEBUGF("we substituted a case label at %u,%u\n", EXPR_LOC_LINE(t),
-++               EXPR_LOC_COL(t));
-++        // debug_tree(CASE_LOW(t));
-++        count += 1;
-++      }
-++    }
-++  }
-++  return count;
-++}
-++
-++tree build_modded_label(unsigned int swcount, const char *case_str,
-++                        location_t loc = UNKNOWN_LOCATION) {
-++  char dest[STRING_BUFFER_SIZE] = {0};
-++  snprintf(dest, sizeof(dest), "__tmpcosmo_%u_%s", swcount, case_str);
-++  tree lab = build_decl(loc, LABEL_DECL, get_identifier(dest), void_type_node);
-++  /* gcc's GIMPLE needs to know that this label
-++   * is within the current function declaration */
-++  DECL_CONTEXT(lab) = current_function_decl;
-++  return build1(LABEL_EXPR, void_type_node, lab);
-++}
-++
-++tree build_modded_exit_label(unsigned int swcount) {
-++  return build_modded_label(swcount, "__end");
-++}
-++
-++static inline tree build_modded_if_stmt(tree condition, tree then_clause,
-++                                        tree else_clause = NULL_TREE) {
-++  return build3(COND_EXPR, void_type_node, condition, then_clause, else_clause);
-++}
-++
-++tree modded_case_label(tree t, unsigned int i, tree swcond, vec<tree> *&ifs,
-++                       SubContext *ctx, tree *default_label) {
-++  // debug_tree(t);
-++  tree result;
-++  tree replacement = NULL_TREE;
-++  subu_node *use = NULL;
-++  char case_str[STRING_BUFFER_SIZE] = {0};
-++
-++  if (CASE_LOW(t) == NULL_TREE) {
-++    DEBUGF("default case\n");
-++    /* default label of the switch case, needs to be last */
-++    result = build_modded_label(ctx->switchcount, "__dflt", EXPR_LOCATION(t));
-++    *default_label = result;
-++  } else if (CASE_LOW(t) != NULL_TREE && CASE_HIGH(t) == NULL_TREE) {
-++    /* a case label */
-++    if (get_subu_elem(ctx->mods, EXPR_LOCATION(t), &use)
-++        /* the case is on a line we substituted */
-++        && arg_should_be_unpatched(CASE_LOW(t), use, &replacement)
-++        /* the case value is the one we substituted */) {
-++      DEBUGF("modded case\n");
-++      result =
-++          build_modded_label(ctx->switchcount, use->name, EXPR_LOCATION(t));
-++      ifs->safe_push(build_modded_if_stmt(
-++          build2(EQ_EXPR, integer_type_node, swcond, replacement),
-++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
-++      remove_subu_elem(ctx->mods, use);
-++      replacement = NULL_TREE;
-++    } else {
-++      /* a case label that we didn't substitute */
-++      DEBUGF("unmodded case\n");
-++      snprintf(case_str, sizeof(case_str), "%x_", i);
-++      result = build_modded_label(ctx->switchcount, case_str, EXPR_LOCATION(t));
-++      ifs->safe_push(build_modded_if_stmt(
-++          build2(EQ_EXPR, integer_type_node, swcond, CASE_LOW(t)),
-++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
-++    }
-++  } else {
-++    DEBUGF("unmodded case range\n");
-++    /* CASE_LOW(t) != NULL_TREE && CASE_HIGH(t) != NULL_TREE */
-++    /* this is a case x .. y sort of range */
-++    snprintf(case_str, sizeof(case_str), "%x_", i);
-++    result = build_modded_label(ctx->switchcount, case_str, EXPR_LOCATION(t));
-++    ifs->safe_push(build_modded_if_stmt(
-++        build2(TRUTH_ANDIF_EXPR, integer_type_node,
-++               build2(GE_EXPR, integer_type_node, swcond, CASE_LOW(t)),
-++               build2(LE_EXPR, integer_type_node, swcond, CASE_HIGH(t))),
-++        build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
-++  }
-++  return result;
-++}
-++
-++tree build_modded_switch_stmt(tree swexpr, SubContext *ctx) {
-++  int case_count = 0, break_count = 0;
-++  int has_default = 0;
-++
-++  tree swcond = save_expr(SWITCH_STMT_COND(swexpr));
-++  tree swbody = get_switch_body(swexpr);
-++  tree *tp = NULL;
-++  char dest[STRING_BUFFER_SIZE] = {0};
-++
-++  vec<tree> *ifs;
-++  vec_alloc(ifs, 0);
-++
-++  tree exit_label = build_modded_exit_label(ctx->switchcount);
-++  tree default_label = NULL_TREE;
-++
-++  for (auto it = tsi_start(swbody); !tsi_end_p(it); tsi_next(&it)) {
-++    tp = tsi_stmt_ptr(it);
-++    if (TREE_CODE(*tp) == CASE_LABEL_EXPR) {
-++      case_count += 1;
-++      has_default = has_default || (CASE_LOW(*tp) == NULL_TREE);
-++      /* replace the case statement with a goto */
-++      *tp =
-++          modded_case_label(*tp, case_count, swcond, ifs, ctx, &default_label);
-++    } else if (TREE_CODE(*tp) == BREAK_STMT) {
-++      break_count += 1;
-++      /* replace the break statement with a goto to the end */
-++      *tp = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
-++    } else if (TREE_CODE(*tp) == BIND_EXPR) {
-++      for (auto it2 = tsi_start(BIND_EXPR_BODY(*tp)); !tsi_end_p(it2);
-++           tsi_next(&it2)) {
-++        auto tp2 = tsi_stmt_ptr(it2);
-++        if (TREE_CODE(*tp2) == BREAK_STMT) {
-++          break_count += 1;
-++          /* replace the break statement with a goto to the end */
-++          *tp2 =
-++              build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
-++        }
-++      }
-++    }
-++  }
-++  /* add all the if statements to the start of the switch body */
-++  /* TODO: do we have to combine them via COND_EXPR_ELSE? why,
-++   * is it not possible to just them as a list one after the other? */
-++  tree res;
-++  unsigned int zz = 0;
-++  if (ifs->length() > 0) {
-++    res = (*ifs)[0];
-++    for (zz = 1; zz < ifs->length(); ++zz) {
-++      COND_EXPR_ELSE(res) = (*ifs)[zz];
-++      res = (*ifs)[zz];
-++    }
-++    /* if we have a valid default for the switch,
-++     * it should be the final else branch */
-++    if (default_label && default_label != NULL_TREE) {
-++      COND_EXPR_ELSE(res) =
-++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(default_label));
-++    } else {
-++      /* if we don't have a default, then the final else branch
-++       * should just jump to after the switch */
-++        COND_EXPR_ELSE(res) =
-++              build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
-++    }
-++    /* reset to the start of the if-else tree */
-++    res = (*ifs)[0];
-++  } else if (has_default && default_label != NULL_TREE) {
-++    /* this switch has only a default? ok... */
-++    res = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(default_label));
-++  } else {
-++    /* this switch has no cases, and no default?! */
-++    warning_at(EXPR_LOCATION(swcond), 0, "switch without cases or default?");
-++    res = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
-++  }
-++  auto it = tsi_start(swbody);
-++  tsi_link_before(&it, res, TSI_SAME_STMT);
-++  tsi_link_before(&it, build_empty_stmt(UNKNOWN_LOCATION), TSI_SAME_STMT);
-++
-++  /* add the 'outside' of the switch, ie the 'finally'
-++   * aka the target of the break statements, the 'exit_label',
-++   * to the end of the switch body */
-++  append_to_statement_list(build_empty_stmt(UNKNOWN_LOCATION), &swbody);
-++  append_to_statement_list(exit_label, &swbody);
-++  append_to_statement_list(build_empty_stmt(UNKNOWN_LOCATION), &swbody);
-++  /*
-++  snprintf(dest, sizeof(dest),
-++           "above switch had %d cases replaced and %d breaks\n", case_count,
-++           break_count);
-++  append_to_statement_list(build_call_expr(VAR_NAME_AS_TREE("printf"), 1,
-++                                           BUILD_STRING_AS_TREE(dest)),
-++                           &swbody); */
-++
-++  /* debug_tree(swbody); */
-++  /* we are returning SWITCH_STMT_BODY(swexpr),
-++   * instead of just swbody, because sometimes,
-++   * SWITCH_STMT_BODY(swexpr) may be a BIND_EXPR
-++   * that has some scoping-related information. */
-++  return SWITCH_STMT_BODY(swexpr);
-++}
-+diff --git a/gcc/c-family/ifswitch.h b/gcc/c-family/ifswitch.h
-+new file mode 100644
-+index 000000000..ccf78067f
-+--- /dev/null
-++++ b/gcc/c-family/ifswitch.h
-+@@ -0,0 +1,10 @@
-++#ifndef IFSWITCH_H
-++#define IFSWITCH_H
-++#include "c-family/portcosmo.internal.h"
-++#include "c-family/subcontext.h"
-++
-++source_range get_switch_bounds(tree);
-++unsigned int count_mods_in_switch(tree, subu_list *);
-++tree build_modded_switch_stmt(tree, SubContext *);
-++
-++#endif /* IFSWITCH_H */
-+diff --git a/gcc/c-family/initstruct.cc b/gcc/c-family/initstruct.cc
-+new file mode 100644
-+index 000000000..6a0d4a78e
-+--- /dev/null
-++++ b/gcc/c-family/initstruct.cc
-+@@ -0,0 +1,422 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/initstruct.h"
-++
-++void portcosmo_finish_decl(void *gcc_data) {
-++    handle_decl(gcc_data, (void *)(&cosmo_ctx));
-++}
-++
-++void set_values_based_on_ctor(tree ctor, subu_list *list, tree body, tree lhs,
-++                              location_t bound) {
-++  subu_node *use = NULL;
-++  unsigned int iprev = 0;
-++  bool started = true;
-++  tree replacement = NULL_TREE;
-++
-++  while (list->count > 0 && LOCATION_BEFORE2(list->start, bound)) {
-++    tree index = NULL_TREE;
-++    tree val = NULL_TREE;
-++    unsigned int i = 0;
-++    int found = 0;
-++    FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(ctor), i, index, val) {
-++      DEBUGF("value %u is %s\n", i, get_tree_code_str(val));
-++      if (!started && i <= iprev) continue;
-++      if (TREE_CODE(val) == INTEGER_CST) {
-++        for (use = list->head; use; use = use->next) {
-++          found = arg_should_be_unpatched(val, use, &replacement);
-++          if (found) break;
-++        }
-++        if (found) {
-++          iprev = i;
-++          started = false;
-++          break;
-++        }
-++      } else if (TREE_CODE(val) == CONSTRUCTOR) {
-++        auto sub = access_at(lhs, index);
-++        // debug_tree(sub);
-++        set_values_based_on_ctor(val, list, body, sub, bound);
-++        use = NULL; /* might've gotten stomped */
-++        if (list->count == 0) return;
-++        get_subu_elem(list, list->start, &use);
-++      }
-++    }
-++    if (found) {
-++      auto modexpr = build2(MODIFY_EXPR, TREE_TYPE(index),
-++                            access_at(lhs, index), replacement);
-++      // debug_tree(modexpr);
-++      append_to_statement_list(modexpr, &body);
-++      remove_subu_elem(list, use);
-++      replacement = NULL_TREE;
-++      DEBUGF("found; %d left\n", list->count);
-++    } else {
-++      /* we did not find any (more) substitutions to fix */
-++      DEBUGF("exiting; %d left\n", list->count);
-++      break;
-++    }
-++  }
-++}
-++
-++/* initstruct/global.cc */
-++
-++void update_global_decls(tree dcl, SubContext *ctx) {
-++  tree body = alloc_stmt_list();
-++  subu_node *use = NULL;
-++  char chk[STRING_BUFFER_SIZE];
-++
-++  /* dcl, the global declaration we have is like these:
-++   *
-++   * static int foo = __tmpcosmo_VAR;
-++   * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
-++   *
-++   * we're going to add functions as follows:
-++   *
-++   * static int foo = __tmpcosmo_VAR;
-++   * __attribute__((constructor)) __hidden_ctor1() {
-++   *   foo = VAR;
-++   * }
-++   * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
-++   * __attribute__((constructor)) __hidden_ctor2() {
-++   *    myvalue.y = VAR;
-++   * }
-++   *
-++   * the modifier functions have the constructor attribute,
-++   * so it they run before anything uses the static. it
-++   * works recursively too: you can have a struct of structs,
-++   * an array of structs, whatever, and it will figure out
-++   * where the substitutions are and attempt to mod them.
-++   *
-++   * a unique constructor for each declaration. probably
-++   * we could have a common constructor for the entire
-++   * file, but that's left as an exercise for the reader. */
-++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl)) &&
-++      get_subu_elem(ctx->mods, ctx->mods->start, &use) &&
-++      /* use is non-NULL if get_subu_elem succeeds */
-++      check_magic_equal(DECL_INITIAL(dcl), use->name)) {
-++    if (TREE_READONLY(dcl)) {
-++      error_at(EXPR_LOCATION(dcl), "cannot substitute this constant\n");
-++      /* actually I can, but the issue is if one of gcc's optimizations
-++       * perform constant folding(and they do), I don't know all the spots
-++       * where this variable has been folded, so I can't substitute there */
-++      ctx->active = 0;
-++      return;
-++    }
-++    append_to_statement_list(
-++        build2(MODIFY_EXPR, void_type_node, dcl, VAR_NAME_AS_TREE(use->name)),
-++        &body);
-++    /*
-++    append_to_statement_list(
-++        build_call_expr(VAR_NAME_AS_TREE("printf"), 2,
-++                        BUILD_STRING_AS_TREE("ctor initstruct %s\n"),
-++                        BUILD_STRING_AS_TREE(IDENTIFIER_NAME(dcl))),
-++        &body);
-++        */
-++    remove_subu_elem(ctx->mods, use);
-++    cgraph_build_static_cdtor('I', body, 0);
-++  } else if ((RECORD_TYPE == TREE_CODE(TREE_TYPE(dcl)) ||
-++              ARRAY_TYPE == TREE_CODE(TREE_TYPE(dcl))) &&
-++             DECL_INITIAL(dcl) != NULL_TREE) {
-++    if (TREE_READONLY(dcl)) {
-++      warning_at(DECL_SOURCE_LOCATION(dcl), 0,
-++                 "not sure if modding const structs is good\n");
-++      TREE_READONLY(dcl) = 0;
-++    }
-++    if (LOCATION_BEFORE2(ctx->mods->end, input_location)) {
-++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, body, dcl,
-++                               input_location);
-++    } else {
-++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, body, dcl,
-++                               ctx->mods->end);
-++    }
-++    /*
-++    append_to_statement_list(
-++        build_call_expr(VAR_NAME_AS_TREE("printf"), 2,
-++                        BUILD_STRING_AS_TREE("ctor initstruct %s\n"),
-++                        BUILD_STRING_AS_TREE(IDENTIFIER_NAME(dcl))),
-++        &body);
-++        */
-++    cgraph_build_static_cdtor('I', body, 0);
-++    DEBUGF("uploaded ctor\n");
-++  }
-++}
-++
-++void handle_decl(void *gcc_data, void *user_data) {
-++  tree t = (tree)gcc_data;
-++  SubContext *ctx = (SubContext *)user_data;
-++  if (ctx->active && ctx->mods->count > 0 && DECL_INITIAL(t) != NULL &&
-++      DECL_CONTEXT(t) == NULL_TREE) {
-++    int internal_use =
-++        !strncmp(IDENTIFIER_NAME(t), "__tmpcosmo_", strlen("__tmpcosmo_"));
-++    if (internal_use || DECL_EXTERNAL(t)) {
-++      error_at(input_location, "the ACTUALLY is before the declaration!\n");
-++      ctx->active = 0;
-++      return;
-++    }
-++    auto rng = EXPR_LOCATION_RANGE(t);
-++    rng.m_start = DECL_SOURCE_LOCATION(t);
-++    rng.m_finish = input_location;
-++
-++    DEBUGF("handle_decl with %s %u,%u - %u-%u\n", IDENTIFIER_NAME(t),
-++           LOCATION_LINE(rng.m_start), LOCATION_COLUMN(rng.m_start),
-++           LOCATION_LINE(rng.m_finish), LOCATION_COLUMN(rng.m_finish));
-++    ctx->initcount += ctx->mods->count;
-++    update_global_decls(t, ctx);
-++    /* now at this stage, all uses of our macros have been
-++     * fixed, INCLUDING case labels. Let's confirm that: */
-++    check_context_clear(ctx, MAX_LOCATION_T);
-++  }
-++}
-++
-++/* initstruct/local.cc */
-++
-++static inline tree build_modded_if_stmt(tree condition, tree then_clause,
-++                                        tree else_clause = NULL_TREE) {
-++  return build3(COND_EXPR, void_type_node, condition, then_clause, else_clause);
-++}
-++
-++int build_modded_int_declaration(tree *dxpr, SubContext *ctx, subu_node *use) {
-++  char chk[STRING_BUFFER_SIZE];
-++  tree dcl = DECL_EXPR_DECL(*dxpr);
-++  tree replacement = NULL_TREE;
-++
-++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl)) &&
-++      arg_should_be_unpatched(DECL_INITIAL(dcl), use, &replacement)) {
-++    if (TREE_READONLY(dcl)) {
-++      error_at(EXPR_LOCATION(dcl), "cannot substitute this constant\n");
-++      /* actually I can, but the issue is if one of gcc's optimizations
-++       * perform constant folding(and they do), I don't know all the spots
-++       * where this variable has been folded, so I can't substitute there */
-++      ctx->active = 0;
-++      return 0;
-++    }
-++
-++    if (!TREE_STATIC(dcl)) {
-++      DECL_INITIAL(dcl) = replacement;
-++      remove_subu_elem(ctx->mods, use);
-++      replacement = NULL_TREE;
-++      return 1;
-++    }
-++
-++    DEBUGF("fixing decl for a static integer\n");
-++    /* (*dxpr), the statement we have is this:
-++     *
-++     * static int myvalue = __tmpcosmo_VAR;
-++     *
-++     * we're going to modify it to this:
-++     *
-++     * static int myvalue = __tmpcosmo_VAR;
-++     * static uint8 __chk_ifs_myvalue = 0;
-++     * if(__chk_ifs_myvalue != 1) {
-++     *   __chk_ifs_myvalue = 1;
-++     *   myvalue = VAR;
-++     * }
-++     *
-++     * so the modified statement runs exactly once,
-++     * whenever the function is first called, right
-++     * after the initialization of the variable we
-++     * wanted to modify. */
-++
-++    /* build __chk_ifs_myvalue */
-++    snprintf(chk, sizeof(chk), "__chk_ifs_%s", IDENTIFIER_NAME(dcl));
-++    tree chknode = build_decl(DECL_SOURCE_LOCATION(dcl), VAR_DECL,
-++                              get_identifier(chk), uint8_type_node);
-++    DECL_INITIAL(chknode) = build_int_cst(uint8_type_node, 0);
-++    TREE_STATIC(chknode) = TREE_STATIC(dcl);
-++    TREE_USED(chknode) = TREE_USED(dcl);
-++    DECL_READ_P(chknode) = DECL_READ_P(dcl);
-++    DECL_CONTEXT(chknode) = DECL_CONTEXT(dcl);
-++    DECL_CHAIN(chknode) = DECL_CHAIN(dcl);
-++    DECL_CHAIN(dcl) = chknode;
-++
-++    /* create the then clause of the if statement */
-++    tree then_clause = alloc_stmt_list();
-++    append_to_statement_list(build2(MODIFY_EXPR, void_type_node, chknode,
-++                                    build_int_cst(uint8_type_node, 1)),
-++                             &then_clause);
-++    append_to_statement_list(
-++        build2(MODIFY_EXPR, void_type_node, dcl, replacement),
-++        &then_clause);
-++    /*
-++    append_to_statement_list(
-++        build_call_expr(VAR_NAME_AS_TREE("printf"), 1,
-++                        BUILD_STRING_AS_TREE("initstruct magic\n")),
-++        &then_clause);
-++    */
-++
-++    /* create the if statement into the overall result mentioned above */
-++    tree res = alloc_stmt_list();
-++    append_to_statement_list(*dxpr, &res);
-++    append_to_statement_list(build1(DECL_EXPR, void_type_node, chknode), &res);
-++    append_to_statement_list(
-++        build_modded_if_stmt(build2(NE_EXPR, void_type_node, chknode,
-++                                    build_int_cst(uint8_type_node, 1)),
-++                             then_clause),
-++        &res);
-++    /* overwrite the input tree with our new statements */
-++    *dxpr = res;
-++    // debug_tree(res);
-++    remove_subu_elem(ctx->mods, use);
-++    replacement = NULL_TREE;
-++    return 1;
-++  }
-++  return 0;
-++}
-++
-++void modify_local_struct_ctor(tree ctor, subu_list *list, location_t bound) {
-++  subu_node *use = NULL;
-++  unsigned int iprev = 0;
-++  bool started = true;
-++  tree replacement = NULL_TREE;
-++
-++  while (list->count > 0 && LOCATION_BEFORE2(list->start, bound)) {
-++    tree val = NULL_TREE;
-++    unsigned int i = 0;
-++    int found = 0;
-++    FOR_EACH_CONSTRUCTOR_VALUE(CONSTRUCTOR_ELTS(ctor), i, val) {
-++      DEBUGF("value %u is %s\n", i, get_tree_code_str(val));
-++      // debug_tree(val);
-++      if (TREE_CODE(val) == INTEGER_CST) {
-++        for (use = list->head; use; use = use->next) {
-++          found = arg_should_be_unpatched(val, use, &replacement);
-++          if (found) break;
-++        }
-++        if (found) {
-++          iprev = i;
-++          started = false;
-++          break;
-++        }
-++      } else if (TREE_CODE(val) == CONSTRUCTOR) {
-++        modify_local_struct_ctor(val, list, bound);
-++        use = NULL; /* might've gotten stomped */
-++        if (list->count == 0 || LOCATION_AFTER2(list->start, bound)) return;
-++      }
-++    }
-++    if (found) {
-++      DEBUGF("found\n");
-++      // debug_tree(CONSTRUCTOR_ELT(ctor, i)->index);
-++      CONSTRUCTOR_ELT(ctor, i)->value = replacement;
-++      // debug_tree(CONSTRUCTOR_ELT(ctor, i)->value);
-++      remove_subu_elem(list, use);
-++      replacement = NULL_TREE;
-++    } else {
-++      /* we did not find any (more) substitutions to fix */
-++      break;
-++    }
-++  }
-++}
-++
-++void build_modded_declaration(tree *dxpr, SubContext *ctx, location_t bound) {
-++  char chk[STRING_BUFFER_SIZE];
-++  tree dcl = DECL_EXPR_DECL(*dxpr);
-++  subu_node *use = NULL;
-++  subu_list *list = ctx->mods;
-++  unsigned int oldcount = list->count;
-++
-++  // debug_tree(DECL_INITIAL(dcl));
-++
-++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl))) {
-++    get_subu_elem(list, list->start, &use);
-++    if (build_modded_int_declaration(dxpr, ctx, use)) {
-++      use = NULL;
-++      ctx->initcount += 1;
-++    }
-++    return;
-++  }
-++
-++  if ((RECORD_TYPE == TREE_CODE(TREE_TYPE(dcl)) ||
-++       ARRAY_TYPE == TREE_CODE(TREE_TYPE(dcl))) &&
-++      DECL_INITIAL(dcl) != NULL_TREE) {
-++    if (TREE_READONLY(dcl)) {
-++      warning_at(EXPR_LOCATION(*dxpr), 0,
-++                 "not sure if modding const structs is good\n");
-++      TREE_READONLY(dcl) = 0;
-++      build_modded_declaration(dxpr, ctx, bound);
-++      return;
-++    } else if (TREE_STATIC(dcl)) {
-++      DEBUGF("fixing decl for a static struct\n");
-++      /* (*dxpr), the statement we have is this:
-++       *
-++       * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
-++       *
-++       * we're going to modify it to this:
-++       *
-++       * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
-++       * static uint8 __chk_ifs_myvalue = 0;
-++       * if(__chk_ifs_myvalue != 1) {
-++       *   __chk_ifs_myvalue = 1;
-++       *   myvalue.y = VAR;
-++       * }
-++       *
-++       * so the modified statement runs exactly once,
-++       * whenever the function is first called, right
-++       * after the initialization of the variable we
-++       * wanted to modify. */
-++
-++      /* build __chk_ifs_myvalue */
-++      snprintf(chk, sizeof(chk), "__chk_ifs_%s", IDENTIFIER_NAME(dcl));
-++      tree chknode = build_decl(DECL_SOURCE_LOCATION(dcl), VAR_DECL,
-++                                get_identifier(chk), uint8_type_node);
-++      DECL_INITIAL(chknode) = build_int_cst(uint8_type_node, 0);
-++      TREE_STATIC(chknode) = TREE_STATIC(dcl);
-++      TREE_USED(chknode) = TREE_USED(dcl);
-++      DECL_READ_P(chknode) = DECL_READ_P(dcl);
-++      DECL_CONTEXT(chknode) = DECL_CONTEXT(dcl);
-++      DECL_CHAIN(chknode) = DECL_CHAIN(dcl);
-++      DECL_CHAIN(dcl) = chknode;
-++
-++      /* build a scope block for the temporary value */
-++      tree tmpscope = build0(BLOCK, void_type_node);
-++      BLOCK_SUPERCONTEXT(tmpscope) = TREE_BLOCK(*dxpr);
-++      // debug_tree(BLOCK_SUPERCONTEXT(tmpscope));
-++
-++      /* create the then clause of the if statement */
-++      tree then_clause = alloc_stmt_list();
-++      append_to_statement_list(build2(MODIFY_EXPR, void_type_node, chknode,
-++                                      build_int_cst(uint8_type_node, 1)),
-++                               &then_clause);
-++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, then_clause, dcl,
-++                               bound);
-++      /*
-++      append_to_statement_list(
-++          build_call_expr(VAR_NAME_AS_TREE("printf"), 2,
-++                          BUILD_STRING_AS_TREE("initstruct magic %lu bytes\n"),
-++                          DECL_SIZE_UNIT(dcl)),
-++          &then_clause);
-++      */
-++
-++      /* create the if statement into the overall result mentioned above */
-++      tree res = alloc_stmt_list();
-++      append_to_statement_list(*dxpr, &res);
-++      append_to_statement_list(build1(DECL_EXPR, void_type_node, chknode),
-++                               &res);
-++      append_to_statement_list(
-++          build_modded_if_stmt(build2(NE_EXPR, void_type_node, chknode,
-++                                      build_int_cst(uint8_type_node, 1)),
-++                               then_clause),
-++          &res);
-++      /* overwrite the input tree with our new statements */
-++      *dxpr = res;
-++    } else {
-++      /* if it's a local struct, we can
-++       * just mod the constructor itself */
-++      auto ctor = DECL_INITIAL(dcl);
-++      modify_local_struct_ctor(ctor, list, bound);
-++    }
-++  }
-++  ctx->initcount += (oldcount - list->count);
-++}
-+diff --git a/gcc/c-family/initstruct.h b/gcc/c-family/initstruct.h
-+new file mode 100644
-+index 000000000..f77fba707
-+--- /dev/null
-++++ b/gcc/c-family/initstruct.h
-+@@ -0,0 +1,15 @@
-++#ifndef INITSTRUCT_H
-++#define INITSTRUCT_H
-++#include "c-family/portcosmo.internal.h"
-++/* gcc utils first */
-++#include "c-family/subcontext.h"
-++
-++void build_modded_declaration(tree *, SubContext *, location_t);
-++int build_modded_int_declaration(tree *, SubContext *, subu_node *);
-++tree copy_struct_ctor(tree);
-++void modify_local_struct_ctor(tree, subu_list *, location_t);
-++
-++void set_values_based_on_ctor(tree, subu_list *, tree, tree, location_t);
-++void handle_decl(void *, void *);
-++tree access_at(tree, tree);
-++#endif /* INITSTRUCT_H */
-+diff --git a/gcc/c-family/portcosmo.cc b/gcc/c-family/portcosmo.cc
-+new file mode 100644
-+index 000000000..4716500b5
-+--- /dev/null
-++++ b/gcc/c-family/portcosmo.cc
-+@@ -0,0 +1,171 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/portcosmo.internal.h"
-++#include "c-family/subcontext.h"
-++#include "c-family/ifswitch.h"
-++#include "c-family/initstruct.h"
-++
-++static tree maybe_get_ifsw_identifier(const char *);
-++static tree patch_int_nonconst(location_t, tree, const char **);
-++
-++struct SubContext cosmo_ctx;
-++static int ctx_inited = 0;
-++
-++void portcosmo_setup() {
-++    if (flag_portcosmo && 0 == ctx_inited) {
-++        construct_context(&cosmo_ctx);
-++        ctx_inited = 1;
-++    }
-++}
-++
-++void portcosmo_teardown() {
-++    if (flag_portcosmo && 1 == ctx_inited) {
-++        cleanup_context(&cosmo_ctx);
-++        ctx_inited = 0;
-++    }
-++}
-++
-++void portcosmo_show_tree(location_t loc, tree t) {
-++    INFORM(loc, "attempting case substitution at: line %u, col %u\n",
-++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
-++    debug_tree(t);
-++}
-++
-++tree patch_case_nonconst(location_t loc, tree t) {
-++    INFORM(loc, "attempting case substitution at: line %u, col %u\n",
-++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
-++    tree subs = NULL_TREE;
-++    const char *name = NULL;
-++    if (cosmo_ctx.active) {
-++        subs = patch_int_nonconst(loc, t, &name);
-++        if (subs != NULL_TREE) {
-++            DEBUGF("folding...\n");
-++            subs = c_fully_fold(subs, false, NULL, false);
-++            /* this substitution was successful, so record
-++             * the location for rewriting the thing later */
-++            add_context_subu(&cosmo_ctx, loc, name, strlen(name),
-++                             PORTCOSMO_SWCASE);
-++        }
-++    }
-++    return subs;
-++}
-++
-++tree patch_init_nonconst(location_t loc, tree t) {
-++    INFORM(loc, "attempting init substitution at: line %u, col %u\n",
-++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
-++    tree subs = NULL_TREE;
-++    const char *name = NULL;
-++    if (cosmo_ctx.active) {
-++        subs = patch_int_nonconst(loc, t, &name);
-++        if (subs != NULL_TREE) {
-++            DEBUGF("folding...\n");
-++            subs = c_fully_fold(subs, false, NULL, false);
-++            /* this substitution was successful, so record
-++             * the location for rewriting the thing later */
-++            add_context_subu(&cosmo_ctx, loc, name, strlen(name),
-++                             PORTCOSMO_INITVAL);
-++        }
-++    }
-++    return subs;
-++}
-++
-++/* internal functions */
-++
-++static tree patch_int_nonconst(location_t loc, tree t, const char **res) {
-++    /* t may be an integer inside a case label, or
-++     * t may be an integer inside an initializer */
-++    tree subs = NULL_TREE;
-++    switch (TREE_CODE(t)) {
-++        case VAR_DECL:
-++            subs = maybe_get_ifsw_identifier(IDENTIFIER_NAME(t));
-++            if (subs != NULL_TREE && TREE_STATIC(subs) && TREE_READONLY(subs)) {
-++                subs = DECL_INITIAL(subs);
-++                *res = IDENTIFIER_NAME(t);
-++                DEBUGF("substitution exists %s\n", *res);
-++            }
-++            break;
-++        case NOP_EXPR:
-++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
-++            if (subs != NULL_TREE) {
-++                subs = build1(NOP_EXPR, integer_type_node, subs);
-++            }
-++            break;
-++        case NEGATE_EXPR:
-++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
-++            if (subs != NULL_TREE) {
-++                subs = build1(NEGATE_EXPR, integer_type_node, subs);
-++            }
-++            break;
-++        case BIT_NOT_EXPR:
-++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
-++            if (subs != NULL_TREE) {
-++                subs = build1(BIT_NOT_EXPR, integer_type_node, subs);
-++            }
-++            break;
-++        default:
-++            subs = NULL_TREE;
-++    }
-++    return subs;
-++}
-++
-++const char *get_tree_code_str(tree expr) {
-++#define END_OF_BASE_TREE_CODES
-++#define DEFTREECODE(a, b, c, d) \
-++    case a:                     \
-++        return b;
-++    switch (TREE_CODE(expr)) {
-++#include "all-tree.def"
-++        default:
-++            return "<unknown>";
-++    }
-++#undef DEFTREECODE
-++#undef END_OF_BASE_TREE_CODES
-++}
-++
-++static tree maybe_get_ifsw_identifier(const char *s) {
-++    char *result = (char *)xmalloc(strlen("__tmpcosmo_") + strlen(s) + 1);
-++    strcpy(result, "__tmpcosmo_");
-++    strcat(result, s);
-++    tree t = maybe_get_identifier(result);
-++    free(result);
-++    if (t != NULL_TREE && lookup_name(t) != NULL_TREE) {
-++        return lookup_name(t);
-++    }
-++    return NULL_TREE;
-++}
-++
-++tree get_ifsw_identifier(char *s) {
-++    char *result = (char *)xmalloc(strlen("__tmpcosmo_") + strlen(s) + 1);
-++    strcpy(result, "__tmpcosmo_");
-++    strcat(result, s);
-++    tree t = lookup_name(get_identifier(result));
-++    free(result);
-++    return t;
-++}
-++
-++int get_value_of_const(char *name) {
-++    tree vx = get_ifsw_identifier(name);
-++    int z = tree_to_shwi(DECL_INITIAL(vx));
-++    return z;
-++}
-++
-++int check_magic_equal(tree value, char *varname) {
-++    tree vx = get_ifsw_identifier(varname);
-++    return tree_int_cst_equal(value, DECL_INITIAL(vx));
-++}
-+diff --git a/gcc/c-family/portcosmo.h b/gcc/c-family/portcosmo.h
-+new file mode 100644
-+index 000000000..b25d8257b
-+--- /dev/null
-++++ b/gcc/c-family/portcosmo.h
-+@@ -0,0 +1,13 @@
-++#ifndef PORTCOSMO_H
-++#define PORTCOSMO_H
-++#include <tree.h>
-++
-++void portcosmo_setup();
-++void portcosmo_teardown();
-++void portcosmo_pre_genericize(void*);
-++void portcosmo_finish_decl(void*);
-++void portcosmo_show_tree(location_t, tree);
-++tree patch_case_nonconst(location_t, tree);
-++tree patch_init_nonconst(location_t, tree);
-++
-++#endif /* PORTCOSMO_H */
-+diff --git a/gcc/c-family/portcosmo.internal.h b/gcc/c-family/portcosmo.internal.h
-+new file mode 100644
-+index 000000000..1d361bfa7
-+--- /dev/null
-++++ b/gcc/c-family/portcosmo.internal.h
-+@@ -0,0 +1,55 @@
-++#ifndef PORTCOSMO_INTERNAL_H
-++#define PORTCOSMO_INTERNAL_H
-++/* first stdlib headers */
-++#include <stdio.h>
-++/* now all the plugin headers */
-++#include <gcc-plugin.h>
-++/* first gcc-plugin, then the others */
-++#include <c-family/c-common.h>
-++#include <c-family/c-pragma.h>
-++#include <c/c-tree.h>
-++#include <cgraph.h>
-++#include <cpplib.h>
-++#include <diagnostic.h>
-++#include <print-tree.h>
-++#include <stringpool.h>
-++#include <tree-iterator.h>
-++#include <tree.h>
-++
-++const char *get_tree_code_str(tree);
-++int get_value_of_const(char *);
-++tree get_ifsw_identifier(char *);
-++int check_magic_equal(tree, char *);
-++
-++#define EXPR_LOC_LINE(x)      LOCATION_LINE(EXPR_LOCATION((x)))
-++#define EXPR_LOC_COL(x)       LOCATION_COLUMN(EXPR_LOCATION((x)))
-++#define LOCATION_APPROX(x, y) (LOCATION_LINE((x)) == LOCATION_LINE((y)))
-++#define LOCATION_BEFORE(x, y) (LOCATION_LINE((x)) <= LOCATION_LINE((y)))
-++#define LOCATION_AFTER(x, y)  (LOCATION_LINE((x)) >= LOCATION_LINE((y)))
-++
-++#define LOCATION_BEFORE2(x, y)                  \
-++  (LOCATION_LINE((x)) < LOCATION_LINE((y)) ||   \
-++   (LOCATION_LINE((x)) == LOCATION_LINE((y)) && \
-++    LOCATION_COLUMN((x)) <= LOCATION_COLUMN((y))))
-++#define LOCATION_AFTER2(x, y)                   \
-++  (LOCATION_LINE((x)) > LOCATION_LINE((y)) ||   \
-++   (LOCATION_LINE((x)) == LOCATION_LINE((y)) && \
-++    LOCATION_COLUMN((x)) >= LOCATION_COLUMN((y))))
-++
-++#define VAR_NAME_AS_TREE(fname)   lookup_name(get_identifier((fname)))
-++#define IDENTIFIER_NAME(z)        IDENTIFIER_POINTER(DECL_NAME((z)))
-++#define BUILD_STRING_AS_TREE(str) build_string_literal(strlen((str)) + 1, (str))
-++
-++#if 0
-++#define DEBUGF(...) fprintf(stderr, "<DEBUG> " __VA_ARGS__)
-++#define INFORM(...) inform(__VA_ARGS__)
-++#else
-++#define DEBUGF(...)
-++#define INFORM(...)
-++#endif
-++
-++#define STRING_BUFFER_SIZE 192
-++
-++void handle_pre_genericize(void *, void *);
-++
-++#endif /* PORTCOSMO.INTERNAL_H */
-+diff --git a/gcc/c-family/subcontext.cc b/gcc/c-family/subcontext.cc
-+new file mode 100644
-+index 000000000..e3e02800d
-+--- /dev/null
-++++ b/gcc/c-family/subcontext.cc
-+@@ -0,0 +1,241 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/subcontext.h"
-++
-++subu_node *build_subu(const location_t loc, const char *name,
-++                      unsigned int namelen, SubstType tp) {
-++  /* xmalloc because malloc is poisoned by gcc-plugin's system.h */
-++  subu_node *res = (subu_node *)xmalloc(sizeof(subu_node));
-++  res->next = NULL;
-++  res->loc = loc;
-++  res->name = xstrndup(name, namelen);
-++  res->tp = tp;
-++  DEBUGF("allocated subu_node at %p\n", res);
-++  return res;
-++};
-++
-++void delete_subu(subu_node *node) {
-++  DEBUGF("freeing subu_node at %p, %u,%u\n", node, LOCATION_LINE(node->loc),
-++         LOCATION_COLUMN(node->loc));
-++  node->loc = 0x0;
-++  free(node->name);
-++  node->next = NULL;
-++  node->tp = PORTCOSMO_UNKNOWN;
-++  free(node);
-++}
-++
-++subu_list *init_subu_list() {
-++  subu_list *res = (subu_list *)xmalloc(sizeof(subu_list));
-++  res->head = NULL;
-++  res->count = 0;
-++  res->start = 0;
-++  res->end = 0;
-++  DEBUGF("allocated subu_list at %p\n", res);
-++  return res;
-++}
-++
-++static void recount_subu_list(subu_list *list) {
-++  int i = 0;
-++  location_t s = MAX_LOCATION_T;
-++  location_t e = 0;
-++  subu_node *it;
-++  for (it = list->head; it != NULL; it = it->next) {
-++    i += 1;
-++    /* is it possible to compare for s and e? */
-++    if (s == MAX_LOCATION_T || LOCATION_BEFORE2(it->loc, s)) s = it->loc;
-++    if (LOCATION_AFTER2(it->loc, e)) e = it->loc;
-++  }
-++  if (LOCATION_AFTER2(s, e)) {
-++    s = e;
-++  }
-++  list->start = s;
-++  list->end = e;
-++  list->count = i;
-++  DEBUGF("list with %d subus, start = %u,%u end = %u,%u\n", list->count,
-++         LOCATION_LINE(list->start), LOCATION_COLUMN(list->start),
-++         LOCATION_LINE(list->end), LOCATION_COLUMN(list->end));
-++}
-++
-++void add_subu_elem(subu_list *list, subu_node *node) {
-++  subu_node *tmp;
-++  if (list->head == NULL) {
-++    list->head = node;
-++  } else {
-++    for (tmp = list->head; tmp->next != NULL; tmp = tmp->next)
-++      ;
-++    tmp->next = node;
-++    node->next = NULL;
-++  }
-++  recount_subu_list(list);
-++}
-++
-++void pop_subu_list(subu_list *list) {
-++  if (list->head != NULL) {
-++    subu_node *tmp = list->head;
-++    list->head = list->head->next;
-++    delete_subu(tmp);
-++  }
-++  recount_subu_list(list);
-++}
-++
-++int valid_subu_bounds(subu_list *list, location_t start, location_t end) {
-++  /* return 1 if the bounds of list and provided bounds overlap */
-++  if (LOCATION_BEFORE(list->start, end) && LOCATION_AFTER(list->start, start))
-++    return 1;
-++  if (LOCATION_BEFORE(start, list->end) && LOCATION_AFTER(start, list->start))
-++    return 1;
-++  return 0;
-++}
-++
-++int check_loc_in_bound(subu_list *list, location_t loc) {
-++  /* return 1 if loc is within the bounds */
-++  if (LOCATION_BEFORE(list->start, loc) && LOCATION_AFTER(list->end, loc)) {
-++    return 1;
-++  } else {
-++    return 0;
-++  }
-++}
-++
-++int get_subu_elem(subu_list *list, location_t loc, subu_node **node) {
-++  /* *node is overwritten on returning 1 ie success */
-++  subu_node *it = list->head;
-++  for (; it != NULL; it = it->next) {
-++    if (LOCATION_APPROX(it->loc, loc)) {
-++      *node = it;
-++      return 1;
-++    }
-++  }
-++  return 0;
-++}
-++
-++int get_subu_elem2(subu_list *list, source_range rng, subu_node **node) {
-++  /* *node is overwritten on returning 1 ie success */
-++  /* returns the first node found within rng's bounds */
-++  subu_node *it = list->head;
-++  for (; it != NULL; it = it->next) {
-++    if (LOCATION_BEFORE(rng.m_start, it->loc) &&
-++        LOCATION_AFTER(rng.m_finish, it->loc)) {
-++      *node = it;
-++      return 1;
-++    }
-++  }
-++  return 0;
-++}
-++
-++void remove_subu_elem(subu_list *list, subu_node *node) {
-++  subu_node *cur, *prev;
-++  if (list->head != NULL) {
-++    if (list->head == node) {
-++      cur = list->head;
-++      list->head = list->head->next;
-++      delete_subu(cur);
-++    } else {
-++      prev = list->head;
-++      cur = list->head->next;
-++      for (; cur != NULL; prev = cur, cur = cur->next) {
-++        if (cur == node) {
-++          prev->next = cur->next;
-++          delete_subu(cur);
-++          break;
-++        }
-++      }
-++    }
-++    recount_subu_list(list);
-++  }
-++}
-++
-++void clear_subu_list(subu_list *list) {
-++  subu_node *it, *tmp;
-++  for (it = list->head; it != NULL;) {
-++    tmp = it;
-++    it = it->next;
-++    delete_subu(tmp);
-++  }
-++  list->head = NULL;
-++  list->count = 0;
-++  list->start = 0;
-++  list->end = 0;
-++}
-++
-++void delete_subu_list(subu_list *list) {
-++  clear_subu_list(list);
-++  free(list);
-++  DEBUGF("freeing subu_list at %p\n", list);
-++}
-++
-++int check_empty_subu_list(subu_list *list, location_t start) {
-++  /* we should have modded all locations before start, and so
-++   * list should not contain any entries which have a location
-++   * before start */
-++  int errcount = 0;
-++  for (auto it = list->head; it; it = it->next) {
-++    if (start == MAX_LOCATION_T || LOCATION_BEFORE2(it->loc, start)) {
-++      error_at(it->loc, "unable to substitute constant\n");
-++      errcount += 1;
-++    }
-++  }
-++  if (errcount != 0) {
-++    /* DON'T DELETE! */
-++    clear_subu_list(list);
-++  }
-++  return errcount == 0;
-++}
-++
-++void construct_context(SubContext *ctx) {
-++  ctx->active = 1;
-++  ctx->mods = init_subu_list();
-++  ctx->prev = NULL;
-++  ctx->switchcount = 0;
-++  ctx->initcount = 0;
-++  ctx->subcount = 0;
-++}
-++
-++void add_context_subu(SubContext *ctx, const location_t loc, const char *defn,
-++                      unsigned int at, SubstType st) {
-++  if (ctx->mods == NULL) return;
-++  add_subu_elem(ctx->mods, build_subu(loc, defn, at, st));
-++}
-++
-++void check_context_clear(SubContext *ctx, location_t start) {
-++  if (ctx->mods) {
-++    ctx->active = check_empty_subu_list(ctx->mods, start);
-++  }
-++}
-++
-++void cleanup_context(SubContext *ctx) {
-++  check_context_clear(ctx, MAX_LOCATION_T);
-++  if (ctx->mods) {
-++    delete_subu_list(ctx->mods);
-++    ctx->mods = NULL;
-++  }
-++  ctx->prev = NULL;
-++  if (ctx->switchcount > 0) {
-++    inform(UNKNOWN_LOCATION, "rewrote %u switch statements", ctx->switchcount);
-++  }
-++  ctx->switchcount = 0;
-++  if (ctx->initcount > 0) {
-++    inform(UNKNOWN_LOCATION, "modified %u initializations", ctx->initcount);
-++  }
-++  ctx->initcount = 0;
-++  if (ctx->subcount > 0) {
-++    inform(UNKNOWN_LOCATION, "modified %u other macro uses", ctx->subcount);
-++  }
-++  ctx->subcount = 0;
-++  ctx->active = 0;
-++}
-+diff --git a/gcc/c-family/subcontext.h b/gcc/c-family/subcontext.h
-+new file mode 100644
-+index 000000000..558e4fd06
-+--- /dev/null
-++++ b/gcc/c-family/subcontext.h
-+@@ -0,0 +1,81 @@
-++#ifndef SUBCONTEXT_H
-++#define SUBCONTEXT_H
-++#include "c-family/portcosmo.internal.h"
-++
-++enum SubstType { 
-++    PORTCOSMO_UNKNOWN = 0, 
-++    PORTCOSMO_SWCASE = 1, 
-++    PORTCOSMO_INITVAL = 2 
-++};
-++
-++struct _subu_node {
-++  /* a node indicating that an ifswitch substitution has occurred.
-++   *
-++   * Details include:
-++   *
-++   * - location_t of the substitution
-++   * - char* of name of the macro that was substituted (alloc'd)
-++   * - whether the substitution was inside a switch statement
-++   * - _subu_node* pointer to the next element in the list (NULL if last)
-++   *
-++   * the idea is that every time one of our modified macros is used,
-++   * we record the substitution, and then we delete this record if
-++   * we find the appropriate location_t during pre-genericize and
-++   * construct the necessary parse trees at that point.
-++   *
-++   * at the end of compilation (ie PLUGIN_FINISH), there should be
-++   * no subu_nodes allocated.
-++   */
-++  location_t loc;
-++  SubstType tp;
-++  char *name;
-++  struct _subu_node *next;
-++};
-++
-++typedef struct _subu_node subu_node;
-++
-++struct _subu_list {
-++  subu_node *head;
-++  /* inclusive bounds, range containing all recorded substitutions */
-++  location_t start, end;
-++  /* number of substitutions */
-++  int count;
-++};
-++typedef struct _subu_list subu_list;
-++
-++int check_loc_in_bound(subu_list *, location_t);
-++int valid_subu_bounds(subu_list *, location_t, location_t);
-++int get_subu_elem(subu_list *, location_t, subu_node **);
-++int get_subu_elem2(subu_list *, source_range, subu_node **);
-++void remove_subu_elem(subu_list *, subu_node *);
-++
-++/* Substitution Context */
-++struct SubContext {
-++  /* record all macro uses */
-++  subu_list *mods;
-++  /* address of the previous statement we walked through,
-++   * in case we missed modding it and have to retry */
-++  tree *prev;
-++  /* count number of switch statements rewritten */
-++  unsigned int switchcount;
-++  /* count number of initializations rewritten */
-++  unsigned int initcount;
-++  /* count number of other substitutions rewritten */
-++  unsigned int subcount;
-++  /* if zero, it means we haven't started or something
-++   * went wrong somewhere */
-++  int active;
-++};
-++
-++void add_context_subu(SubContext *, const location_t, const char *,
-++                      unsigned int, SubstType);
-++void construct_context(SubContext *);
-++void check_context_clear(SubContext *, location_t);
-++void cleanup_context(SubContext *);
-++
-++int arg_should_be_unpatched(tree, const subu_node *, tree *);
-++
-++/* declaring cosmo_ctx here so initstruct knows it exists */
-++extern struct SubContext cosmo_ctx;
-++
-++#endif /* SUBCONTEXT_H */
-+diff --git a/gcc/c-family/unpatch_ast.cc b/gcc/c-family/unpatch_ast.cc
-+new file mode 100644
-+index 000000000..56b5b9a01
-+--- /dev/null
-++++ b/gcc/c-family/unpatch_ast.cc
-+@@ -0,0 +1,115 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/ifswitch.h"
-++#include "c-family/initstruct.h"
-++
-++tree check_usage(tree *tp, int *check_subtree, void *data) {
-++    SubContext *ctx = (SubContext *)(data);
-++    tree t = *tp;
-++    tree z;
-++    subu_node *use = NULL;
-++    location_t loc = EXPR_LOCATION(t);
-++    source_range rng = EXPR_LOCATION_RANGE(t);
-++
-++    if (ctx->active == 0 || ctx->mods->count == 0) {
-++        /* DEBUGF("substitutions complete\n"); */
-++        *check_subtree = 0;
-++        return NULL_TREE;
-++    }
-++
-++    if (LOCATION_AFTER2(loc, rng.m_start)) {
-++        loc = rng.m_start;
-++    } else {
-++        rng.m_start = loc;
-++    }
-++
-++    if (ctx->prev && LOCATION_BEFORE2(ctx->mods->start, rng.m_start)) {
-++        auto vloc = DECL_SOURCE_LOCATION(DECL_EXPR_DECL(*(ctx->prev)));
-++        /* below inequality holds inside this if condition:
-++         *    vloc <= ctx->mods->start <= rng.m_start
-++         * this means that there was a macro substitution
-++         * between vloc and rng.m_start, which was not
-++         * eliminated when we went through the other parts
-++         * of the parse tree earlier. thus, the decl_expr
-++         * that we have stored in ctx->prev needs to be
-++         * checked for possible macro substitutions */
-++        DEBUGF(
-++            "did we miss a decl? vloc=%u,%u, loc=%u,%u, rng.mstart=%u,%u, "
-++            "start=%u,%u\n",
-++            LOCATION_LINE(vloc), LOCATION_COLUMN(vloc),  //
-++            LOCATION_LINE(loc), LOCATION_COLUMN(loc),    //
-++            LOCATION_LINE(rng.m_start), LOCATION_COLUMN(rng.m_start),
-++            LOCATION_LINE(ctx->mods->start), LOCATION_COLUMN(ctx->mods->start));
-++        auto z = ctx->initcount;
-++        build_modded_declaration(ctx->prev, ctx, rng.m_start);
-++        if (z != ctx->initcount) {
-++            ctx->prev = NULL;
-++            check_context_clear(ctx, loc);
-++        }
-++    }
-++
-++    if (TREE_CODE(t) == DECL_EXPR && TREE_STATIC(DECL_EXPR_DECL(t))) {
-++        INFORM(loc, "should we mod this?\n");
-++        ctx->prev = tp;
-++    }
-++
-++    if (TREE_CODE(t) == SWITCH_STMT) {
-++        rng = get_switch_bounds(t);
-++        if (valid_subu_bounds(ctx->mods, rng.m_start, rng.m_finish) &&
-++            count_mods_in_switch(t, ctx->mods) > 0) {
-++            /* this is one of the switch statements
-++             * where we modified a case label */
-++            DEBUGF("modding the switch \n");
-++            *tp = build_modded_switch_stmt(t, ctx);
-++            DEBUGF("we modded it??\n");
-++            walk_tree_without_duplicates(tp, check_usage, ctx);
-++            /* due to the above call, I don't need to check
-++             * any subtrees from this current location */
-++            *check_subtree = 0;
-++            ctx->switchcount += 1;
-++            return NULL_TREE;
-++        }
-++    }
-++
-++    return NULL_TREE;
-++}
-++
-++void handle_pre_genericize(void *gcc_data, void *user_data) {
-++    tree t = (tree)gcc_data;
-++    SubContext *ctx = (SubContext *)user_data;
-++    tree t2;
-++    if (ctx->active && TREE_CODE(t) == FUNCTION_DECL &&
-++        DECL_INITIAL(t) != NULL && TREE_STATIC(t)) {
-++        /* this function is defined within the file I'm processing */
-++        if (ctx->mods->count == 0) {
-++            // DEBUGF("no substitutions were made in %s\n", IDENTIFIER_NAME(t));
-++            return;
-++        }
-++        t2 = DECL_SAVED_TREE(t);
-++        ctx->prev = NULL;
-++        walk_tree_without_duplicates(&t2, check_usage, ctx);
-++        /* now at this stage, all uses of our macros have been
-++         * fixed, INCLUDING case labels. Let's confirm that: */
-++        check_context_clear(ctx, MAX_LOCATION_T);
-++    }
-++}
-++
-++void portcosmo_pre_genericize(void *gcc_data) {
-++    handle_pre_genericize(gcc_data, (void *)(&cosmo_ctx));
-++}
-+diff --git a/gcc/c-family/unpatch_int.cc b/gcc/c-family/unpatch_int.cc
-+new file mode 100644
-+index 000000000..08c96b544
-+--- /dev/null
-++++ b/gcc/c-family/unpatch_int.cc
-+@@ -0,0 +1,63 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/subcontext.h"
-++
-++int arg_should_be_unpatched(tree arg, const subu_node *use, tree *rep_ptr) {
-++  /* if we are returning 1, rep_ptr has been set.
-++   * if we are returning 0, rep_ptr is unchanged.
-++   * use is not affected! */
-++  if (TREE_CODE(arg) == INTEGER_CST) {
-++    tree vx = DECL_INITIAL(get_ifsw_identifier(use->name));
-++    if (tree_int_cst_equal(arg, vx)) {
-++      /* if this is an integer constant, AND its
-++       * value is equal to the macro we substituted,
-++       * then we replace the correct variable here */
-++      *rep_ptr =
-++          build1(NOP_EXPR, integer_type_node, VAR_NAME_AS_TREE(use->name));
-++      INFORM(use->loc, "unpatched an integer here with %s\n", use->name);
-++      return 1;
-++    }
-++    /* here you might want to handle some
-++     * minimal constant folding algebra,
-++     * like -VAR or ~VAR */
-++    if (tree_fits_poly_int64_p(vx) && tree_fits_poly_int64_p(arg)) {
-++      auto v1 = tree_to_poly_int64(vx);
-++      auto v2 = tree_to_poly_int64(arg);
-++
-++      /* handle the -VAR case */
-++      if (known_eq(v1, -v2)) {
-++        INFORM(use->loc, "unpatched an integer here with -%s\n", use->name);
-++        *rep_ptr =
-++            build1(NEGATE_EXPR, integer_type_node, VAR_NAME_AS_TREE(use->name));
-++        return 1;
-++      }
-++
-++      /* handle the ~VAR case */
-++      if (known_eq(v1, ~v2)) {
-++        INFORM(use->loc, "unpatched an integer here with ~%s\n", use->name);
-++        *rep_ptr = build1(BIT_NOT_EXPR, integer_type_node,
-++                          VAR_NAME_AS_TREE(use->name));
-++        return 1;
-++      }
-++    }
-++    return 0;
-++  }
-++
-++  return 0;
-++}
-+diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
-+index a1cdee872..ce57e8a27 100644
-+--- a/gcc/c/Make-lang.in
-++++ b/gcc/c/Make-lang.in
-+@@ -55,8 +55,10 @@ C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \
-+   c/c-fold.o c/gimple-parser.o \
-+   $(C_COMMON_OBJS) $(C_TARGET_OBJS)
-+ 
-++PORTCOSMO_C_OBJS = c/portcosmo_bcref.o
-++
-+ # Language-specific object files for C.
-+-C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
-++C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS) $(PORTCOSMO_C_OBJS)
-+ c_OBJS = $(C_OBJS) cc1-checksum.o c/gccspec.o
-+ 
-+ # Use strict warnings for this front end.
-+diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-+index 53b2b5b63..51f3a72e5 100644
-+--- a/gcc/c/c-decl.c
-++++ b/gcc/c/c-decl.c
-+@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
-+ #include "c-family/name-hint.h"
-+ #include "c-family/known-headers.h"
-+ #include "c-family/c-spellcheck.h"
-++#include "c-family/portcosmo.h"
-+ #include "context.h"  /* For 'g'.  */
-+ #include "omp-general.h"
-+ #include "omp-offload.h"  /* For offload_vars.  */
-+@@ -5685,6 +5686,9 @@ finish_decl (tree decl, location_t init_loc, tree init,
-+       && !DECL_HARD_REGISTER (decl))
-+     targetm.lower_local_decl_alignment (decl);
-+ 
-++  if(flag_portcosmo) {
-++      portcosmo_finish_decl(decl);
-++  }
-+   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
-+ }
-+ 
-+@@ -10277,6 +10281,10 @@ finish_function (location_t end_loc)
-+     {
-+       if (!decl_function_context (fndecl))
-+ 	{
-++      if (flag_portcosmo)
-++     {
-++        portcosmo_pre_genericize(fndecl); 
-++     }
-+ 	  invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
-+ 	  c_genericize (fndecl);
-+ 
-+diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
-+index b5d139e5d..2df309eba 100644
-+--- a/gcc/c/c-typeck.c
-++++ b/gcc/c/c-typeck.c
-+@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
-+ #include "omp-general.h"
-+ #include "c-family/c-objc.h"
-+ #include "c-family/c-ubsan.h"
-++#include "c-family/portcosmo.h"
-+ #include "gomp-constants.h"
-+ #include "spellcheck-tree.h"
-+ #include "gcc-rich-location.h"
-+@@ -8170,8 +8171,17 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
-+ 	       && !initializer_constant_valid_p (inside_init,
-+ 						 TREE_TYPE (inside_init)))
-+ 	{
-+-	  error_init (init_loc, "initializer element is not constant");
-+-	  inside_init = error_mark_node;
-++      if (flag_portcosmo) {
-++        inside_init = patch_init_nonconst(init_loc, inside_init);
-++        if (inside_init == NULL_TREE) {
-++	      error_init (init_loc, "initializer element is not constant");
-++	      inside_init = error_mark_node;
-++        }
-++      }
-++      else {
-++	    error_init (init_loc, "initializer element is not constant");
-++	    inside_init = error_mark_node;
-++      }
-+ 	}
-+       else if (require_constant && !maybe_const)
-+ 	pedwarn_init (init_loc, OPT_Wpedantic,
-+@@ -9787,7 +9797,7 @@ output_init_element (location_t loc, tree value, tree origtype,
-+   /* Proceed to check the constness of the original initializer.  */
-+   if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
-+     {
-+-      if (require_constant_value)
-++      if (require_constant_value && !flag_portcosmo)
-+ 	{
-+ 	  error_init (loc, "initializer element is not constant");
-+ 	  value = error_mark_node;
-+diff --git a/gcc/c/portcosmo_bcref.cc b/gcc/c/portcosmo_bcref.cc
-+new file mode 100644
-+index 000000000..2c6a58296
-+--- /dev/null
-++++ b/gcc/c/portcosmo_bcref.cc
-+@@ -0,0 +1,30 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "c-family/initstruct.h"
-++
-++/* initstruct/common.cc */
-++
-++tree access_at(tree obj, tree ind) {
-++  if (TREE_CODE(TREE_TYPE(obj)) == ARRAY_TYPE) {
-++    return build_array_ref(input_location, obj, ind);
-++  }
-++  return build_component_ref(input_location, obj,
-++                             get_identifier(IDENTIFIER_NAME(ind)),
-++                             DECL_SOURCE_LOCATION(ind));
-++}
-+diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
-+index 155be74ef..2fe9484ff 100644
-+--- a/gcc/cp/Make-lang.in
-++++ b/gcc/cp/Make-lang.in
-+@@ -84,6 +84,10 @@ g++-cross$(exeext): xg++$(exeext)
-+ CXX_C_OBJS = attribs.o incpath.o \
-+ 	$(C_COMMON_OBJS) $(CXX_TARGET_OBJS)
-+ 
-++# initstruct has some issues building with cc1plus,
-++# so we provide nothing for now
-++PORTCOSMO_CXX_OBJS = cp/portcosmo_bcref_cp.o
-++
-+ # Language-specific object files for C++ and Objective C++.
-+ CXX_AND_OBJCXX_OBJS = \
-+ 	cp/call.o cp/class.o cp/constexpr.o cp/constraint.o \
-+@@ -101,7 +105,7 @@ CXX_AND_OBJCXX_OBJS = \
-+ 	cp/rtti.o \
-+ 	cp/search.o cp/semantics.o \
-+ 	cp/tree.o cp/typeck.o cp/typeck2.o \
-+-	cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
-++	cp/vtable-class-hierarchy.o $(CXX_C_OBJS) $(PORTCOSMO_CXX_OBJS)
-+ 
-+ ifeq ($(if $(wildcard ../stage_current),$(shell cat \
-+   ../stage_current)),stageautofeedback)
-+diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
-+index 5e101ffb8..1f68dddbf 100644
-+--- a/gcc/cp/decl.c
-++++ b/gcc/cp/decl.c
-+@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
-+ #include "context.h"  /* For 'g'.  */
-+ #include "omp-general.h"
-+ #include "omp-offload.h"  /* For offload_vars.  */
-++#include "c-family/portcosmo.h"
-+ 
-+ /* Possible cases of bad specifiers type used by bad_specifiers. */
-+ enum bad_spec_place {
-+@@ -8246,6 +8247,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
-+       && !DECL_HARD_REGISTER (decl))
-+     targetm.lower_local_decl_alignment (decl);
-+ 
-++  if (flag_portcosmo) {
-++      portcosmo_finish_decl(decl);
-++  }
-+   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
-+ }
-+ 
-+@@ -17459,8 +17463,13 @@ finish_function (bool inline_p)
-+   maybe_save_constexpr_fundef (fndecl);
-+ 
-+   /* Invoke the pre-genericize plugin before we start munging things.  */
-+-  if (!processing_template_decl)
-++  if (!processing_template_decl) {
-++      if (flag_portcosmo)
-++     {
-++        portcosmo_pre_genericize(fndecl); 
-++     }
-+     invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
-++  }
-+ 
-+   /* Perform delayed folding before NRV transformation.  */
-+   if (!processing_template_decl
-+diff --git a/gcc/cp/portcosmo_bcref_cp.cc b/gcc/cp/portcosmo_bcref_cp.cc
-+new file mode 100644
-+index 000000000..bf01d9aeb
-+--- /dev/null
-++++ b/gcc/cp/portcosmo_bcref_cp.cc
-+@@ -0,0 +1,42 @@
-++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
-++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
-++╞══════════════════════════════════════════════════════════════════════════════╡
-++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
-++│                                                                              │
-++│ Permission to use, copy, modify, and/or distribute this software for         │
-++│ any purpose with or without fee is hereby granted, provided that the         │
-++│ above copyright notice and this permission notice appear in all copies.      │
-++│                                                                              │
-++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
-++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
-++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
-++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
-++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
-++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
-++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
-++│ PERFORMANCE OF THIS SOFTWARE.                                                │
-++╚─────────────────────────────────────────────────────────────────────────────*/
-++#include "config.h"
-++#include "system.h"
-++#include "coretypes.h"
-++#include "target.h"
-++#include "c-family/c-target.h"
-++#include "cp-tree.h"
-++#include "tree.h"
-++#include "stringpool.h"
-++
-++#define IDENTIFIER_NAME(z)        IDENTIFIER_POINTER(DECL_NAME((z)))
-++
-++/* initstruct/common.cc */
-++
-++tree access_at(tree obj, tree ind) {
-++  return cp_build_addr_expr(ind, 0);
-++  /*
-++  if (TREE_CODE(TREE_TYPE(obj)) == ARRAY_TYPE) {
-++    return build_array_ref(input_location, obj, ind);
-++  }
-++  return build_component_ref(input_location, obj,
-++                             get_identifier(IDENTIFIER_NAME(ind)),
-++                             DECL_SOURCE_LOCATION(ind));
-++  */
-++}
+diff --git a/gcc/Makefile.in b/gcc/Makefile.in
+index 8a5fb3fd9..3a7498db8 100644
+--- a/gcc/Makefile.in
++++ b/gcc/Makefile.in
+@@ -1231,6 +1231,10 @@ GCC_OBJS = gcc.o gcc-main.o ggc-none.o
+ 
+ c-family-warn = $(STRICT_WARN)
+ 
++PORTCOSMO_OBJS = c-family/portcosmo.o c-family/subcontext.o\
++				 c-family/initstruct.o c-family/ifswitch.o \
++                 c-family/unpatch_int.o c-family/unpatch_ast.o
 +
+ # Language-specific object files shared by all C-family front ends.
+ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
+   c-family/c-format.o c-family/c-gimplify.o c-family/c-indentation.o \
+@@ -1238,7 +1242,8 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
+   c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
+   c-family/c-semantics.o c-family/c-ada-spec.o \
+   c-family/c-ubsan.o c-family/known-headers.o \
+-  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o
++  c-family/c-attribs.o c-family/c-warn.o c-family/c-spellcheck.o \
++  $(PORTCOSMO_OBJS)
+ 
+ # Analyzer object files
+ ANALYZER_OBJS = \
+diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
+index d227686a0..a1d4c81ec 100644
+--- a/gcc/c-family/c-common.c
++++ b/gcc/c-family/c-common.c
+@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
+ #include "c-spellcheck.h"
+ #include "selftest.h"
+ #include "debug.h"
++#include "c-family/portcosmo.h"
+ 
+ cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
+ 
+@@ -2112,8 +2113,16 @@ check_case_value (location_t loc, tree value)
+     value = perform_integral_promotions (value);
+   else if (value != error_mark_node)
+     {
+-      error_at (loc, "case label does not reduce to an integer constant");
+-      value = error_mark_node;
++      if (flag_portcosmo) {
++          value = patch_case_nonconst(loc, value);
++          if (value == NULL_TREE) {
++            error_at (loc, "case label does not reduce to an integer constant");
++            value = error_mark_node;
++          }
++      } else {
++            error_at (loc, "case label does not reduce to an integer constant");
++            value = error_mark_node;
++      }
+     }
+ 
+   constant_expression_warning (value);
+diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
+index 89e05a4c5..15c26f507 100644
+--- a/gcc/c-family/c-opts.c
++++ b/gcc/c-family/c-opts.c
+@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
+ #include "mkdeps.h"
+ #include "dumpfile.h"
+ #include "file-prefix-map.h"    /* add_*_prefix_map()  */
++#include "c-family/portcosmo.h"
+ 
+ #ifndef DOLLARS_IN_IDENTIFIERS
+ # define DOLLARS_IN_IDENTIFIERS true
+@@ -1131,6 +1132,10 @@ c_common_post_options (const char **pfilename)
+   cpp_post_options (parse_in);
+   init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
+ 
++  if (flag_portcosmo)
++    {
++        portcosmo_setup();
++    }
+   input_location = UNKNOWN_LOCATION;
+ 
+   *pfilename = this_input_filename
+@@ -1281,6 +1286,10 @@ c_common_finish (void)
+   /* For performance, avoid tearing down cpplib's internal structures
+      with cpp_destroy ().  */
+   cpp_finish (parse_in, deps_stream);
++  if(flag_portcosmo) 
++    {
++        portcosmo_teardown();
++    }
+ 
+   if (deps_stream && deps_stream != out_stream && deps_stream != stdout
+       && (ferror (deps_stream) || fclose (deps_stream)))
+@@ -1288,6 +1297,7 @@ c_common_finish (void)
+ 
+   if (out_stream && (ferror (out_stream) || fclose (out_stream)))
+     fatal_error (input_location, "when writing output to %s: %m", out_fname);
++
+ }
+ 
+ /* Either of two environment variables can specify output of
+diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
+index 2005b783c..a69a9a349 100644
+--- a/gcc/c-family/c.opt
++++ b/gcc/c-family/c.opt
+@@ -1881,6 +1881,10 @@ fopenmp-simd
+ C ObjC C++ ObjC++ Var(flag_openmp_simd)
+ Enable OpenMP's SIMD directives.
+ 
++fportcosmo
++C C++ RejectNegative Var(flag_portcosmo)
++Enable AST rewriting for Cosmopolitan Libc magic numbers.
++
+ foperator-names
+ C++ ObjC++
+ Recognize C++ keywords like \"compl\" and \"xor\".
+diff --git a/gcc/c-family/ifswitch.cc b/gcc/c-family/ifswitch.cc
+new file mode 100644
+index 000000000..0dab740f1
+--- /dev/null
++++ b/gcc/c-family/ifswitch.cc
+@@ -0,0 +1,226 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/ifswitch.h"
++
++static tree get_switch_body(tree swexpr) {
++  auto body = SWITCH_STMT_BODY(swexpr);
++  if (TREE_CODE(body) == BIND_EXPR) {
++    body = BIND_EXPR_BODY(body);
++  }
++  return body;
++}
++
++source_range get_switch_bounds(tree sws) {
++  auto body = get_switch_body(sws);
++  source_range rng;
++  rng.m_start = MAX_LOCATION_T;
++  rng.m_finish = MAX_LOCATION_T;
++  if (STATEMENT_LIST_HEAD(body) && STATEMENT_LIST_TAIL(body)) {
++    /* otherwise this is an empty switch statement */
++    auto rng1 = EXPR_LOCATION_RANGE(STATEMENT_LIST_HEAD(body)->stmt);
++    auto rng2 = EXPR_LOCATION_RANGE(STATEMENT_LIST_TAIL(body)->stmt);
++    rng.m_start = rng1.m_start;
++    rng.m_finish = rng2.m_finish;
++  }
++  return rng;
++}
++
++unsigned int count_mods_in_switch(tree swexpr, subu_list *list) {
++  tree body = get_switch_body(swexpr);
++  tree t = NULL_TREE;
++  tree replacement = NULL_TREE;
++  subu_node *use = NULL;
++  unsigned int count = 0;
++  for (auto i = tsi_start(body); !tsi_end_p(i); tsi_next(&i)) {
++    t = tsi_stmt(i);
++    if (TREE_CODE(t) == CASE_LABEL_EXPR) {
++      if (get_subu_elem(list, EXPR_LOCATION(t),
++                        &use)          /* on a line we substituted */
++          && CASE_LOW(t) != NULL_TREE  /* not a x..y range */
++          && CASE_HIGH(t) == NULL_TREE /* not a default */
++          && arg_should_be_unpatched(CASE_LOW(t), use, &replacement)
++          /* the case is the one we substituted */) {
++        DEBUGF("we substituted a case label at %u,%u\n", EXPR_LOC_LINE(t),
++               EXPR_LOC_COL(t));
++        count += 1;
++      }
++    }
++  }
++  return count;
++}
++
++tree build_modded_label(unsigned int swcount, const char *case_str,
++                        location_t loc = UNKNOWN_LOCATION) {
++  char dest[STRING_BUFFER_SIZE] = {0};
++  snprintf(dest, sizeof(dest), "__tmpcosmo_%u_%s", swcount, case_str);
++  tree lab = build_decl(loc, LABEL_DECL, get_identifier(dest), void_type_node);
++  /* gcc's GIMPLE needs to know that this label
++   * is within the current function declaration */
++  DECL_CONTEXT(lab) = current_function_decl;
++  return build1(LABEL_EXPR, void_type_node, lab);
++}
++
++tree build_modded_exit_label(unsigned int swcount) {
++  return build_modded_label(swcount, "__end");
++}
++
++static inline tree build_modded_if_stmt(tree condition, tree then_clause,
++                                        tree else_clause = NULL_TREE) {
++  return build3(COND_EXPR, void_type_node, condition, then_clause, else_clause);
++}
++
++tree modded_case_label(tree t, unsigned int i, tree swcond, vec<tree> *&ifs,
++                       SubContext *ctx, tree *default_label) {
++  tree result;
++  tree replacement = NULL_TREE;
++  subu_node *use = NULL;
++  char case_str[STRING_BUFFER_SIZE] = {0};
++
++  if (CASE_LOW(t) == NULL_TREE) {
++    DEBUGF("default case\n");
++    /* default label of the switch case, needs to be last */
++    result = build_modded_label(ctx->switchcount, "__dflt", EXPR_LOCATION(t));
++    *default_label = result;
++  } else if (CASE_LOW(t) != NULL_TREE && CASE_HIGH(t) == NULL_TREE) {
++    /* a case label */
++    if (get_subu_elem(ctx->mods, EXPR_LOCATION(t), &use)
++        /* the case is on a line we substituted */
++        && arg_should_be_unpatched(CASE_LOW(t), use, &replacement)
++        /* the case value is the one we substituted */) {
++      DEBUGF("modded case\n");
++      result =
++          build_modded_label(ctx->switchcount, use->name, EXPR_LOCATION(t));
++      ifs->safe_push(build_modded_if_stmt(
++          build2(EQ_EXPR, integer_type_node, swcond, replacement),
++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
++      remove_subu_elem(ctx->mods, use);
++      replacement = NULL_TREE;
++    } else {
++      /* a case label that we didn't substitute */
++      DEBUGF("unmodded case\n");
++      snprintf(case_str, sizeof(case_str), "%x_", i);
++      result = build_modded_label(ctx->switchcount, case_str, EXPR_LOCATION(t));
++      ifs->safe_push(build_modded_if_stmt(
++          build2(EQ_EXPR, integer_type_node, swcond, CASE_LOW(t)),
++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
++    }
++  } else {
++    DEBUGF("unmodded case range\n");
++    /* CASE_LOW(t) != NULL_TREE && CASE_HIGH(t) != NULL_TREE */
++    /* this is a case x .. y sort of range */
++    snprintf(case_str, sizeof(case_str), "%x_", i);
++    result = build_modded_label(ctx->switchcount, case_str, EXPR_LOCATION(t));
++    ifs->safe_push(build_modded_if_stmt(
++        build2(TRUTH_ANDIF_EXPR, integer_type_node,
++               build2(GE_EXPR, integer_type_node, swcond, CASE_LOW(t)),
++               build2(LE_EXPR, integer_type_node, swcond, CASE_HIGH(t))),
++        build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(result))));
++  }
++  return result;
++}
++
++tree build_modded_switch_stmt(tree swexpr, SubContext *ctx) {
++  int case_count = 0, break_count = 0;
++  int has_default = 0;
++
++  tree swcond = save_expr(SWITCH_STMT_COND(swexpr));
++  tree swbody = get_switch_body(swexpr);
++  tree *tp = NULL;
++  char dest[STRING_BUFFER_SIZE] = {0};
++
++  vec<tree> *ifs;
++  vec_alloc(ifs, 0);
++
++  tree exit_label = build_modded_exit_label(ctx->switchcount);
++  tree default_label = NULL_TREE;
++
++  for (auto it = tsi_start(swbody); !tsi_end_p(it); tsi_next(&it)) {
++    tp = tsi_stmt_ptr(it);
++    if (TREE_CODE(*tp) == CASE_LABEL_EXPR) {
++      case_count += 1;
++      has_default = has_default || (CASE_LOW(*tp) == NULL_TREE);
++      /* replace the case statement with a goto */
++      *tp =
++          modded_case_label(*tp, case_count, swcond, ifs, ctx, &default_label);
++    } else if (TREE_CODE(*tp) == BREAK_STMT) {
++      break_count += 1;
++      /* replace the break statement with a goto to the end */
++      *tp = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
++    } else if (TREE_CODE(*tp) == BIND_EXPR) {
++      for (auto it2 = tsi_start(BIND_EXPR_BODY(*tp)); !tsi_end_p(it2);
++           tsi_next(&it2)) {
++        auto tp2 = tsi_stmt_ptr(it2);
++        if (TREE_CODE(*tp2) == BREAK_STMT) {
++          break_count += 1;
++          /* replace the break statement with a goto to the end */
++          *tp2 =
++              build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
++        }
++      }
++    }
++  }
++  /* add all the if statements to the start of the switch body */
++  /* TODO: do we have to combine them via COND_EXPR_ELSE? why,
++   * is it not possible to have them as a list one after the other? */
++  tree res;
++  unsigned int zz = 0;
++  if (ifs->length() > 0) {
++    res = (*ifs)[0];
++    for (zz = 1; zz < ifs->length(); ++zz) {
++      COND_EXPR_ELSE(res) = (*ifs)[zz];
++      res = (*ifs)[zz];
++    }
++    /* if we have a valid default for the switch,
++     * it should be the final else branch */
++    if (default_label && default_label != NULL_TREE) {
++      COND_EXPR_ELSE(res) =
++          build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(default_label));
++    } else {
++      /* if we don't have a default, then the final else branch
++       * should just jump to after the switch */
++        COND_EXPR_ELSE(res) =
++              build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
++    }
++    /* reset to the start of the if-else tree */
++    res = (*ifs)[0];
++  } else if (has_default && default_label != NULL_TREE) {
++    /* this switch has only a default? ok... */
++    res = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(default_label));
++  } else {
++    /* this switch has no cases, and no default?! */
++    warning_at(EXPR_LOCATION(swcond), 0, "switch without cases or default?");
++    res = build1(GOTO_EXPR, void_type_node, LABEL_EXPR_LABEL(exit_label));
++  }
++  auto it = tsi_start(swbody);
++  tsi_link_before(&it, res, TSI_SAME_STMT);
++  tsi_link_before(&it, build_empty_stmt(UNKNOWN_LOCATION), TSI_SAME_STMT);
++
++  /* add the 'outside' of the switch, ie the 'finally'
++   * aka the target of the break statements, the 'exit_label',
++   * to the end of the switch body */
++  append_to_statement_list(build_empty_stmt(UNKNOWN_LOCATION), &swbody);
++  append_to_statement_list(exit_label, &swbody);
++  append_to_statement_list(build_empty_stmt(UNKNOWN_LOCATION), &swbody);
++
++  /* we are returning SWITCH_STMT_BODY(swexpr),
++   * instead of just swbody, because sometimes,
++   * SWITCH_STMT_BODY(swexpr) may be a BIND_EXPR
++   * that has some scoping-related information. */
++  return SWITCH_STMT_BODY(swexpr);
++}
+diff --git a/gcc/c-family/ifswitch.h b/gcc/c-family/ifswitch.h
+new file mode 100644
+index 000000000..ccf78067f
+--- /dev/null
++++ b/gcc/c-family/ifswitch.h
+@@ -0,0 +1,10 @@
++#ifndef IFSWITCH_H
++#define IFSWITCH_H
++#include "c-family/portcosmo.internal.h"
++#include "c-family/subcontext.h"
++
++source_range get_switch_bounds(tree);
++unsigned int count_mods_in_switch(tree, subu_list *);
++tree build_modded_switch_stmt(tree, SubContext *);
++
++#endif /* IFSWITCH_H */
+diff --git a/gcc/c-family/initstruct.cc b/gcc/c-family/initstruct.cc
+new file mode 100644
+index 000000000..b0162406c
+--- /dev/null
++++ b/gcc/c-family/initstruct.cc
+@@ -0,0 +1,396 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/initstruct.h"
++
++void portcosmo_finish_decl(void *gcc_data) {
++    handle_decl(gcc_data, (void *)(&cosmo_ctx));
++}
++
++void set_values_based_on_ctor(tree ctor, subu_list *list, tree body, tree lhs,
++                              location_t bound) {
++  subu_node *use = NULL;
++  unsigned int iprev = 0;
++  bool started = true;
++  tree replacement = NULL_TREE;
++
++  while (list->count > 0 && LOCATION_BEFORE2(list->start, bound)) {
++    tree index = NULL_TREE;
++    tree val = NULL_TREE;
++    unsigned int i = 0;
++    int found = 0;
++    FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(ctor), i, index, val) {
++      DEBUGF("value %u is %s\n", i, get_tree_code_str(val));
++      if (!started && i <= iprev) continue;
++      if (TREE_CODE(val) == INTEGER_CST) {
++        for (use = list->head; use; use = use->next) {
++          found = arg_should_be_unpatched(val, use, &replacement);
++          if (found) break;
++        }
++        if (found) {
++          iprev = i;
++          started = false;
++          break;
++        }
++      } else if (TREE_CODE(val) == CONSTRUCTOR) {
++        auto sub = access_at(lhs, index);
++        set_values_based_on_ctor(val, list, body, sub, bound);
++        use = NULL; /* might've gotten stomped */
++        if (list->count == 0) return;
++        get_subu_elem(list, list->start, &use);
++      }
++    }
++    if (found) {
++      auto modexpr = build2(MODIFY_EXPR, TREE_TYPE(index),
++                            access_at(lhs, index), replacement);
++      append_to_statement_list(modexpr, &body);
++      remove_subu_elem(list, use);
++      replacement = NULL_TREE;
++      DEBUGF("found; %d left\n", list->count);
++    } else {
++      /* we did not find any (more) substitutions to fix */
++      DEBUGF("exiting; %d left\n", list->count);
++      break;
++    }
++  }
++}
++
++/* initstruct/global.cc */
++
++void update_global_decls(tree dcl, SubContext *ctx) {
++  tree body = alloc_stmt_list();
++  subu_node *use = NULL;
++  char chk[STRING_BUFFER_SIZE];
++
++  /* dcl, the global declaration we have is like these:
++   *
++   * static int foo = __tmpcosmo_VAR;
++   * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
++   *
++   * we're going to add functions as follows:
++   *
++   * static int foo = __tmpcosmo_VAR;
++   * __attribute__((constructor)) __hidden_ctor1() {
++   *   foo = VAR;
++   * }
++   * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
++   * __attribute__((constructor)) __hidden_ctor2() {
++   *    myvalue.y = VAR;
++   * }
++   *
++   * the modifier functions have the constructor attribute,
++   * so it they run before anything uses the static. it
++   * works recursively too: you can have a struct of structs,
++   * an array of structs, whatever, and it will figure out
++   * where the substitutions are and attempt to mod them.
++   *
++   * a unique constructor for each declaration. probably
++   * we could have a common constructor for the entire
++   * file, but that's left as an exercise for the reader. */
++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl)) &&
++      get_subu_elem(ctx->mods, ctx->mods->start, &use) &&
++      /* use is non-NULL if get_subu_elem succeeds */
++      check_magic_equal(DECL_INITIAL(dcl), use->name)) {
++    if (TREE_READONLY(dcl)) {
++      error_at(EXPR_LOCATION(dcl), "cannot substitute this constant\n");
++      /* actually I can, but the issue is if one of gcc's optimizations
++       * perform constant folding(and they do), I don't know all the spots
++       * where this variable has been folded, so I can't substitute there */
++      ctx->active = 0;
++      return;
++    }
++    append_to_statement_list(
++        build2(MODIFY_EXPR, void_type_node, dcl, VAR_NAME_AS_TREE(use->name)),
++        &body);
++    remove_subu_elem(ctx->mods, use);
++    cgraph_build_static_cdtor('I', body, 0);
++  } else if ((RECORD_TYPE == TREE_CODE(TREE_TYPE(dcl)) ||
++              ARRAY_TYPE == TREE_CODE(TREE_TYPE(dcl))) &&
++             DECL_INITIAL(dcl) != NULL_TREE) {
++    if (TREE_READONLY(dcl)) {
++      warning_at(DECL_SOURCE_LOCATION(dcl), 0,
++                 "not sure if modding const structs is good\n");
++      TREE_READONLY(dcl) = 0;
++    }
++    if (LOCATION_BEFORE2(ctx->mods->end, input_location)) {
++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, body, dcl,
++                               input_location);
++    } else {
++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, body, dcl,
++                               ctx->mods->end);
++    }
++    cgraph_build_static_cdtor('I', body, 0);
++    DEBUGF("uploaded ctor\n");
++  }
++}
++
++void handle_decl(void *gcc_data, void *user_data) {
++  tree t = (tree)gcc_data;
++  SubContext *ctx = (SubContext *)user_data;
++  if (TREE_CODE(t) != VAR_DECL) return;
++  if (ctx->active && ctx->mods->count > 0 && DECL_INITIAL(t) != NULL &&
++      DECL_CONTEXT(t) == NULL_TREE) {
++    int internal_use =
++        !strncmp(IDENTIFIER_NAME(t), "__tmpcosmo_", strlen("__tmpcosmo_"));
++    if (internal_use || DECL_EXTERNAL(t)) {
++      error_at(input_location, "the ACTUALLY is before the declaration!\n");
++      ctx->active = 0;
++      return;
++    }
++    auto rng = EXPR_LOCATION_RANGE(t);
++    rng.m_start = DECL_SOURCE_LOCATION(t);
++    rng.m_finish = input_location;
++
++    DEBUGF("handle_decl with %s %u,%u - %u-%u\n", IDENTIFIER_NAME(t),
++           LOCATION_LINE(rng.m_start), LOCATION_COLUMN(rng.m_start),
++           LOCATION_LINE(rng.m_finish), LOCATION_COLUMN(rng.m_finish));
++    ctx->initcount += ctx->mods->count;
++    update_global_decls(t, ctx);
++    /* now at this stage, all uses of our macros have been
++     * fixed, INCLUDING case labels. Let's confirm that: */
++    check_context_clear(ctx, MAX_LOCATION_T);
++  }
++}
++
++/* initstruct/local.cc */
++
++static inline tree build_modded_if_stmt(tree condition, tree then_clause,
++                                        tree else_clause = NULL_TREE) {
++  return build3(COND_EXPR, void_type_node, condition, then_clause, else_clause);
++}
++
++int build_modded_int_declaration(tree *dxpr, SubContext *ctx, subu_node *use) {
++  char chk[STRING_BUFFER_SIZE];
++  tree dcl = DECL_EXPR_DECL(*dxpr);
++  tree replacement = NULL_TREE;
++
++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl)) &&
++      arg_should_be_unpatched(DECL_INITIAL(dcl), use, &replacement)) {
++    if (TREE_READONLY(dcl)) {
++      error_at(EXPR_LOCATION(dcl), "cannot substitute this constant\n");
++      /* actually I can, but the issue is if one of gcc's optimizations
++       * perform constant folding(and they do), I don't know all the spots
++       * where this variable has been folded, so I can't substitute there */
++      ctx->active = 0;
++      return 0;
++    }
++
++    if (!TREE_STATIC(dcl)) {
++      DECL_INITIAL(dcl) = replacement;
++      remove_subu_elem(ctx->mods, use);
++      replacement = NULL_TREE;
++      return 1;
++    }
++
++    DEBUGF("fixing decl for a static integer\n");
++    /* (*dxpr), the statement we have is this:
++     *
++     * static int myvalue = __tmpcosmo_VAR;
++     *
++     * we're going to modify it to this:
++     *
++     * static int myvalue = __tmpcosmo_VAR;
++     * static uint8 __chk_ifs_myvalue = 0;
++     * if(__chk_ifs_myvalue != 1) {
++     *   __chk_ifs_myvalue = 1;
++     *   myvalue = VAR;
++     * }
++     *
++     * so the modified statement runs exactly once,
++     * whenever the function is first called, right
++     * after the initialization of the variable we
++     * wanted to modify. */
++
++    /* build __chk_ifs_myvalue */
++    snprintf(chk, sizeof(chk), "__chk_ifs_%s", IDENTIFIER_NAME(dcl));
++    tree chknode = build_decl(DECL_SOURCE_LOCATION(dcl), VAR_DECL,
++                              get_identifier(chk), uint8_type_node);
++    DECL_INITIAL(chknode) = build_int_cst(uint8_type_node, 0);
++    TREE_STATIC(chknode) = TREE_STATIC(dcl);
++    TREE_USED(chknode) = TREE_USED(dcl);
++    DECL_READ_P(chknode) = DECL_READ_P(dcl);
++    DECL_CONTEXT(chknode) = DECL_CONTEXT(dcl);
++    DECL_CHAIN(chknode) = DECL_CHAIN(dcl);
++    DECL_CHAIN(dcl) = chknode;
++
++    /* create the then clause of the if statement */
++    tree then_clause = alloc_stmt_list();
++    append_to_statement_list(build2(MODIFY_EXPR, void_type_node, chknode,
++                                    build_int_cst(uint8_type_node, 1)),
++                             &then_clause);
++    append_to_statement_list(
++        build2(MODIFY_EXPR, void_type_node, dcl, replacement),
++        &then_clause);
++    /*
++    append_to_statement_list(
++        build_call_expr(VAR_NAME_AS_TREE("printf"), 1,
++                        BUILD_STRING_AS_TREE("initstruct magic\n")),
++        &then_clause);
++    */
++
++    /* create the if statement into the overall result mentioned above */
++    tree res = alloc_stmt_list();
++    append_to_statement_list(*dxpr, &res);
++    append_to_statement_list(build1(DECL_EXPR, void_type_node, chknode), &res);
++    append_to_statement_list(
++        build_modded_if_stmt(build2(NE_EXPR, void_type_node, chknode,
++                                    build_int_cst(uint8_type_node, 1)),
++                             then_clause),
++        &res);
++    /* overwrite the input tree with our new statements */
++    *dxpr = res;
++    remove_subu_elem(ctx->mods, use);
++    replacement = NULL_TREE;
++    return 1;
++  }
++  return 0;
++}
++
++void modify_local_struct_ctor(tree ctor, subu_list *list, location_t bound) {
++  subu_node *use = NULL;
++  unsigned int iprev = 0;
++  bool started = true;
++  tree replacement = NULL_TREE;
++
++  while (list->count > 0 && LOCATION_BEFORE2(list->start, bound)) {
++    tree val = NULL_TREE;
++    unsigned int i = 0;
++    int found = 0;
++    FOR_EACH_CONSTRUCTOR_VALUE(CONSTRUCTOR_ELTS(ctor), i, val) {
++      DEBUGF("value %u is %s\n", i, get_tree_code_str(val));
++      if (TREE_CODE(val) == INTEGER_CST) {
++        for (use = list->head; use; use = use->next) {
++          found = arg_should_be_unpatched(val, use, &replacement);
++          if (found) break;
++        }
++        if (found) {
++          iprev = i;
++          started = false;
++          break;
++        }
++      } else if (TREE_CODE(val) == CONSTRUCTOR) {
++        modify_local_struct_ctor(val, list, bound);
++        use = NULL; /* might've gotten stomped */
++        if (list->count == 0 || LOCATION_AFTER2(list->start, bound)) return;
++      }
++    }
++    if (found) {
++      DEBUGF("found\n");
++      // debug_tree(CONSTRUCTOR_ELT(ctor, i)->index);
++      CONSTRUCTOR_ELT(ctor, i)->value = replacement;
++      // debug_tree(CONSTRUCTOR_ELT(ctor, i)->value);
++      remove_subu_elem(list, use);
++      replacement = NULL_TREE;
++    } else {
++      /* we did not find any (more) substitutions to fix */
++      break;
++    }
++  }
++}
++
++void build_modded_declaration(tree *dxpr, SubContext *ctx, location_t bound) {
++  char chk[STRING_BUFFER_SIZE];
++  tree dcl = DECL_EXPR_DECL(*dxpr);
++  subu_node *use = NULL;
++  subu_list *list = ctx->mods;
++  unsigned int oldcount = list->count;
++
++  if (INTEGRAL_TYPE_P(TREE_TYPE(dcl))) {
++    get_subu_elem(list, list->start, &use);
++    if (build_modded_int_declaration(dxpr, ctx, use)) {
++      use = NULL;
++      ctx->initcount += 1;
++    }
++    return;
++  }
++
++  if ((RECORD_TYPE == TREE_CODE(TREE_TYPE(dcl)) ||
++       ARRAY_TYPE == TREE_CODE(TREE_TYPE(dcl))) &&
++      DECL_INITIAL(dcl) != NULL_TREE) {
++    if (TREE_READONLY(dcl)) {
++      warning_at(EXPR_LOCATION(*dxpr), 0,
++                 "not sure if modding const structs is good\n");
++      TREE_READONLY(dcl) = 0;
++      build_modded_declaration(dxpr, ctx, bound);
++      return;
++    } else if (TREE_STATIC(dcl)) {
++      DEBUGF("fixing decl for a static struct\n");
++      /* (*dxpr), the statement we have is this:
++       *
++       * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
++       *
++       * we're going to modify it to this:
++       *
++       * static struct toy myvalue = {.x=1, .y=__tmpcosmo_VAR};
++       * static uint8 __chk_ifs_myvalue = 0;
++       * if(__chk_ifs_myvalue != 1) {
++       *   __chk_ifs_myvalue = 1;
++       *   myvalue.y = VAR;
++       * }
++       *
++       * so the modified statement runs exactly once,
++       * whenever the function is first called, right
++       * after the initialization of the variable we
++       * wanted to modify. */
++
++      /* build __chk_ifs_myvalue */
++      snprintf(chk, sizeof(chk), "__chk_ifs_%s", IDENTIFIER_NAME(dcl));
++      tree chknode = build_decl(DECL_SOURCE_LOCATION(dcl), VAR_DECL,
++                                get_identifier(chk), uint8_type_node);
++      DECL_INITIAL(chknode) = build_int_cst(uint8_type_node, 0);
++      TREE_STATIC(chknode) = TREE_STATIC(dcl);
++      TREE_USED(chknode) = TREE_USED(dcl);
++      DECL_READ_P(chknode) = DECL_READ_P(dcl);
++      DECL_CONTEXT(chknode) = DECL_CONTEXT(dcl);
++      DECL_CHAIN(chknode) = DECL_CHAIN(dcl);
++      DECL_CHAIN(dcl) = chknode;
++
++      /* build a scope block for the temporary value */
++      tree tmpscope = build0(BLOCK, void_type_node);
++      BLOCK_SUPERCONTEXT(tmpscope) = TREE_BLOCK(*dxpr);
++      // debug_tree(BLOCK_SUPERCONTEXT(tmpscope));
++
++      /* create the then clause of the if statement */
++      tree then_clause = alloc_stmt_list();
++      append_to_statement_list(build2(MODIFY_EXPR, void_type_node, chknode,
++                                      build_int_cst(uint8_type_node, 1)),
++                               &then_clause);
++      set_values_based_on_ctor(DECL_INITIAL(dcl), ctx->mods, then_clause, dcl,
++                               bound);
++
++      /* create the if statement into the overall result mentioned above */
++      tree res = alloc_stmt_list();
++      append_to_statement_list(*dxpr, &res);
++      append_to_statement_list(build1(DECL_EXPR, void_type_node, chknode),
++                               &res);
++      append_to_statement_list(
++          build_modded_if_stmt(build2(NE_EXPR, void_type_node, chknode,
++                                      build_int_cst(uint8_type_node, 1)),
++                               then_clause),
++          &res);
++      /* overwrite the input tree with our new statements */
++      *dxpr = res;
++    } else {
++      /* if it's a local struct, we can
++       * just mod the constructor itself */
++      auto ctor = DECL_INITIAL(dcl);
++      modify_local_struct_ctor(ctor, list, bound);
++    }
++  }
++  ctx->initcount += (oldcount - list->count);
++}
+diff --git a/gcc/c-family/initstruct.h b/gcc/c-family/initstruct.h
+new file mode 100644
+index 000000000..f77fba707
+--- /dev/null
++++ b/gcc/c-family/initstruct.h
+@@ -0,0 +1,15 @@
++#ifndef INITSTRUCT_H
++#define INITSTRUCT_H
++#include "c-family/portcosmo.internal.h"
++/* gcc utils first */
++#include "c-family/subcontext.h"
++
++void build_modded_declaration(tree *, SubContext *, location_t);
++int build_modded_int_declaration(tree *, SubContext *, subu_node *);
++tree copy_struct_ctor(tree);
++void modify_local_struct_ctor(tree, subu_list *, location_t);
++
++void set_values_based_on_ctor(tree, subu_list *, tree, tree, location_t);
++void handle_decl(void *, void *);
++tree access_at(tree, tree);
++#endif /* INITSTRUCT_H */
+diff --git a/gcc/c-family/portcosmo.cc b/gcc/c-family/portcosmo.cc
+new file mode 100644
+index 000000000..37cd2847c
+--- /dev/null
++++ b/gcc/c-family/portcosmo.cc
+@@ -0,0 +1,208 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/portcosmo.internal.h"
++#include "c-family/subcontext.h"
++#include "c-family/ifswitch.h"
++#include "c-family/initstruct.h"
++
++static tree patch_int_nonconst(location_t, tree, const char **);
++
++struct SubContext cosmo_ctx;
++static int ctx_inited = 0;
++static void (*other_define) (cpp_reader *, location_t, cpp_hashnode *) = NULL;
++
++void check_macro_define(cpp_reader *reader, location_t loc,
++                        cpp_hashnode *node) {
++  const char *defn = (const char *)cpp_macro_definition(reader, node);
++  if (cosmo_ctx.active && strstr(defn, "__tmpcosmo_") == defn)
++  {
++    const char *arg_start = defn + strlen("__tmpcosmo_");
++    const char *arg_end = strstr(arg_start, " ");
++    if (!arg_start || !arg_end || arg_end - arg_start < 1) return;
++    char* name = xstrndup(arg_start, arg_end - arg_start);
++    char* val = xstrdup(arg_end);
++    long long val2 = strtoll(arg_end, NULL, 0);
++    if (val2 == 0) {
++        cpp_error_at(parse_in, CPP_DL_ERROR, loc,
++                "cannot parse portcosmo temporary constant\n");
++        cosmo_ctx.active = 0;
++    } else {
++        if (cosmo_ctx.map->get(name)) {
++            cpp_error_at(parse_in, CPP_DL_ERROR, loc,
++                    "duplicate portcosmo temporary constant\n");
++            cosmo_ctx.active = 0;
++        } else {
++            tmpconst z;
++            z.raw = val2; 
++            z.t = build_int_cst(long_long_integer_type_node, val2);
++            cosmo_ctx.map->put(name, z);
++            // INFORM(loc, "added temporary for %s\n", name);
++        }
++    }
++    /* not freeing name because it's in the hashmap */
++    free(val);
++  }
++  else if(other_define) {
++     DEBUGF("we should just let this be %s\n", defn);
++     other_define(reader, loc, node);
++  }
++}
++
++void portcosmo_setup() {
++    cpp_callbacks *cbs = cpp_get_callbacks(parse_in);
++    if (flag_portcosmo && 0 == ctx_inited) {
++        construct_context(&cosmo_ctx);
++        ctx_inited = 1;
++        if (cbs) {
++            if (cbs->define) {
++                other_define = cbs->define;
++                /* TODO: do we need for cbs->undef as well? */
++            }
++            cbs->define = check_macro_define;
++        }
++    }
++}
++
++void portcosmo_teardown() {
++    if (flag_portcosmo && 1 == ctx_inited) {
++        cleanup_context(&cosmo_ctx);
++        ctx_inited = 0;
++    }
++}
++
++void portcosmo_show_tree(location_t loc, tree t) {
++    INFORM(loc, "attempting case substitution at: line %u, col %u\n",
++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
++    debug_tree(t);
++}
++
++tree patch_case_nonconst(location_t loc, tree t) {
++    INFORM(loc, "attempting case substitution at: line %u, col %u\n",
++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
++    tree subs = NULL_TREE;
++    const char *name = NULL;
++    if (cosmo_ctx.active) {
++        subs = patch_int_nonconst(loc, t, &name);
++        if (subs != NULL_TREE) {
++            DEBUGF("folding...\n");
++            subs = c_fully_fold(subs, false, NULL, false);
++            /* this substitution was successful, so record
++             * the location for rewriting the thing later */
++            add_context_subu(&cosmo_ctx, loc, name, strlen(name),
++                             PORTCOSMO_SWCASE);
++        }
++    }
++    if (subs == NULL_TREE) {
++        inform(loc, "unable to find __tmpcosmo_ temporary");
++    }
++    return subs;
++}
++
++tree patch_init_nonconst(location_t loc, tree t) {
++    INFORM(loc, "attempting init substitution at: line %u, col %u\n",
++           LOCATION_LINE(loc), LOCATION_COLUMN(loc));
++    tree subs = NULL_TREE;
++    const char *name = NULL;
++    if (cosmo_ctx.active) {
++        subs = patch_int_nonconst(loc, t, &name);
++        if (subs != NULL_TREE) {
++            DEBUGF("folding...\n");
++            subs = c_fully_fold(subs, false, NULL, false);
++            /* this substitution was successful, so record
++             * the location for rewriting the thing later */
++            add_context_subu(&cosmo_ctx, loc, name, strlen(name),
++                             PORTCOSMO_INITVAL);
++            DEBUGF("done\n");
++        }
++    }
++    if (subs == NULL_TREE) {
++        inform(loc, "unable to find __tmpcosmo_ temporary");
++    }
++    return subs;
++}
++
++/* internal functions */
++
++static tree patch_int_nonconst(location_t loc, tree t, const char **res) {
++    /* t may be an integer inside a case label, or
++     * t may be an integer inside an initializer */
++    tree subs = NULL_TREE;
++    switch (TREE_CODE(t)) {
++        case VAR_DECL:
++            subs = maybe_get_tmpconst_value(IDENTIFIER_NAME(t));
++            if (subs != NULL_TREE) {
++                *res = IDENTIFIER_NAME(t);
++                DEBUGF("substitution exists %s\n", *res);
++            }
++            break;
++        case CONVERT_EXPR:
++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
++            if (subs != NULL_TREE) {
++                subs = build1(CONVERT_EXPR, integer_type_node, subs);
++            }
++            break;
++        case NOP_EXPR:
++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
++            if (subs != NULL_TREE) {
++                subs = build1(NOP_EXPR, integer_type_node, subs);
++            }
++            break;
++        case NEGATE_EXPR:
++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
++            if (subs != NULL_TREE) {
++                subs = build1(NEGATE_EXPR, integer_type_node, subs);
++            }
++            break;
++        case BIT_NOT_EXPR:
++            subs = patch_int_nonconst(loc, TREE_OPERAND(t, 0), res);
++            if (subs != NULL_TREE) {
++                subs = build1(BIT_NOT_EXPR, integer_type_node, subs);
++            }
++            break;
++        default:
++            subs = NULL_TREE;
++    }
++    return subs;
++}
++
++const char *get_tree_code_str(tree expr) {
++#define END_OF_BASE_TREE_CODES
++#define DEFTREECODE(a, b, c, d) \
++    case a:                     \
++        return b;
++    switch (TREE_CODE(expr)) {
++#include "all-tree.def"
++        default:
++            return "<unknown>";
++    }
++#undef DEFTREECODE
++#undef END_OF_BASE_TREE_CODES
++}
++
++tree maybe_get_tmpconst_value(const char *s) {
++    char *result = xstrdup(s);
++    tmpconst *z = cosmo_ctx.map->get(result);
++    free(result);
++    return z ? z->t : NULL_TREE;
++}
++
++int check_magic_equal(tree value, char *varname) {
++    tree vx = maybe_get_tmpconst_value(varname);
++    return vx != NULL_TREE && tree_int_cst_equal(value, vx);
++}
+diff --git a/gcc/c-family/portcosmo.h b/gcc/c-family/portcosmo.h
+new file mode 100644
+index 000000000..b25d8257b
+--- /dev/null
++++ b/gcc/c-family/portcosmo.h
+@@ -0,0 +1,13 @@
++#ifndef PORTCOSMO_H
++#define PORTCOSMO_H
++#include <tree.h>
++
++void portcosmo_setup();
++void portcosmo_teardown();
++void portcosmo_pre_genericize(void*);
++void portcosmo_finish_decl(void*);
++void portcosmo_show_tree(location_t, tree);
++tree patch_case_nonconst(location_t, tree);
++tree patch_init_nonconst(location_t, tree);
++
++#endif /* PORTCOSMO_H */
+diff --git a/gcc/c-family/portcosmo.internal.h b/gcc/c-family/portcosmo.internal.h
+new file mode 100644
+index 000000000..77e59050a
+--- /dev/null
++++ b/gcc/c-family/portcosmo.internal.h
+@@ -0,0 +1,54 @@
++#ifndef PORTCOSMO_INTERNAL_H
++#define PORTCOSMO_INTERNAL_H
++/* first stdlib headers */
++#include <stdio.h>
++/* now all the plugin headers */
++#include <gcc-plugin.h>
++/* first gcc-plugin, then the others */
++#include <c-family/c-common.h>
++#include <c-family/c-pragma.h>
++#include <c/c-tree.h>
++#include <cgraph.h>
++#include <cpplib.h>
++#include <diagnostic.h>
++#include <print-tree.h>
++#include <stringpool.h>
++#include <tree-iterator.h>
++#include <tree.h>
++
++const char *get_tree_code_str(tree);
++tree maybe_get_tmpconst_value(const char *);
++int check_magic_equal(tree, char *);
++
++#define EXPR_LOC_LINE(x)      LOCATION_LINE(EXPR_LOCATION((x)))
++#define EXPR_LOC_COL(x)       LOCATION_COLUMN(EXPR_LOCATION((x)))
++#define LOCATION_APPROX(x, y) (LOCATION_LINE((x)) == LOCATION_LINE((y)))
++#define LOCATION_BEFORE(x, y) (LOCATION_LINE((x)) <= LOCATION_LINE((y)))
++#define LOCATION_AFTER(x, y)  (LOCATION_LINE((x)) >= LOCATION_LINE((y)))
++
++#define LOCATION_BEFORE2(x, y)                  \
++  (LOCATION_LINE((x)) < LOCATION_LINE((y)) ||   \
++   (LOCATION_LINE((x)) == LOCATION_LINE((y)) && \
++    LOCATION_COLUMN((x)) <= LOCATION_COLUMN((y))))
++#define LOCATION_AFTER2(x, y)                   \
++  (LOCATION_LINE((x)) > LOCATION_LINE((y)) ||   \
++   (LOCATION_LINE((x)) == LOCATION_LINE((y)) && \
++    LOCATION_COLUMN((x)) >= LOCATION_COLUMN((y))))
++
++#define VAR_NAME_AS_TREE(fname)   lookup_name(get_identifier((fname)))
++#define IDENTIFIER_NAME(z)        IDENTIFIER_POINTER(DECL_NAME((z)))
++#define BUILD_STRING_AS_TREE(str) build_string_literal(strlen((str)) + 1, (str))
++
++#if 0
++#define DEBUGF(...) fprintf(stderr, "<DEBUG> " __VA_ARGS__)
++#define INFORM(...) inform(__VA_ARGS__)
++#else
++#define DEBUGF(...)
++#define INFORM(...)
++#endif
++
++#define STRING_BUFFER_SIZE 192
++
++void handle_pre_genericize(void *, void *);
++
++#endif /* PORTCOSMO.INTERNAL_H */
+diff --git a/gcc/c-family/subcontext.cc b/gcc/c-family/subcontext.cc
+new file mode 100644
+index 000000000..40d180b2c
+--- /dev/null
++++ b/gcc/c-family/subcontext.cc
+@@ -0,0 +1,245 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/subcontext.h"
++
++subu_node *build_subu(const location_t loc, const char *name,
++                      unsigned int namelen, SubstType tp) {
++  /* xmalloc because malloc is poisoned by gcc-plugin's system.h */
++  subu_node *res = (subu_node *)xmalloc(sizeof(subu_node));
++  res->next = NULL;
++  res->loc = loc;
++  res->name = xstrndup(name, namelen);
++  res->tp = tp;
++  DEBUGF("allocated subu_node at %p\n", res);
++  return res;
++};
++
++void delete_subu(subu_node *node) {
++  DEBUGF("freeing subu_node at %p, %u,%u\n", node, LOCATION_LINE(node->loc),
++         LOCATION_COLUMN(node->loc));
++  node->loc = 0x0;
++  free(node->name);
++  node->next = NULL;
++  node->tp = PORTCOSMO_UNKNOWN;
++  free(node);
++}
++
++subu_list *init_subu_list() {
++  subu_list *res = (subu_list *)xmalloc(sizeof(subu_list));
++  res->head = NULL;
++  res->count = 0;
++  res->start = 0;
++  res->end = 0;
++  DEBUGF("allocated subu_list at %p\n", res);
++  return res;
++}
++
++static void recount_subu_list(subu_list *list) {
++  int i = 0;
++  location_t s = MAX_LOCATION_T;
++  location_t e = 0;
++  subu_node *it;
++  for (it = list->head; it != NULL; it = it->next) {
++    i += 1;
++    /* is it possible to compare for s and e? */
++    if (s == MAX_LOCATION_T || LOCATION_BEFORE2(it->loc, s)) s = it->loc;
++    if (LOCATION_AFTER2(it->loc, e)) e = it->loc;
++  }
++  if (LOCATION_AFTER2(s, e)) {
++    s = e;
++  }
++  list->start = s;
++  list->end = e;
++  list->count = i;
++  DEBUGF("list with %d subus, start = %u,%u end = %u,%u\n", list->count,
++         LOCATION_LINE(list->start), LOCATION_COLUMN(list->start),
++         LOCATION_LINE(list->end), LOCATION_COLUMN(list->end));
++}
++
++void add_subu_elem(subu_list *list, subu_node *node) {
++  subu_node *tmp;
++  if (list->head == NULL) {
++    list->head = node;
++  } else {
++    for (tmp = list->head; tmp->next != NULL; tmp = tmp->next)
++      ;
++    tmp->next = node;
++    node->next = NULL;
++  }
++  recount_subu_list(list);
++}
++
++void pop_subu_list(subu_list *list) {
++  if (list->head != NULL) {
++    subu_node *tmp = list->head;
++    list->head = list->head->next;
++    delete_subu(tmp);
++  }
++  recount_subu_list(list);
++}
++
++int valid_subu_bounds(subu_list *list, location_t start, location_t end) {
++  /* return 1 if the bounds of list and provided bounds overlap */
++  if (LOCATION_BEFORE(list->start, end) && LOCATION_AFTER(list->start, start))
++    return 1;
++  if (LOCATION_BEFORE(start, list->end) && LOCATION_AFTER(start, list->start))
++    return 1;
++  return 0;
++}
++
++int check_loc_in_bound(subu_list *list, location_t loc) {
++  /* return 1 if loc is within the bounds */
++  if (LOCATION_BEFORE(list->start, loc) && LOCATION_AFTER(list->end, loc)) {
++    return 1;
++  } else {
++    return 0;
++  }
++}
++
++int get_subu_elem(subu_list *list, location_t loc, subu_node **node) {
++  /* *node is overwritten on returning 1 ie success */
++  subu_node *it = list->head;
++  for (; it != NULL; it = it->next) {
++    if (LOCATION_APPROX(it->loc, loc)) {
++      *node = it;
++      return 1;
++    }
++  }
++  return 0;
++}
++
++int get_subu_elem2(subu_list *list, source_range rng, subu_node **node) {
++  /* *node is overwritten on returning 1 ie success */
++  /* returns the first node found within rng's bounds */
++  subu_node *it = list->head;
++  for (; it != NULL; it = it->next) {
++    if (LOCATION_BEFORE(rng.m_start, it->loc) &&
++        LOCATION_AFTER(rng.m_finish, it->loc)) {
++      *node = it;
++      return 1;
++    }
++  }
++  return 0;
++}
++
++void remove_subu_elem(subu_list *list, subu_node *node) {
++  subu_node *cur, *prev;
++  if (list->head != NULL) {
++    if (list->head == node) {
++      cur = list->head;
++      list->head = list->head->next;
++      delete_subu(cur);
++    } else {
++      prev = list->head;
++      cur = list->head->next;
++      for (; cur != NULL; prev = cur, cur = cur->next) {
++        if (cur == node) {
++          prev->next = cur->next;
++          delete_subu(cur);
++          break;
++        }
++      }
++    }
++    recount_subu_list(list);
++  }
++}
++
++void clear_subu_list(subu_list *list) {
++  subu_node *it, *tmp;
++  for (it = list->head; it != NULL;) {
++    tmp = it;
++    it = it->next;
++    delete_subu(tmp);
++  }
++  list->head = NULL;
++  list->count = 0;
++  list->start = 0;
++  list->end = 0;
++}
++
++void delete_subu_list(subu_list *list) {
++  clear_subu_list(list);
++  free(list);
++  DEBUGF("freeing subu_list at %p\n", list);
++}
++
++int check_empty_subu_list(subu_list *list, location_t start) {
++  /* we should have modded all locations before start, and so
++   * list should not contain any entries which have a location
++   * before start */
++  int errcount = 0;
++  for (auto it = list->head; it; it = it->next) {
++    if (start == MAX_LOCATION_T || LOCATION_BEFORE2(it->loc, start)) {
++      error_at(it->loc, "unable to substitute constant\n");
++      errcount += 1;
++    }
++  }
++  if (errcount != 0) {
++    /* DON'T DELETE! */
++    clear_subu_list(list);
++  }
++  return errcount == 0;
++}
++
++void construct_context(SubContext *ctx) {
++  ctx->active = 1;
++  ctx->mods = init_subu_list();
++  ctx->prev = NULL;
++  ctx->switchcount = 0;
++  ctx->initcount = 0;
++  ctx->subcount = 0;
++  ctx->map = NULL;
++  ctx->map = hash_map_maybe_create<false, char, tmpconst, tmpmap_traits>(ctx->map);
++}
++
++void add_context_subu(SubContext *ctx, const location_t loc, const char *defn,
++                      unsigned int at, SubstType st) {
++  if (ctx->mods == NULL) return;
++  add_subu_elem(ctx->mods, build_subu(loc, defn, at, st));
++}
++
++void check_context_clear(SubContext *ctx, location_t start) {
++  if (ctx->mods) {
++    ctx->active = check_empty_subu_list(ctx->mods, start);
++  }
++}
++
++void cleanup_context(SubContext *ctx) {
++  check_context_clear(ctx, MAX_LOCATION_T);
++  if (ctx->mods) {
++    delete_subu_list(ctx->mods);
++    ctx->mods = NULL;
++  }
++  ctx->prev = NULL;
++  if (ctx->switchcount > 0) {
++    inform(UNKNOWN_LOCATION, "rewrote %u switch statements", ctx->switchcount);
++  }
++  ctx->switchcount = 0;
++  if (ctx->initcount > 0) {
++    inform(UNKNOWN_LOCATION, "modified %u initializations", ctx->initcount);
++  }
++  ctx->initcount = 0;
++  if (ctx->subcount > 0) {
++    inform(UNKNOWN_LOCATION, "modified %u other macro uses", ctx->subcount);
++  }
++  ctx->subcount = 0;
++  ctx->active = 0;
++  delete ctx->map;
++  ctx->map = NULL;
++}
+diff --git a/gcc/c-family/subcontext.h b/gcc/c-family/subcontext.h
+new file mode 100644
+index 000000000..e4ffaad0c
+--- /dev/null
++++ b/gcc/c-family/subcontext.h
+@@ -0,0 +1,103 @@
++#ifndef SUBCONTEXT_H
++#define SUBCONTEXT_H
++#include "c-family/portcosmo.internal.h"
++#include "hash-map-traits.h"
++#include "hash-map.h"
++#include "hash-traits.h"
++
++enum SubstType { 
++    PORTCOSMO_UNKNOWN = 0, 
++    PORTCOSMO_SWCASE = 1, 
++    PORTCOSMO_INITVAL = 2 
++};
++
++struct subu_node {
++  /* a node indicating that an ifswitch substitution has occurred.
++   *
++   * Details include:
++   *
++   * - location_t of the substitution
++   * - char* of name of the macro that was substituted (alloc'd)
++   * - whether the substitution was inside a switch statement
++   * - _subu_node* pointer to the next element in the list (NULL if last)
++   *
++   * the idea is that every time one of our modified macros is used,
++   * we record the substitution, and then we delete this record if
++   * we find the appropriate location_t during pre-genericize and
++   * construct the necessary parse trees at that point.
++   *
++   * at the end of compilation (ie PLUGIN_FINISH), there should be
++   * no subu_nodes allocated.
++   */
++  location_t loc;
++  SubstType tp;
++  char *name;
++  struct subu_node *next;
++};
++
++typedef struct subu_node subu_node;
++
++struct subu_list {
++  subu_node *head;
++  /* inclusive bounds, range containing all recorded substitutions */
++  location_t start, end;
++  /* number of substitutions */
++  int count;
++};
++typedef struct subu_list subu_list;
++
++int check_loc_in_bound(subu_list *, location_t);
++int valid_subu_bounds(subu_list *, location_t, location_t);
++int get_subu_elem(subu_list *, location_t, subu_node **);
++int get_subu_elem2(subu_list *, source_range, subu_node **);
++void remove_subu_elem(subu_list *, subu_node *);
++
++struct tmpconst {
++    long long raw;
++    tree t;
++};
++typedef struct tmpconst tmpconst;
++
++struct free_string_hash : pointer_hash<char>, typed_free_remove <char> {
++  static inline hashval_t hash (char *id) {
++    return htab_hash_string (id);
++  };
++  static inline bool equal (char *a, char *b) {
++    return strcmp(a, b) == 0;
++  };
++};
++using tmpmap_traits = simple_hashmap_traits<free_string_hash, tmpconst>;
++using tmpmap = hash_map<char, tmpconst, tmpmap_traits>;
++
++/* Substitution Context */
++struct SubContext {
++  /* record all macro uses */
++  subu_list *mods;
++  /* address of the previous statement we walked through,
++   * in case we missed modding it and have to retry */
++  tree *prev;
++  /* count number of switch statements rewritten */
++  unsigned int switchcount;
++  /* count number of initializations rewritten */
++  unsigned int initcount;
++  /* count number of other substitutions rewritten */
++  unsigned int subcount;
++  /* if zero, it means we haven't started or something
++   * went wrong somewhere */
++  int active;
++  /* store values of all temporary constants */
++  tmpmap *map;
++};
++
++void add_context_subu(SubContext *, const location_t, const char *,
++                      unsigned int, SubstType);
++void construct_context(SubContext *);
++void check_context_clear(SubContext *, location_t);
++void cleanup_context(SubContext *);
++
++int arg_should_be_unpatched(tree, const subu_node *, tree *);
++
++/* declaring cosmo_ctx here so initstruct knows it exists */
++extern struct SubContext cosmo_ctx;
++
++#endif /* SUBCONTEXT_H */
+diff --git a/gcc/c-family/unpatch_ast.cc b/gcc/c-family/unpatch_ast.cc
+new file mode 100644
+index 000000000..56b5b9a01
+--- /dev/null
++++ b/gcc/c-family/unpatch_ast.cc
+@@ -0,0 +1,115 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/ifswitch.h"
++#include "c-family/initstruct.h"
++
++tree check_usage(tree *tp, int *check_subtree, void *data) {
++    SubContext *ctx = (SubContext *)(data);
++    tree t = *tp;
++    tree z;
++    subu_node *use = NULL;
++    location_t loc = EXPR_LOCATION(t);
++    source_range rng = EXPR_LOCATION_RANGE(t);
++
++    if (ctx->active == 0 || ctx->mods->count == 0) {
++        /* DEBUGF("substitutions complete\n"); */
++        *check_subtree = 0;
++        return NULL_TREE;
++    }
++
++    if (LOCATION_AFTER2(loc, rng.m_start)) {
++        loc = rng.m_start;
++    } else {
++        rng.m_start = loc;
++    }
++
++    if (ctx->prev && LOCATION_BEFORE2(ctx->mods->start, rng.m_start)) {
++        auto vloc = DECL_SOURCE_LOCATION(DECL_EXPR_DECL(*(ctx->prev)));
++        /* below inequality holds inside this if condition:
++         *    vloc <= ctx->mods->start <= rng.m_start
++         * this means that there was a macro substitution
++         * between vloc and rng.m_start, which was not
++         * eliminated when we went through the other parts
++         * of the parse tree earlier. thus, the decl_expr
++         * that we have stored in ctx->prev needs to be
++         * checked for possible macro substitutions */
++        DEBUGF(
++            "did we miss a decl? vloc=%u,%u, loc=%u,%u, rng.mstart=%u,%u, "
++            "start=%u,%u\n",
++            LOCATION_LINE(vloc), LOCATION_COLUMN(vloc),  //
++            LOCATION_LINE(loc), LOCATION_COLUMN(loc),    //
++            LOCATION_LINE(rng.m_start), LOCATION_COLUMN(rng.m_start),
++            LOCATION_LINE(ctx->mods->start), LOCATION_COLUMN(ctx->mods->start));
++        auto z = ctx->initcount;
++        build_modded_declaration(ctx->prev, ctx, rng.m_start);
++        if (z != ctx->initcount) {
++            ctx->prev = NULL;
++            check_context_clear(ctx, loc);
++        }
++    }
++
++    if (TREE_CODE(t) == DECL_EXPR && TREE_STATIC(DECL_EXPR_DECL(t))) {
++        INFORM(loc, "should we mod this?\n");
++        ctx->prev = tp;
++    }
++
++    if (TREE_CODE(t) == SWITCH_STMT) {
++        rng = get_switch_bounds(t);
++        if (valid_subu_bounds(ctx->mods, rng.m_start, rng.m_finish) &&
++            count_mods_in_switch(t, ctx->mods) > 0) {
++            /* this is one of the switch statements
++             * where we modified a case label */
++            DEBUGF("modding the switch \n");
++            *tp = build_modded_switch_stmt(t, ctx);
++            DEBUGF("we modded it??\n");
++            walk_tree_without_duplicates(tp, check_usage, ctx);
++            /* due to the above call, I don't need to check
++             * any subtrees from this current location */
++            *check_subtree = 0;
++            ctx->switchcount += 1;
++            return NULL_TREE;
++        }
++    }
++
++    return NULL_TREE;
++}
++
++void handle_pre_genericize(void *gcc_data, void *user_data) {
++    tree t = (tree)gcc_data;
++    SubContext *ctx = (SubContext *)user_data;
++    tree t2;
++    if (ctx->active && TREE_CODE(t) == FUNCTION_DECL &&
++        DECL_INITIAL(t) != NULL && TREE_STATIC(t)) {
++        /* this function is defined within the file I'm processing */
++        if (ctx->mods->count == 0) {
++            // DEBUGF("no substitutions were made in %s\n", IDENTIFIER_NAME(t));
++            return;
++        }
++        t2 = DECL_SAVED_TREE(t);
++        ctx->prev = NULL;
++        walk_tree_without_duplicates(&t2, check_usage, ctx);
++        /* now at this stage, all uses of our macros have been
++         * fixed, INCLUDING case labels. Let's confirm that: */
++        check_context_clear(ctx, MAX_LOCATION_T);
++    }
++}
++
++void portcosmo_pre_genericize(void *gcc_data) {
++    handle_pre_genericize(gcc_data, (void *)(&cosmo_ctx));
++}
+diff --git a/gcc/c-family/unpatch_int.cc b/gcc/c-family/unpatch_int.cc
+new file mode 100644
+index 000000000..31a2cebb0
+--- /dev/null
++++ b/gcc/c-family/unpatch_int.cc
+@@ -0,0 +1,66 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/subcontext.h"
++
++int arg_should_be_unpatched(tree arg, const subu_node *use, tree *rep_ptr) {
++  /* if we are returning 1, rep_ptr has been set.
++   * if we are returning 0, rep_ptr is unchanged.
++   * use is not affected! */
++  if (TREE_CODE(arg) == INTEGER_CST) {
++    tree vx = maybe_get_tmpconst_value(use->name);
++    if (vx == NULL_TREE) {
++        return 0;
++    }
++    if (tree_int_cst_equal(arg, vx)) {
++      /* if this is an integer constant, AND its
++       * value is equal to the macro we substituted,
++       * then we replace the correct variable here */
++      *rep_ptr =
++          build1(NOP_EXPR, integer_type_node, VAR_NAME_AS_TREE(use->name));
++      INFORM(use->loc, "unpatched an integer here with %s\n", use->name);
++      return 1;
++    }
++    /* here you might want to handle some
++     * minimal constant folding algebra,
++     * like -VAR or ~VAR */
++    if (tree_fits_poly_int64_p(vx) && tree_fits_poly_int64_p(arg)) {
++      auto v1 = tree_to_poly_int64(vx);
++      auto v2 = tree_to_poly_int64(arg);
++
++      /* handle the -VAR case */
++      if (known_eq(v1, -v2)) {
++        INFORM(use->loc, "unpatched an integer here with -%s\n", use->name);
++        *rep_ptr =
++            build1(NEGATE_EXPR, integer_type_node, VAR_NAME_AS_TREE(use->name));
++        return 1;
++      }
++
++      /* handle the ~VAR case */
++      if (known_eq(v1, ~v2)) {
++        INFORM(use->loc, "unpatched an integer here with ~%s\n", use->name);
++        *rep_ptr = build1(BIT_NOT_EXPR, integer_type_node,
++                          VAR_NAME_AS_TREE(use->name));
++        return 1;
++      }
++    }
++    return 0;
++  }
++
++  return 0;
++}
+diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
+index a1cdee872..ce57e8a27 100644
+--- a/gcc/c/Make-lang.in
++++ b/gcc/c/Make-lang.in
+@@ -55,8 +55,10 @@ C_AND_OBJC_OBJS = attribs.o c/c-errors.o c/c-decl.o c/c-typeck.o \
+   c/c-fold.o c/gimple-parser.o \
+   $(C_COMMON_OBJS) $(C_TARGET_OBJS)
+ 
++PORTCOSMO_C_OBJS = c/portcosmo_bcref.o
++
+ # Language-specific object files for C.
+-C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS)
++C_OBJS = c/c-lang.o c-family/stub-objc.o $(C_AND_OBJC_OBJS) $(PORTCOSMO_C_OBJS)
+ c_OBJS = $(C_OBJS) cc1-checksum.o c/gccspec.o
+ 
+ # Use strict warnings for this front end.
+diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
+index 53b2b5b63..51f3a72e5 100644
+--- a/gcc/c/c-decl.c
++++ b/gcc/c/c-decl.c
+@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
+ #include "c-family/name-hint.h"
+ #include "c-family/known-headers.h"
+ #include "c-family/c-spellcheck.h"
++#include "c-family/portcosmo.h"
+ #include "context.h"  /* For 'g'.  */
+ #include "omp-general.h"
+ #include "omp-offload.h"  /* For offload_vars.  */
+@@ -5685,6 +5686,9 @@ finish_decl (tree decl, location_t init_loc, tree init,
+       && !DECL_HARD_REGISTER (decl))
+     targetm.lower_local_decl_alignment (decl);
+ 
++  if(flag_portcosmo) {
++      portcosmo_finish_decl(decl);
++  }
+   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+ }
+ 
+@@ -10277,6 +10281,10 @@ finish_function (location_t end_loc)
+     {
+       if (!decl_function_context (fndecl))
+ 	{
++      if (flag_portcosmo)
++     {
++        portcosmo_pre_genericize(fndecl); 
++     }
+ 	  invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
+ 	  c_genericize (fndecl);
+ 
+diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
+index b5d139e5d..45be3af80 100644
+--- a/gcc/c/c-typeck.c
++++ b/gcc/c/c-typeck.c
+@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3.  If not see
+ #include "omp-general.h"
+ #include "c-family/c-objc.h"
+ #include "c-family/c-ubsan.h"
++#include "c-family/portcosmo.h"
+ #include "gomp-constants.h"
+ #include "spellcheck-tree.h"
+ #include "gcc-rich-location.h"
+@@ -8159,10 +8160,10 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
+ 	    = valid_compound_expr_initializer (inside_init,
+ 					       TREE_TYPE (inside_init));
+ 	  if (inside_init == error_mark_node)
+-	    error_init (init_loc, "initializer element is not constant");
++	    error_init (init_loc, "initializer element is not constant 8163");
+ 	  else
+ 	    pedwarn_init (init_loc, OPT_Wpedantic,
+-			  "initializer element is not constant");
++			  "initializer element is not constant 8166");
+ 	  if (flag_pedantic_errors)
+ 	    inside_init = error_mark_node;
+ 	}
+@@ -8170,8 +8171,17 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
+ 	       && !initializer_constant_valid_p (inside_init,
+ 						 TREE_TYPE (inside_init)))
+ 	{
+-	  error_init (init_loc, "initializer element is not constant");
+-	  inside_init = error_mark_node;
++      if (flag_portcosmo) {
++        inside_init = patch_init_nonconst(init_loc, inside_init);
++        if (inside_init == NULL_TREE) {
++	      error_init (init_loc, "initializer element is not constant 8177");
++	      inside_init = error_mark_node;
++        }
++      }
++      else {
++	    error_init (init_loc, "initializer element is not constant 8183");
++	    inside_init = error_mark_node;
++      }
+ 	}
+       else if (require_constant && !maybe_const)
+ 	pedwarn_init (init_loc, OPT_Wpedantic,
+@@ -8210,8 +8220,17 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
+ 	;
+       else if (require_constant && !TREE_CONSTANT (inside_init))
+ 	{
+-	  error_init (init_loc, "initializer element is not constant");
+-	  inside_init = error_mark_node;
++	  if (flag_portcosmo) {
++        inside_init = patch_init_nonconst(init_loc, inside_init);
++        if (inside_init == NULL_TREE) {
++	      error_init (init_loc, "initializer element is not constant 8226");
++	      inside_init = error_mark_node;
++        }
++      }
++      else {
++	    error_init (init_loc, "initializer element is not constant 8183");
++	    inside_init = error_mark_node;
++      }
+ 	}
+       else if (require_constant
+ 	       && !initializer_constant_valid_p (inside_init,
+@@ -9740,7 +9759,7 @@ output_init_element (location_t loc, tree value, tree origtype,
+ 	 the brace enclosed list they contain).  */
+       if (flag_isoc99)
+ 	pedwarn_init (loc, OPT_Wpedantic, "initializer element is not "
+-		      "constant");
++		      "constant 9754");
+       tree decl = COMPOUND_LITERAL_EXPR_DECL (value);
+       value = DECL_INITIAL (decl);
+     }
+@@ -9787,9 +9806,9 @@ output_init_element (location_t loc, tree value, tree origtype,
+   /* Proceed to check the constness of the original initializer.  */
+   if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
+     {
+-      if (require_constant_value)
++      if (require_constant_value && !flag_portcosmo)
+ 	{
+-	  error_init (loc, "initializer element is not constant");
++	  error_init (loc, "initializer element is not constant 9803");
+ 	  value = error_mark_node;
+ 	}
+       else if (require_constant_elements)
+diff --git a/gcc/c/portcosmo_bcref.cc b/gcc/c/portcosmo_bcref.cc
+new file mode 100644
+index 000000000..2c6a58296
+--- /dev/null
++++ b/gcc/c/portcosmo_bcref.cc
+@@ -0,0 +1,30 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "c-family/initstruct.h"
++
++/* initstruct/common.cc */
++
++tree access_at(tree obj, tree ind) {
++  if (TREE_CODE(TREE_TYPE(obj)) == ARRAY_TYPE) {
++    return build_array_ref(input_location, obj, ind);
++  }
++  return build_component_ref(input_location, obj,
++                             get_identifier(IDENTIFIER_NAME(ind)),
++                             DECL_SOURCE_LOCATION(ind));
++}
+diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
+index 155be74ef..2fe9484ff 100644
+--- a/gcc/cp/Make-lang.in
++++ b/gcc/cp/Make-lang.in
+@@ -84,6 +84,10 @@ g++-cross$(exeext): xg++$(exeext)
+ CXX_C_OBJS = attribs.o incpath.o \
+ 	$(C_COMMON_OBJS) $(CXX_TARGET_OBJS)
+ 
++# initstruct has some issues building with cc1plus,
++# so we provide nothing for now
++PORTCOSMO_CXX_OBJS = cp/portcosmo_bcref_cp.o
++
+ # Language-specific object files for C++ and Objective C++.
+ CXX_AND_OBJCXX_OBJS = \
+ 	cp/call.o cp/class.o cp/constexpr.o cp/constraint.o \
+@@ -101,7 +105,7 @@ CXX_AND_OBJCXX_OBJS = \
+ 	cp/rtti.o \
+ 	cp/search.o cp/semantics.o \
+ 	cp/tree.o cp/typeck.o cp/typeck2.o \
+-	cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
++	cp/vtable-class-hierarchy.o $(CXX_C_OBJS) $(PORTCOSMO_CXX_OBJS)
+ 
+ ifeq ($(if $(wildcard ../stage_current),$(shell cat \
+   ../stage_current)),stageautofeedback)
+diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
+index 5e101ffb8..1f68dddbf 100644
+--- a/gcc/cp/decl.c
++++ b/gcc/cp/decl.c
+@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
+ #include "context.h"  /* For 'g'.  */
+ #include "omp-general.h"
+ #include "omp-offload.h"  /* For offload_vars.  */
++#include "c-family/portcosmo.h"
+ 
+ /* Possible cases of bad specifiers type used by bad_specifiers. */
+ enum bad_spec_place {
+@@ -8246,6 +8247,9 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
+       && !DECL_HARD_REGISTER (decl))
+     targetm.lower_local_decl_alignment (decl);
+ 
++  if (flag_portcosmo) {
++      portcosmo_finish_decl(decl);
++  }
+   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+ }
+ 
+@@ -17459,8 +17463,13 @@ finish_function (bool inline_p)
+   maybe_save_constexpr_fundef (fndecl);
+ 
+   /* Invoke the pre-genericize plugin before we start munging things.  */
+-  if (!processing_template_decl)
++  if (!processing_template_decl) {
++      if (flag_portcosmo)
++     {
++        portcosmo_pre_genericize(fndecl); 
++     }
+     invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);
++  }
+ 
+   /* Perform delayed folding before NRV transformation.  */
+   if (!processing_template_decl
+diff --git a/gcc/cp/portcosmo_bcref_cp.cc b/gcc/cp/portcosmo_bcref_cp.cc
+new file mode 100644
+index 000000000..bf01d9aeb
+--- /dev/null
++++ b/gcc/cp/portcosmo_bcref_cp.cc
+@@ -0,0 +1,42 @@
++/*- mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
++│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8                              :vi│
++╞══════════════════════════════════════════════════════════════════════════════╡
++│ Copyright © 2022, Gautham Venkatasubramanian                                 │
++│                                                                              │
++│ Permission to use, copy, modify, and/or distribute this software for         │
++│ any purpose with or without fee is hereby granted, provided that the         │
++│ above copyright notice and this permission notice appear in all copies.      │
++│                                                                              │
++│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL                │
++│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED                │
++│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE             │
++│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL         │
++│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR        │
++│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER               │
++│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR             │
++│ PERFORMANCE OF THIS SOFTWARE.                                                │
++╚─────────────────────────────────────────────────────────────────────────────*/
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "target.h"
++#include "c-family/c-target.h"
++#include "cp-tree.h"
++#include "tree.h"
++#include "stringpool.h"
++
++#define IDENTIFIER_NAME(z)        IDENTIFIER_POINTER(DECL_NAME((z)))
++
++/* initstruct/common.cc */
++
++tree access_at(tree obj, tree ind) {
++  return cp_build_addr_expr(ind, 0);
++  /*
++  if (TREE_CODE(TREE_TYPE(obj)) == ARRAY_TYPE) {
++    return build_array_ref(input_location, obj, ind);
++  }
++  return build_component_ref(input_location, obj,
++                             get_identifier(IDENTIFIER_NAME(ind)),
++                             DECL_SOURCE_LOCATION(ind));
++  */
++}