<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Stackoverflow on printing code of struct with member function pointer which takes pointer to the struct as parameter and returns pointer to undeclared struct"
   href="https://bugs.llvm.org/show_bug.cgi?id=49157">49157</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Stackoverflow on printing code of struct with member function pointer which takes pointer to the struct as parameter and returns pointer to undeclared struct
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>10.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Tooling
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>vad.e.volodin@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When calling a print method on struct decl there is a stackoverflow.


Code to analyze (file.c) (inspired by git sources):

struct fetch_negotiator {
        struct object_id * (*next)(struct fetch_negotiator *x);
};

int main() {}


copmile_commands.json:
[
    {
        "arguments": [
            "clang",
            "-c",
            "-o",
            "file.o",
            "file.c"
        ],
        "directory": "/home/myuser/work/tmp",
        "file": "file.c"
    }
]



Tooling code:

#include <clang/ASTMatchers/ASTMatchFinder.h>
#include <clang/Frontend/FrontendActions.h>
#include <clang/Tooling/CommonOptionsParser.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Tooling/Tooling.h>

#include <string>
#include <vector>
#include <memory>
#include <iostream>

using namespace clang::ast_matchers;
using namespace clang;
using namespace clang::tooling;
using namespace std;

string prefix = "/home/myuser/";
string ccPath = prefix + "work/tmp/";
vector<string> files = {
        prefix + "work/tmp/file.c"
};

class Fetcher : public MatchFinder::MatchCallback {
public:
    void run(const MatchFinder::MatchResult &Result) override {
        if (const auto *decl = Result.Nodes.getNodeAs<RecordDecl>("struct")) {
            std::string result;
            llvm::raw_string_ostream resultStream{ result };
            decl->print(resultStream);
        }
    }
};

int main() {
    unique_ptr<clang::tooling::ClangTool> clangTool;
    unique_ptr<Fetcher> fetcherInstance;
    MatchFinder finder;

    const DeclarationMatcher structMatcher =
            recordDecl(isStruct(), isDefinition())
                    .bind("struct");

    string errMsg;
    shared_ptr<clang::tooling::CompilationDatabase> cDb =
clang::tooling::CompilationDatabase::autoDetectFromDirectory(ccPath, errMsg);
    std::cout << errMsg; // No output
    clangTool = std::make_unique<ClangTool>(*cDb, files);
    fetcherInstance = std::make_unique<Fetcher>();
    finder.addMatcher(structMatcher, fetcherInstance.get());

    clangTool->run(newFrontendActionFactory(&finder).get());
}


CMakeLists.txt for tooling code:

cmake_minimum_required(VERSION 3.16)
project(untitled)

set(CMAKE_CXX_STANDARD 17)

find_package(Clang REQUIRED)
include_directories(${CLANG_INCLUDE_DIRS})
add_definitions(${CLANG_DEFINITIONS})

add_executable(clang_error main.cpp)
target_link_libraries(clang_error PUBLIC clangTooling clangBasic
clangASTMatchers)



Part of stack trace:

clang::Decl::print(llvm::raw_ostream&, clang::PrintingPolicy const&, unsigned
int, bool) const 0x00000000012234ab
(anonymous namespace)::TypePrinter::printTag(clang::TagDecl*,
llvm::raw_ostream&) 0x00000000013e1395
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013db400
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013ddcba
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013dd01f
(anonymous namespace)::TypePrinter::print(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&, llvm::StringRef) 0x00000000013da372
(anonymous namespace)::TypePrinter::printAfter(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013e0199
(anonymous namespace)::TypePrinter::printAfter(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013dfc80
(anonymous namespace)::TypePrinter::print(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&, llvm::StringRef) 0x00000000013da3e7
clang::QualType::print(clang::Type const*, clang::Qualifiers,
llvm::raw_ostream&, clang::PrintingPolicy const&, llvm::Twine const&, unsigned
int) 0x00000000013da2cc
(anonymous namespace)::DeclPrinter::VisitFieldDecl(clang::FieldDecl*)
0x000000000122a400
clang::Decl::printGroup(clang::Decl**, unsigned int, llvm::raw_ostream&,
clang::PrintingPolicy const&, unsigned int) 0x0000000001228732
(anonymous namespace)::DeclPrinter::VisitDeclContext(clang::DeclContext*, bool)
0x00000000012293f1
clang::declvisitor::Base<std::add_pointer, (anonymous namespace)::DeclPrinter,
void>::Visit(clang::Decl*) 0x0000000001225f63
clang::Decl::print(llvm::raw_ostream&, clang::PrintingPolicy const&, unsigned
int, bool) const 0x00000000012234ab
(anonymous namespace)::TypePrinter::printTag(clang::TagDecl*,
llvm::raw_ostream&) 0x00000000013e1395
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013db400
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013ddcba
(anonymous namespace)::TypePrinter::printBefore(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013dd01f
(anonymous namespace)::TypePrinter::print(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&, llvm::StringRef) 0x00000000013da372
(anonymous namespace)::TypePrinter::printAfter(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013e0199
(anonymous namespace)::TypePrinter::printAfter(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&) 0x00000000013dfc80
(anonymous namespace)::TypePrinter::print(clang::Type const*,
clang::Qualifiers, llvm::raw_ostream&, llvm::StringRef) 0x00000000013da3e7
clang::QualType::print(clang::Type const*, clang::Qualifiers,
llvm::raw_ostream&, clang::PrintingPolicy const&, llvm::Twine const&, unsigned
int) 0x00000000013da2cc
(anonymous namespace)::DeclPrinter::VisitFieldDecl(clang::FieldDecl*)
0x000000000122a400
clang::Decl::printGroup(clang::Decl**, unsigned int, llvm::raw_ostream&,
clang::PrintingPolicy const&, unsigned int) 0x0000000001228732
(anonymous namespace)::DeclPrinter::VisitDeclContext(clang::DeclContext*, bool)
0x00000000012293f1
clang::declvisitor::Base<std::add_pointer, (anonymous namespace)::DeclPrinter,
void>::Visit(clang::Decl*) 0x0000000001225f63
clang::Decl::print(llvm::raw_ostream&, unsigned int, bool) const
0x0000000001223455
Fetcher::run main.cpp:29


First characters of result variable:
"struct fetch_negotiator {\n   struct object_id *(*next)(struct
fetch_negotiator {\n    struct object_id *(*next)(struct fetch_negotiator {\n  
   struct object_id *(*next)(struct fetch_negotiator {\n       struct object_id
*(*next)(struct fetch_negotiator {\n        struct object_id *(*next)(struct
fetch_negotiator {\n         struct object_id *(*next)(struct fetch_negotiator
{\n          struct object_id *(*next)(struct fetch_negotiator {\n    ......


Clang version 10.0.0</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>