Skip to content

Exception parsing Constructor with conditional initializers #171

Description

@bbczeuz

Minimum crashing example

struct MyObject
{
MyObject();
private:
int testing;
void *output_file_handle_;
}; MyObject::MyObject()
: testing(0),
#if 1 output_file_handle_(nullptr)
#endif
{
}

Tested with:

user@host:~$ cppclean main.cpp Traceback (most recent call last):
File "/home/user/.local/bin/cppclean", line 166, in <module>
sys.exit(main())
^^^^^^
File "/home/user/.local/bin/cppclean", line 139, in main
entire_ast = list([_f for _f in builder.generate() if _f])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
result = self._generate_one(token)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
return self._get_method(temp_tokens, 0, None, False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
member = member[0]
~~~~~~^^^
IndexError: list index out of range

Exception is thrown here:

 # Handle ctor initializers.
# Supports C++11 method of direct initialization with braces.
initializers = {}
if token.name == ':':
while token.name != ';' and token.name != '{':
# skip preprocesors macros
1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
1095 token = self._get_next_token()
1096 continue
1097 member, token = self.get_name()
1098 member = member[0]
if token.name == '(' or token.name == '{':
end = '}' if token.name == '{' else ')'
initializers[member] = [
x for x in list(self._get_matching_char(token.name,
end))
if x.name != ',' and x.name != end]
token = self._get_next_token()

On line 1097: member is empty; token is Token('#if 1', 133, 138)
It seems as the check on line 1094 fails.

Workaround

Adapt code so that all initializers are within the same preprocessor condition:

MyObject::MyObject()
#if SOME_CONDITION
: testing(0), output_file_handle_(nullptr)
#endif
{
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
     blocks
    (function() {
    function addCopyButtons() {
    document.querySelectorAll('pre code').forEach(function(codeBlock) {
    if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
    codeBlock.parentElement.setAttribute('data-copy-added', 'true');
    var btn = document.createElement('button');
    btn.textContent = 'Copy';
    btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
    btn.onmouseover = function() { this.style.opacity = '1'; };
    btn.onmouseout = function() { this.style.opacity = '0.7'; };
    btn.onclick = function() {
    navigator.clipboard.writeText(codeBlock.textContent).then(function() {
    btn.textContent = 'Copied!';
    setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
    });
    };
    codeBlock.parentElement.style.position = 'relative';
    codeBlock.parentElement.appendChild(btn);
    });
    }
    addCopyButtons();
    // Re-run on dynamic content
    var observer = new MutationObserver(addCopyButtons);
    observer.observe(document.body, { childList: true, subtree: true });
    })();
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
    Skip to content

    Exception parsing Constructor with conditional initializers #171

    Description

    @bbczeuz

    Minimum crashing example

    struct MyObject
    {
    MyObject();
    private:
    int testing;
    void *output_file_handle_;
    }; MyObject::MyObject()
    : testing(0),
    #if 1 output_file_handle_(nullptr)
    #endif
    {
    }
    

    Tested with:

    user@host:~$ cppclean main.cpp Traceback (most recent call last):
    File "/home/user/.local/bin/cppclean", line 166, in <module>
    sys.exit(main())
    ^^^^^^
    File "/home/user/.local/bin/cppclean", line 139, in main
    entire_ast = list([_f for _f in builder.generate() if _f])
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
    result = self._generate_one(token)
    ^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
    return self._get_method(temp_tokens, 0, None, False)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
    member = member[0]
    ~~~~~~^^^
    IndexError: list index out of range
    

    Exception is thrown here:

     # Handle ctor initializers.
    # Supports C++11 method of direct initialization with braces.
    initializers = {}
    if token.name == ':':
    while token.name != ';' and token.name != '{':
    # skip preprocesors macros
    1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
    1095 token = self._get_next_token()
    1096 continue
    1097 member, token = self.get_name()
    1098 member = member[0]
    if token.name == '(' or token.name == '{':
    end = '}' if token.name == '{' else ')'
    initializers[member] = [
    x for x in list(self._get_matching_char(token.name,
    end))
    if x.name != ',' and x.name != end]
    token = self._get_next_token()
    

    On line 1097: member is empty; token is Token('#if 1', 133, 138)
    It seems as the check on line 1094 fails.

    Workaround

    Adapt code so that all initializers are within the same preprocessor condition:

    MyObject::MyObject()
    #if SOME_CONDITION
    : testing(0), output_file_handle_(nullptr)
    #endif
    {
    }
    

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      No labels
      No labels

      Projects

      No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
      Skip to content

      Exception parsing Constructor with conditional initializers #171

      Description

      @bbczeuz

      Minimum crashing example

      struct MyObject
      {
      MyObject();
      private:
      int testing;
      void *output_file_handle_;
      }; MyObject::MyObject()
      : testing(0),
      #if 1 output_file_handle_(nullptr)
      #endif
      {
      }
      

      Tested with:

      user@host:~$ cppclean main.cpp Traceback (most recent call last):
      File "/home/user/.local/bin/cppclean", line 166, in <module>
      sys.exit(main())
      ^^^^^^
      File "/home/user/.local/bin/cppclean", line 139, in main
      entire_ast = list([_f for _f in builder.generate() if _f])
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
      result = self._generate_one(token)
      ^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
      return self._get_method(temp_tokens, 0, None, False)
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
      member = member[0]
      ~~~~~~^^^
      IndexError: list index out of range
      

      Exception is thrown here:

       # Handle ctor initializers.
      # Supports C++11 method of direct initialization with braces.
      initializers = {}
      if token.name == ':':
      while token.name != ';' and token.name != '{':
      # skip preprocesors macros
      1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
      1095 token = self._get_next_token()
      1096 continue
      1097 member, token = self.get_name()
      1098 member = member[0]
      if token.name == '(' or token.name == '{':
      end = '}' if token.name == '{' else ')'
      initializers[member] = [
      x for x in list(self._get_matching_char(token.name,
      end))
      if x.name != ',' and x.name != end]
      token = self._get_next_token()
      

      On line 1097: member is empty; token is Token('#if 1', 133, 138)
      It seems as the check on line 1094 fails.

      Workaround

      Adapt code so that all initializers are within the same preprocessor condition:

      MyObject::MyObject()
      #if SOME_CONDITION
      : testing(0), output_file_handle_(nullptr)
      #endif
      {
      }
      

      Metadata

      Metadata

      Assignees

      No one assigned

        Labels

        No labels
        No labels

        Projects

        No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
        Skip to content

        Exception parsing Constructor with conditional initializers #171

        Description

        @bbczeuz

        Minimum crashing example

        struct MyObject
        {
        MyObject();
        private:
        int testing;
        void *output_file_handle_;
        }; MyObject::MyObject()
        : testing(0),
        #if 1 output_file_handle_(nullptr)
        #endif
        {
        }
        

        Tested with:

        user@host:~$ cppclean main.cpp Traceback (most recent call last):
        File "/home/user/.local/bin/cppclean", line 166, in <module>
        sys.exit(main())
        ^^^^^^
        File "/home/user/.local/bin/cppclean", line 139, in main
        entire_ast = list([_f for _f in builder.generate() if _f])
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
        result = self._generate_one(token)
        ^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
        return self._get_method(temp_tokens, 0, None, False)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
        member = member[0]
        ~~~~~~^^^
        IndexError: list index out of range
        

        Exception is thrown here:

         # Handle ctor initializers.
        # Supports C++11 method of direct initialization with braces.
        initializers = {}
        if token.name == ':':
        while token.name != ';' and token.name != '{':
        # skip preprocesors macros
        1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
        1095 token = self._get_next_token()
        1096 continue
        1097 member, token = self.get_name()
        1098 member = member[0]
        if token.name == '(' or token.name == '{':
        end = '}' if token.name == '{' else ')'
        initializers[member] = [
        x for x in list(self._get_matching_char(token.name,
        end))
        if x.name != ',' and x.name != end]
        token = self._get_next_token()
        

        On line 1097: member is empty; token is Token('#if 1', 133, 138)
        It seems as the check on line 1094 fails.

        Workaround

        Adapt code so that all initializers are within the same preprocessor condition:

        MyObject::MyObject()
        #if SOME_CONDITION
        : testing(0), output_file_handle_(nullptr)
        #endif
        {
        }
        

        Metadata

        Metadata

        Assignees

        No one assigned

          Labels

          No labels
          No labels

          Projects

          No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
          Skip to content

          Exception parsing Constructor with conditional initializers #171

          Description

          @bbczeuz

          Minimum crashing example

          struct MyObject
          {
          MyObject();
          private:
          int testing;
          void *output_file_handle_;
          }; MyObject::MyObject()
          : testing(0),
          #if 1 output_file_handle_(nullptr)
          #endif
          {
          }
          

          Tested with:

          user@host:~$ cppclean main.cpp Traceback (most recent call last):
          File "/home/user/.local/bin/cppclean", line 166, in <module>
          sys.exit(main())
          ^^^^^^
          File "/home/user/.local/bin/cppclean", line 139, in main
          entire_ast = list([_f for _f in builder.generate() if _f])
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
          result = self._generate_one(token)
          ^^^^^^^^^^^^^^^^^^^^^^^^^
          File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
          return self._get_method(temp_tokens, 0, None, False)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
          member = member[0]
          ~~~~~~^^^
          IndexError: list index out of range
          

          Exception is thrown here:

           # Handle ctor initializers.
          # Supports C++11 method of direct initialization with braces.
          initializers = {}
          if token.name == ':':
          while token.name != ';' and token.name != '{':
          # skip preprocesors macros
          1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
          1095 token = self._get_next_token()
          1096 continue
          1097 member, token = self.get_name()
          1098 member = member[0]
          if token.name == '(' or token.name == '{':
          end = '}' if token.name == '{' else ')'
          initializers[member] = [
          x for x in list(self._get_matching_char(token.name,
          end))
          if x.name != ',' and x.name != end]
          token = self._get_next_token()
          

          On line 1097: member is empty; token is Token('#if 1', 133, 138)
          It seems as the check on line 1094 fails.

          Workaround

          Adapt code so that all initializers are within the same preprocessor condition:

          MyObject::MyObject()
          #if SOME_CONDITION
          : testing(0), output_file_handle_(nullptr)
          #endif
          {
          }
          

          Metadata

          Metadata

          Assignees

          No one assigned

            Labels

            No labels
            No labels

            Projects

            No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
            Skip to content

            Exception parsing Constructor with conditional initializers #171

            Description

            @bbczeuz

            Minimum crashing example

            struct MyObject
            {
            MyObject();
            private:
            int testing;
            void *output_file_handle_;
            }; MyObject::MyObject()
            : testing(0),
            #if 1 output_file_handle_(nullptr)
            #endif
            {
            }
            

            Tested with:

            user@host:~$ cppclean main.cpp Traceback (most recent call last):
            File "/home/user/.local/bin/cppclean", line 166, in <module>
            sys.exit(main())
            ^^^^^^
            File "/home/user/.local/bin/cppclean", line 139, in main
            entire_ast = list([_f for _f in builder.generate() if _f])
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
            result = self._generate_one(token)
            ^^^^^^^^^^^^^^^^^^^^^^^^^
            File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
            return self._get_method(temp_tokens, 0, None, False)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
            member = member[0]
            ~~~~~~^^^
            IndexError: list index out of range
            

            Exception is thrown here:

             # Handle ctor initializers.
            # Supports C++11 method of direct initialization with braces.
            initializers = {}
            if token.name == ':':
            while token.name != ';' and token.name != '{':
            # skip preprocesors macros
            1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
            1095 token = self._get_next_token()
            1096 continue
            1097 member, token = self.get_name()
            1098 member = member[0]
            if token.name == '(' or token.name == '{':
            end = '}' if token.name == '{' else ')'
            initializers[member] = [
            x for x in list(self._get_matching_char(token.name,
            end))
            if x.name != ',' and x.name != end]
            token = self._get_next_token()
            

            On line 1097: member is empty; token is Token('#if 1', 133, 138)
            It seems as the check on line 1094 fails.

            Workaround

            Adapt code so that all initializers are within the same preprocessor condition:

            MyObject::MyObject()
            #if SOME_CONDITION
            : testing(0), output_file_handle_(nullptr)
            #endif
            {
            }
            

            Metadata

            Metadata

            Assignees

            No one assigned

              Labels

              No labels
              No labels

              Projects

              No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Exception parsing Constructor with conditional initializers · Issue #171 · myint/cppclean · GitHub
              Skip to content

              Exception parsing Constructor with conditional initializers #171

              Description

              @bbczeuz

              Minimum crashing example

              struct MyObject
              {
              MyObject();
              private:
              int testing;
              void *output_file_handle_;
              }; MyObject::MyObject()
              : testing(0),
              #if 1 output_file_handle_(nullptr)
              #endif
              {
              }
              

              Tested with:

              user@host:~$ cppclean main.cpp Traceback (most recent call last):
              File "/home/user/.local/bin/cppclean", line 166, in <module>
              sys.exit(main())
              ^^^^^^
              File "/home/user/.local/bin/cppclean", line 139, in main
              entire_ast = list([_f for _f in builder.generate() if _f])
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 675, in generate
              result = self._generate_one(token)
              ^^^^^^^^^^^^^^^^^^^^^^^^^
              File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 753, in _generate_one
              return self._get_method(temp_tokens, 0, None, False)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
              File "/home/user/.local/share/pipx/venvs/cppclean/lib/python3.12/site-packages/cpp/ast.py", line 1098, in _get_method
              member = member[0]
              ~~~~~~^^^
              IndexError: list index out of range
              

              Exception is thrown here:

               # Handle ctor initializers.
              # Supports C++11 method of direct initialization with braces.
              initializers = {}
              if token.name == ':':
              while token.name != ';' and token.name != '{':
              # skip preprocesors macros
              1094 if token.name.startswith(('#if', '#elif', '#else', '#endif')):
              1095 token = self._get_next_token()
              1096 continue
              1097 member, token = self.get_name()
              1098 member = member[0]
              if token.name == '(' or token.name == '{':
              end = '}' if token.name == '{' else ')'
              initializers[member] = [
              x for x in list(self._get_matching_char(token.name,
              end))
              if x.name != ',' and x.name != end]
              token = self._get_next_token()
              

              On line 1097: member is empty; token is Token('#if 1', 133, 138)
              It seems as the check on line 1094 fails.

              Workaround

              Adapt code so that all initializers are within the same preprocessor condition:

              MyObject::MyObject()
              #if SOME_CONDITION
              : testing(0), output_file_handle_(nullptr)
              #endif
              {
              }
              

              Metadata

              Metadata

              Assignees

              No one assigned

                Labels

                No labels
                No labels

                Projects

                No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions