new_contents: #! /usr/bin/env python
  
  # To use:
  #  1) Update the 'decls' list below with your fuzzing configuration.
  #  2) Run with the clang binary as the command-line argument.
  
  import random
  import subprocess
  import sys
  import os
  
  clang = sys.argv[1]
  none_opts = 0.3
  
  class Decl:
    def __init__(self, text, depends=[], provides=[], conflicts=[]):
      self.text = text
      self.depends = depends
      self.provides = provides
      self.conflicts = conflicts
  
    def valid(self, model):
      for i in self.depends:
        if i not in model.decls:
          return False
      for i in self.conflicts:
        if i in model.decls:
          return False
      return True
  
    def apply(self, model, name):
      for i in self.provides:
        model.decls[i] = True
      model.source += self.text % {'name': name}
  
  decls = [
    Decl('struct X { int n; };\n', provides=['X'], conflicts=['X']),
    Decl('static_assert(X{.n=1}.n == 1, "");\n', depends=['X']),
    Decl('X %(name)s;\n', depends=['X']),
  ]
  
  class FS:
    def __init__(self):
      self.fs = {}
      self.prevfs = {}
  
    def write(self, path, contents):
      self.fs[path] = contents
  
    def done(self):
      for f, s in self.fs.items():
        if self.prevfs.get(f) != s:
          f = file(f, 'w')
          f.write(s)
          f.close()
  
      for f in self.prevfs:
        if f not in self.fs:
          os.remove(f)
  
      self.prevfs, self.fs = self.fs, {}
  
  fs = FS()
  
  class CodeModel:
    def __init__(self):
      self.source = ''
      self.modules = {}
      self.decls = {}
      self.i = 0
  
    def make_name(self):
      self.i += 1
      return 'n' + str(self.i)
  
    def fails(self):
      fs.write('module.modulemap',
            ''.join('module %s { header "%s.h" export * }\n' % (m, m)
                    for m in self.modules.keys()))
  
      for m, (s, _) in self.modules.items():
        fs.write('%s.h' % m, s)
  
      fs.write('main.cc', self.source)
      fs.done()
  
      return subprocess.call([clang, '-std=c++11', '-c', '-fmodules', 'main.cc', '-o', '/dev/null']) != 0
  
  def generate():
    model = CodeModel()
    m = []
  
    try:
      for d in mutations(model):
        d(model)
        m.append(d)
      if not model.fails():
        return
    except KeyboardInterrupt:
      print
      return True
  
    sys.stdout.write('\nReducing:\n')
    sys.stdout.flush()
  
    try:
      while True:
        assert m, 'got a failure with no steps; broken clang binary?'
        i = random.choice(range(len(m)))
        x = m[0:i] + m[i+1:]
        m2 = CodeModel()
        for d in x:
          d(m2)
        if m2.fails():
          m = x
          model = m2
        else:
          sys.stdout.write('.')
          sys.stdout.flush()
    except KeyboardInterrupt:
      # FIXME: Clean out output directory first.
      model.fails()
      return model
  
  def choose(options):
    while True:
      i = int(random.uniform(0, len(options) + none_opts))
      if i >= len(options):
        break
      yield options[i]
  
  def mutations(model):
    options = [create_module, add_top_level_decl]
    for opt in choose(options):
      yield opt(model, options)
  
  def create_module(model, options):
    n = model.make_name()
    def go(model):
      model.modules[n] = (model.source, model.decls)
      (model.source, model.decls) = ('', {})
    options += [lambda model, options: add_import(model, options, n)]
    return go
  
  def add_top_level_decl(model, options):
    n = model.make_name()
    d = random.choice([decl for decl in decls if decl.valid(model)])
    def go(model):
      if not d.valid(model):
        return
      d.apply(model, n)
    return go
  
  def add_import(model, options, module_name):
    def go(model):
      if module_name in model.modules:
        model.source += '#include "%s.h"\n' % module_name
        model.decls.update(model.modules[module_name][1])
    return go
  
  sys.stdout.write('Finding bug: ')
  while True:
    if generate():
      break
    sys.stdout.write('.')
    sys.stdout.flush()
  
subject: Add simple, stupid, pattern-based fuzzer / reducer for modules bugs. I've already used this to find and reduce quite a few bugs, and it works pretty well if you can find the right patterns.