[llvm-bugs] [Bug 49157] 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

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Feb 12 02:30:28 PST 2021


https://bugs.llvm.org/show_bug.cgi?id=49157

            Bug ID: 49157
           Summary: Stackoverflow on printing code of struct with member
                    function pointer which takes pointer to the struct as
                    parameter and returns pointer to undeclared struct
           Product: clang
           Version: 10.0
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: Tooling
          Assignee: unassignedclangbugs at nondot.org
          Reporter: vad.e.volodin at gmail.com
                CC: llvm-bugs at lists.llvm.org

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

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20210212/394be817/attachment.html>


More information about the llvm-bugs mailing list