mirror of
https://github.com/intel/llvm.git
synced 2026-02-08 08:57:43 +08:00
Don't segfault in EmitCXXGlobalInitFunc when main file is a membuf
Summary: When the main file is created from a membuffer, there is no file entry that can be retrieved. This uses "__GLOBAL_I_a" in that case which is what was always used before r208128. Reviewers: majnemer, thakis Reviewed By: thakis Subscribers: yaron.keren, rsmith, cfe-commits Differential Revision: http://reviews.llvm.org/D5043 llvm-svn: 216495
This commit is contained in:
@@ -409,19 +409,25 @@ CodeGenModule::EmitCXXGlobalInitFunc() {
|
||||
AddGlobalCtor(Fn, Priority);
|
||||
}
|
||||
}
|
||||
|
||||
// Include the filename in the symbol name. Including "sub_" matches gcc and
|
||||
// makes sure these symbols appear lexicographically behind the symbols with
|
||||
// priority emitted above.
|
||||
|
||||
SmallString<128> FileName;
|
||||
SourceManager &SM = Context.getSourceManager();
|
||||
SmallString<128> FileName(llvm::sys::path::filename(
|
||||
SM.getFileEntryForID(SM.getMainFileID())->getName()));
|
||||
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
|
||||
// Include the filename in the symbol name. Including "sub_" matches gcc and
|
||||
// makes sure these symbols appear lexicographically behind the symbols with
|
||||
// priority emitted above.
|
||||
FileName = llvm::sys::path::filename(MainFile->getName());
|
||||
} else {
|
||||
FileName = SmallString<128>("<null>");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < FileName.size(); ++i) {
|
||||
// Replace everything that's not [a-zA-Z0-9._] with a _. This set happens
|
||||
// to be the set of C preprocessing numbers.
|
||||
if (!isPreprocessingNumberBody(FileName[i]))
|
||||
FileName[i] = '_';
|
||||
}
|
||||
|
||||
llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
|
||||
*this, FTy, llvm::Twine("_GLOBAL__sub_I_", FileName));
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ add_subdirectory(AST)
|
||||
add_subdirectory(Tooling)
|
||||
add_subdirectory(Format)
|
||||
add_subdirectory(Sema)
|
||||
add_subdirectory(CodeGen)
|
||||
# FIXME: Why are the libclang unit tests disabled on Windows?
|
||||
if(NOT WIN32)
|
||||
add_subdirectory(libclang)
|
||||
|
||||
78
clang/unittests/CodeGen/BufferSourceTest.cpp
Normal file
78
clang/unittests/CodeGen/BufferSourceTest.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
//===- unittests/CodeGen/BufferSourceTest.cpp - MemoryBuffer source tests -===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/RecursiveASTVisitor.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "clang/CodeGen/ModuleBuilder.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
#include "clang/Parse/ParseAST.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace clang;
|
||||
|
||||
namespace {
|
||||
|
||||
// Emitting constructors for global objects involves looking
|
||||
// at the source file name. This makes sure that we don't crash
|
||||
// if the source file is a memory buffer.
|
||||
const char TestProgram[] =
|
||||
"class EmitCXXGlobalInitFunc "
|
||||
"{ "
|
||||
"public: "
|
||||
" EmitCXXGlobalInitFunc() {} "
|
||||
"}; "
|
||||
"EmitCXXGlobalInitFunc test; ";
|
||||
|
||||
TEST(BufferSourceTest, EmitCXXGlobalInitFunc) {
|
||||
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.getCodeGenOpts(),
|
||||
compiler.getTargetOpts(),
|
||||
llvm::getGlobalContext())));
|
||||
|
||||
compiler.createSema(clang::TU_Prefix,NULL);
|
||||
|
||||
clang::SourceManager &sm = compiler.getSourceManager();
|
||||
sm.setMainFileID(sm.createFileID(
|
||||
llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
|
||||
|
||||
clang::ParseAST(compiler.getSema(), false, false);
|
||||
}
|
||||
|
||||
}
|
||||
17
clang/unittests/CodeGen/CMakeLists.txt
Normal file
17
clang/unittests/CodeGen/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
Support
|
||||
)
|
||||
|
||||
add_clang_unittest(CodeGenTests
|
||||
BufferSourceTest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(CodeGenTests
|
||||
clangAST
|
||||
clangBasic
|
||||
clangFrontend
|
||||
clangParse
|
||||
clangSema
|
||||
clangTooling
|
||||
clangCodeGen
|
||||
)
|
||||
20
clang/unittests/CodeGen/Makefile
Normal file
20
clang/unittests/CodeGen/Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
##===- unittests/CodeGen/Makefile --------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
CLANG_LEVEL = ../..
|
||||
TESTNAME = CodeGen
|
||||
include $(CLANG_LEVEL)/../../Makefile.config
|
||||
LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
|
||||
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
|
||||
clangRewrite.a clangRewriteFrontend.a \
|
||||
clangParse.a clangSema.a clangAnalysis.a \
|
||||
clangEdit.a clangAST.a clangASTMatchers.a clangLex.a clangBasic.a \
|
||||
clangCodeGen.a
|
||||
|
||||
include $(CLANG_LEVEL)/unittests/Makefile
|
||||
@@ -14,7 +14,8 @@ ifndef CLANG_LEVEL
|
||||
|
||||
IS_UNITTEST_LEVEL := 1
|
||||
CLANG_LEVEL := ..
|
||||
PARALLEL_DIRS = Basic Lex Driver libclang Format ASTMatchers AST Tooling Sema
|
||||
PARALLEL_DIRS = CodeGen Basic Lex Driver libclang Format ASTMatchers AST Tooling \
|
||||
Sema
|
||||
|
||||
include $(CLANG_LEVEL)/../..//Makefile.config
|
||||
|
||||
|
||||
Reference in New Issue
Block a user