[cfe-dev] Segfault calling clang::parseAST on file with syntax error.

Zeke Medley via cfe-dev cfe-dev at lists.llvm.org
Mon Sep 23 12:37:24 PDT 2019


Hi everyone,

I'm working on a program to compile C++ code into llvm::Modules at the
moment and am having trouble handling files with errors. I'm following
along with the incremental processing unit test
<https://github.com/llvm-mirror/clang/blob/324f918438715b4a0d024af5930628c1674f4fcd/unittests/CodeGen/IncrementalProcessingTest.cpp>.
The method in there works fine, unless the file its asked to parse contains
an error in which case it segfaults. The problem seems to extend to
clang::parseAST as well and I can reproduce it pretty easily. I attached a
program to do that at the end of the email.

According to gdb, the segfault is happening in
clang::DiagnosticRenderer::emitDiagnostic, but the stack trace other than
that looks pretty good. The clang::Sema calls
clang::Sema::DiagnoseUnknownTypeName which seems like the right idea.

Does anyone have any ideas why this might be happening or how to fix this?
I'm also open to other ideas on how best to approach compiling C++ code
into llvm::Modules from inside C++ land. Ultimately, I'd like to be able to
JIT the resulting code with LLVM's JIT.

Thanks,
Zeke

Program to reproduce

#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"

using namespace llvm;
using namespace clang;

const char TestProgram[] =
    "class EmitCXXGlobalInitFunc    "
    "{                              "
    "public:                        "
    "  *err* EmitCXXGlobalInitFunc() {}  " // I've added an error here.
    "};                             "
    "EmitCXXGlobalInitFunc test;    ";


int main()
    {
    LLVMContext Context;
    CompilerInstance compiler;

    compiler.createDiagnostics();
    compiler.getLangOpts().CPlusPlus = 1;
    compiler.getLangOpts().CPlusPlus11 = 1;

    compiler.getTargetOpts().Triple = llvm::Triple::normalize(
    llvm::sys::getProcessTriple());
    compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
   compiler.getDiagnostics(),
   std::make_shared<clang::TargetOptions>(
   compiler.getTargetOpts())));

    compiler.createFileManager();
    compiler.createSourceManager(compiler.getFileManager());
    compiler.createPreprocessor(clang::TU_Prefix);

    compiler.createASTContext();

    compiler.setASTConsumer(std::unique_ptr<ASTConsumer>(
    CreateLLVMCodeGen(
      compiler.getDiagnostics(),
      "EmitCXXGlobalInitFuncTest",
      compiler.getHeaderSearchOpts(),
      compiler.getPreprocessorOpts(),
      compiler.getCodeGenOpts(),
      Context)));

    compiler.createSema(clang::TU_Prefix, nullptr);

    clang::SourceManager &sm = compiler.getSourceManager();
    sm.setMainFileID(sm.createFileID(
    llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));

    clang::ParseAST(compiler.getSema(), false, false);  // segfault here.
    }

Stack Trace:

#0  0x0000000000df3c2f in
clang::DiagnosticRenderer::emitDiagnostic(clang::FullSourceLoc,
clang::DiagnosticsEngine::Level, llvm::StringRef,
llvm::ArrayRef<clang::CharSourceRange>, llvm::ArrayRef<clang::FixItHint>,
llvm::PointerUnion<clang::Diagnostic const*, clang::StoredDiagnostic
const*>) ()
#1  0x0000000000dbe8d3 in
clang::TextDiagnosticPrinter::HandleDiagnostic(clang::DiagnosticsEngine::Level,
clang::Diagnostic const&) ()
#2  0x0000000001ab8066 in
clang::DiagnosticIDs::ProcessDiag(clang::DiagnosticsEngine&) const ()
#3  0x0000000001ab28a3 in
clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool) ()
#4  0x000000000117fa7a in clang::Sema::EmitCurrentDiagnostic(unsigned int)
()
#5  0x000000000123a528 in
clang::Sema::DiagnoseUnknownTypeName(clang::IdentifierInfo*&,
clang::SourceLocation, clang::Scope*, clang::CXXScopeSpec*,
clang::OpaquePtr<clang::QualType>&, bool) ()
#6  0x0000000000f32aad in clang::Parser::ParseImplicitInt(clang::DeclSpec&,
clang::CXXScopeSpec*, clang::Parser::ParsedTemplateInfo const&,
clang::AccessSpecifier, clang::Parser::DeclSpecContext,
clang::Parser::ParsedAttributesWithRange&) ()
#7  0x0000000000f2de92 in
clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&,
clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier,
clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) ()
#8  0x0000000000f4bb6c in
clang::Parser::ParseCXXClassMemberDeclaration(clang::AccessSpecifier,
clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo const&,
clang::ParsingDeclRAIIObject*) ()
#9  0x0000000000f4e3a5 in
clang::Parser::ParseCXXClassMemberDeclarationWithPragmas(clang::AccessSpecifier&,
clang::Parser::ParsedAttributesWithRange&, clang::TypeSpecifierType,
clang::Decl*) ()
#10 0x0000000000f49358 in
clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation,
clang::SourceLocation, clang::Parser::ParsedAttributesWithRange&, unsigned
int, clang::Decl*) ()
#11 0x0000000000f46e51 in
clang::Parser::ParseClassSpecifier(clang::tok::TokenKind,
clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo
const&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext,
clang::Parser::ParsedAttributesWithRange&) ()
#12 0x0000000000f2c05e in
clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&,
clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier,
clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) ()
#13 0x0000000000f1827a in
clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec&, clang::AccessSpecifier) ()
#14 0x0000000000f17f4c in
clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec*, clang::AccessSpecifier) ()
#15 0x0000000000f17016 in
clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&,
clang::ParsingDeclSpec*) ()
#16 0x0000000000f15482 in
clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&,
bool) ()
#17 0x0000000000f14ff6 in
clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&)
()
#18 0x0000000000f10ac7 in clang::ParseAST(clang::Sema&, bool, bool) ()
#19 0x00000000006b1dd6 in main () at parseASTtest.cpp:68
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190923/07c2aad9/attachment.html>


More information about the cfe-dev mailing list