2009-12-10 08:16:00 +08:00
|
|
|
//===--- CGDeclCXX.cpp - Emit LLVM Code for C++ declarations --------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This contains code dealing with code generation of C++ declarations
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "CodeGenFunction.h"
|
2010-08-31 15:33:07 +08:00
|
|
|
#include "CGCXXABI.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "CGObjCRuntime.h"
|
2014-11-11 12:05:39 +08:00
|
|
|
#include "CGOpenMPRuntime.h"
|
2010-06-16 07:19:56 +08:00
|
|
|
#include "clang/Frontend/CodeGenOptions.h"
|
2012-11-07 06:44:45 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2013-01-02 19:45:17 +08:00
|
|
|
#include "llvm/IR/Intrinsics.h"
|
2014-05-07 04:32:45 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2010-05-16 09:24:12 +08:00
|
|
|
|
2009-12-10 08:16:00 +08:00
|
|
|
using namespace clang;
|
|
|
|
using namespace CodeGen;
|
|
|
|
|
2009-12-10 08:57:45 +08:00
|
|
|
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ConstantAddress DeclPtr) {
|
2009-12-10 08:57:45 +08:00
|
|
|
assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
|
|
|
|
assert(!D.getType()->isReferenceType() &&
|
|
|
|
"Should not call EmitDeclInit on a reference!");
|
|
|
|
|
2011-06-16 12:16:24 +08:00
|
|
|
QualType type = D.getType();
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
LValue lv = CGF.MakeAddrLValue(DeclPtr, type);
|
2011-06-16 12:16:24 +08:00
|
|
|
|
|
|
|
const Expr *Init = D.getInit();
|
2013-03-08 05:37:08 +08:00
|
|
|
switch (CGF.getEvaluationKind(type)) {
|
|
|
|
case TEK_Scalar: {
|
2011-01-14 04:00:54 +08:00
|
|
|
CodeGenModule &CGM = CGF.CGM;
|
2011-06-16 12:16:24 +08:00
|
|
|
if (lv.isObjCStrong())
|
2011-06-16 07:02:42 +08:00
|
|
|
CGM.getObjCRuntime().EmitObjCGlobalAssign(CGF, CGF.EmitScalarExpr(Init),
|
2013-04-13 10:43:54 +08:00
|
|
|
DeclPtr, D.getTLSKind());
|
2011-06-16 12:16:24 +08:00
|
|
|
else if (lv.isObjCWeak())
|
|
|
|
CGM.getObjCRuntime().EmitObjCWeakAssign(CGF, CGF.EmitScalarExpr(Init),
|
|
|
|
DeclPtr);
|
2011-01-14 04:00:54 +08:00
|
|
|
else
|
2011-06-16 12:16:24 +08:00
|
|
|
CGF.EmitScalarInit(Init, &D, lv, false);
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
case TEK_Complex:
|
|
|
|
CGF.EmitComplexExprIntoLValue(Init, lv, /*isInit*/ true);
|
|
|
|
return;
|
|
|
|
case TEK_Aggregate:
|
2012-03-30 01:37:10 +08:00
|
|
|
CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed,
|
|
|
|
AggValueSlot::DoesNotNeedGCBarriers,
|
|
|
|
AggValueSlot::IsNotAliased));
|
2013-03-08 05:37:08 +08:00
|
|
|
return;
|
2009-12-10 08:16:00 +08:00
|
|
|
}
|
2013-03-08 05:37:08 +08:00
|
|
|
llvm_unreachable("bad evaluation kind");
|
2009-12-10 08:16:00 +08:00
|
|
|
}
|
|
|
|
|
2010-09-08 09:44:27 +08:00
|
|
|
/// Emit code to cause the destruction of the given variable with
|
|
|
|
/// static storage duration.
|
2010-05-05 23:38:32 +08:00
|
|
|
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ConstantAddress addr) {
|
2010-05-05 23:38:32 +08:00
|
|
|
CodeGenModule &CGM = CGF.CGM;
|
2011-07-13 11:01:35 +08:00
|
|
|
|
|
|
|
// FIXME: __attribute__((cleanup)) ?
|
2010-05-05 23:38:32 +08:00
|
|
|
|
2011-07-13 11:01:35 +08:00
|
|
|
QualType type = D.getType();
|
|
|
|
QualType::DestructionKind dtorKind = type.isDestructedType();
|
|
|
|
|
|
|
|
switch (dtorKind) {
|
|
|
|
case QualType::DK_none:
|
2010-05-05 23:38:32 +08:00
|
|
|
return;
|
2011-07-13 11:01:35 +08:00
|
|
|
|
|
|
|
case QualType::DK_cxx_destructor:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case QualType::DK_objc_strong_lifetime:
|
|
|
|
case QualType::DK_objc_weak_lifetime:
|
|
|
|
// We don't care about releasing objects during process teardown.
|
2013-04-15 07:01:42 +08:00
|
|
|
assert(!D.getTLSKind() && "should have rejected this");
|
2010-05-05 23:38:32 +08:00
|
|
|
return;
|
2011-07-13 11:01:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
llvm::Constant *function;
|
|
|
|
llvm::Constant *argument;
|
|
|
|
|
|
|
|
// Special-case non-array C++ destructors, where there's a function
|
|
|
|
// with the right signature that we can just call.
|
2014-05-21 13:09:00 +08:00
|
|
|
const CXXRecordDecl *record = nullptr;
|
2011-07-13 11:01:35 +08:00
|
|
|
if (dtorKind == QualType::DK_cxx_destructor &&
|
|
|
|
(record = type->getAsCXXRecordDecl())) {
|
|
|
|
assert(!record->hasTrivialDestructor());
|
|
|
|
CXXDestructorDecl *dtor = record->getDestructor();
|
|
|
|
|
2014-09-11 23:42:06 +08:00
|
|
|
function = CGM.getAddrOfCXXStructor(dtor, StructorType::Complete);
|
2013-10-03 00:03:16 +08:00
|
|
|
argument = llvm::ConstantExpr::getBitCast(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
addr.getPointer(), CGF.getTypes().ConvertType(type)->getPointerTo());
|
2011-07-13 11:01:35 +08:00
|
|
|
|
|
|
|
// Otherwise, the standard logic requires a helper function.
|
|
|
|
} else {
|
2013-08-28 07:57:18 +08:00
|
|
|
function = CodeGenFunction(CGM)
|
|
|
|
.generateDestroyHelper(addr, type, CGF.getDestroyer(dtorKind),
|
|
|
|
CGF.needsEHCleanup(dtorKind), &D);
|
2011-07-13 11:01:35 +08:00
|
|
|
argument = llvm::Constant::getNullValue(CGF.Int8PtrTy);
|
|
|
|
}
|
|
|
|
|
2013-04-15 07:01:42 +08:00
|
|
|
CGM.getCXXABI().registerGlobalDtor(CGF, D, function, argument);
|
2010-05-05 23:38:32 +08:00
|
|
|
}
|
|
|
|
|
2012-02-17 15:31:37 +08:00
|
|
|
/// Emit code to cause the variable at the given address to be considered as
|
|
|
|
/// constant from this point onwards.
|
2012-02-21 08:26:58 +08:00
|
|
|
static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D,
|
|
|
|
llvm::Constant *Addr) {
|
2012-02-18 04:12:52 +08:00
|
|
|
// Don't emit the intrinsic if we're not optimizing.
|
|
|
|
if (!CGF.CGM.getCodeGenOpts().OptimizationLevel)
|
|
|
|
return;
|
|
|
|
|
2012-02-17 15:31:37 +08:00
|
|
|
// Grab the llvm.invariant.start intrinsic.
|
|
|
|
llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
|
|
|
|
llvm::Constant *InvariantStart = CGF.CGM.getIntrinsic(InvStartID);
|
|
|
|
|
2012-02-21 08:26:58 +08:00
|
|
|
// Emit a call with the size in bytes of the object.
|
|
|
|
CharUnits WidthChars = CGF.getContext().getTypeSizeInChars(D.getType());
|
|
|
|
uint64_t Width = WidthChars.getQuantity();
|
|
|
|
llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(CGF.Int64Ty, Width),
|
2012-02-17 15:31:37 +08:00
|
|
|
llvm::ConstantExpr::getBitCast(Addr, CGF.Int8PtrTy)};
|
|
|
|
CGF.Builder.CreateCall(InvariantStart, Args);
|
|
|
|
}
|
|
|
|
|
2009-12-10 08:57:45 +08:00
|
|
|
void CodeGenFunction::EmitCXXGlobalVarDeclInit(const VarDecl &D,
|
2012-02-14 06:16:19 +08:00
|
|
|
llvm::Constant *DeclPtr,
|
|
|
|
bool PerformInit) {
|
2009-12-10 08:57:45 +08:00
|
|
|
|
|
|
|
const Expr *Init = D.getInit();
|
|
|
|
QualType T = D.getType();
|
|
|
|
|
2015-03-26 04:06:28 +08:00
|
|
|
// The address space of a static local variable (DeclPtr) may be different
|
|
|
|
// from the address space of the "this" argument of the constructor. In that
|
|
|
|
// case, we need an addrspacecast before calling the constructor.
|
|
|
|
//
|
|
|
|
// struct StructWithCtor {
|
|
|
|
// __device__ StructWithCtor() {...}
|
|
|
|
// };
|
|
|
|
// __device__ void foo() {
|
|
|
|
// __shared__ StructWithCtor s;
|
|
|
|
// ...
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// For example, in the above CUDA code, the static local variable s has a
|
|
|
|
// "shared" address space qualifier, but the constructor of StructWithCtor
|
|
|
|
// expects "this" in the "generic" address space.
|
|
|
|
unsigned ExpectedAddrSpace = getContext().getTargetAddressSpace(T);
|
|
|
|
unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
|
|
|
|
if (ActualAddrSpace != ExpectedAddrSpace) {
|
|
|
|
llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(T);
|
|
|
|
llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
|
|
|
|
DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
|
|
|
|
}
|
|
|
|
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
ConstantAddress DeclAddr(DeclPtr, getContext().getDeclAlign(&D));
|
|
|
|
|
2009-12-10 08:57:45 +08:00
|
|
|
if (!T->isReferenceType()) {
|
2014-11-11 12:05:39 +08:00
|
|
|
if (getLangOpts().OpenMP && D.hasAttr<OMPThreadPrivateDeclAttr>())
|
2015-02-25 16:32:46 +08:00
|
|
|
(void)CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
&D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
|
2014-11-11 12:05:39 +08:00
|
|
|
PerformInit, this);
|
2012-02-14 06:16:19 +08:00
|
|
|
if (PerformInit)
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitDeclInit(*this, D, DeclAddr);
|
2012-02-17 15:31:37 +08:00
|
|
|
if (CGM.isTypeConstant(D.getType(), true))
|
2012-02-21 08:26:58 +08:00
|
|
|
EmitDeclInvariant(*this, D, DeclPtr);
|
2012-02-17 15:31:37 +08:00
|
|
|
else
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitDeclDestroy(*this, D, DeclAddr);
|
2009-12-10 08:57:45 +08:00
|
|
|
return;
|
|
|
|
}
|
2010-06-28 01:52:15 +08:00
|
|
|
|
2012-02-14 06:16:19 +08:00
|
|
|
assert(PerformInit && "cannot have constant initializer which needs "
|
|
|
|
"destruction for reference");
|
2013-06-13 07:38:09 +08:00
|
|
|
RValue RV = EmitReferenceBindingToExpr(Init);
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
EmitStoreOfScalar(RV.getScalarVal(), DeclAddr, false, T);
|
2009-12-10 08:57:45 +08:00
|
|
|
}
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2012-04-07 02:21:06 +08:00
|
|
|
/// Create a stub function, suitable for being passed to atexit,
|
|
|
|
/// which passes the given address to the given destructor function.
|
2014-10-05 13:05:40 +08:00
|
|
|
llvm::Constant *CodeGenFunction::createAtExitStub(const VarDecl &VD,
|
|
|
|
llvm::Constant *dtor,
|
|
|
|
llvm::Constant *addr) {
|
2012-04-07 02:21:06 +08:00
|
|
|
// Get the destructor function type, void(*)(void).
|
|
|
|
llvm::FunctionType *ty = llvm::FunctionType::get(CGM.VoidTy, false);
|
2013-09-11 04:14:30 +08:00
|
|
|
SmallString<256> FnName;
|
|
|
|
{
|
|
|
|
llvm::raw_svector_ostream Out(FnName);
|
|
|
|
CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
|
|
|
|
}
|
2015-10-31 09:28:07 +08:00
|
|
|
|
|
|
|
const CGFunctionInfo &FI = CGM.getTypes().arrangeNullaryFunction();
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(ty, FnName.str(),
|
2015-10-31 09:28:07 +08:00
|
|
|
FI,
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
VD.getLocation());
|
2012-04-07 02:21:06 +08:00
|
|
|
|
|
|
|
CodeGenFunction CGF(CGM);
|
2010-03-20 12:15:41 +08:00
|
|
|
|
2015-10-31 09:28:07 +08:00
|
|
|
CGF.StartFunction(&VD, CGM.getContext().VoidTy, fn, FI, FunctionArgList());
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2012-04-07 02:21:06 +08:00
|
|
|
llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
|
|
|
|
|
|
|
|
// Make sure the call and the callee agree on calling convention.
|
|
|
|
if (llvm::Function *dtorFn =
|
|
|
|
dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
|
|
|
|
call->setCallingConv(dtorFn->getCallingConv());
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2012-04-07 02:21:06 +08:00
|
|
|
CGF.FinishFunction();
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2012-04-07 02:21:06 +08:00
|
|
|
return fn;
|
|
|
|
}
|
|
|
|
|
2012-05-01 14:13:13 +08:00
|
|
|
/// Register a global destructor using the C atexit runtime function.
|
2013-08-28 07:57:18 +08:00
|
|
|
void CodeGenFunction::registerGlobalDtorWithAtExit(const VarDecl &VD,
|
|
|
|
llvm::Constant *dtor,
|
2012-05-01 14:13:13 +08:00
|
|
|
llvm::Constant *addr) {
|
2012-04-07 02:21:06 +08:00
|
|
|
// Create a function which calls the destructor.
|
2014-10-05 13:05:40 +08:00
|
|
|
llvm::Constant *dtorStub = createAtExitStub(VD, dtor, addr);
|
2012-04-07 02:21:06 +08:00
|
|
|
|
|
|
|
// extern "C" int atexit(void (*f)(void));
|
|
|
|
llvm::FunctionType *atexitTy =
|
2012-05-01 14:13:13 +08:00
|
|
|
llvm::FunctionType::get(IntTy, dtorStub->getType(), false);
|
2012-04-07 02:21:06 +08:00
|
|
|
|
|
|
|
llvm::Constant *atexit =
|
2012-05-01 14:13:13 +08:00
|
|
|
CGM.CreateRuntimeFunction(atexitTy, "atexit");
|
2012-04-07 02:21:06 +08:00
|
|
|
if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
|
|
|
|
atexitFn->setDoesNotThrow();
|
|
|
|
|
2013-03-01 03:01:20 +08:00
|
|
|
EmitNounwindRuntimeCall(atexit, dtorStub);
|
2009-12-10 08:30:05 +08:00
|
|
|
}
|
|
|
|
|
2010-11-06 17:44:32 +08:00
|
|
|
void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D,
|
2012-03-31 03:44:53 +08:00
|
|
|
llvm::GlobalVariable *DeclPtr,
|
2012-02-14 06:16:19 +08:00
|
|
|
bool PerformInit) {
|
2011-03-18 10:56:14 +08:00
|
|
|
// If we've been asked to forbid guard variables, emit an error now.
|
|
|
|
// This diagnostic is hard-coded for Darwin's use case; we can find
|
|
|
|
// better phrasing if someone else needs it.
|
|
|
|
if (CGM.getCodeGenOpts().ForbidGuardVariables)
|
|
|
|
CGM.Error(D.getLocation(),
|
|
|
|
"this initialization requires a guard variable, which "
|
|
|
|
"the kernel does not support");
|
|
|
|
|
2012-03-31 03:44:53 +08:00
|
|
|
CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr, PerformInit);
|
2010-09-08 09:44:27 +08:00
|
|
|
}
|
|
|
|
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction(
|
2015-10-31 09:28:07 +08:00
|
|
|
llvm::FunctionType *FTy, const Twine &Name, const CGFunctionInfo &FI,
|
|
|
|
SourceLocation Loc, bool TLS) {
|
2010-06-09 06:40:05 +08:00
|
|
|
llvm::Function *Fn =
|
|
|
|
llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
|
2014-10-05 13:05:40 +08:00
|
|
|
Name, &getModule());
|
|
|
|
if (!getLangOpts().AppleKext && !TLS) {
|
2011-02-16 02:54:46 +08:00
|
|
|
// Set the section if needed.
|
2014-10-05 13:05:40 +08:00
|
|
|
if (const char *Section = getTarget().getStaticInitSectionSpecifier())
|
2011-02-16 02:54:46 +08:00
|
|
|
Fn->setSection(Section);
|
|
|
|
}
|
2010-06-09 06:47:50 +08:00
|
|
|
|
2015-10-31 09:28:07 +08:00
|
|
|
SetInternalFunctionAttributes(nullptr, Fn, FI);
|
2015-04-23 03:37:32 +08:00
|
|
|
|
2014-10-05 13:05:40 +08:00
|
|
|
Fn->setCallingConv(getRuntimeCC());
|
2013-03-01 03:01:20 +08:00
|
|
|
|
2014-10-05 13:05:40 +08:00
|
|
|
if (!getLangOpts().Exceptions)
|
2010-07-06 12:38:10 +08:00
|
|
|
Fn->setDoesNotThrow();
|
|
|
|
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
if (!isInSanitizerBlacklist(Fn, Loc)) {
|
2015-06-19 20:19:07 +08:00
|
|
|
if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
|
|
|
|
SanitizerKind::KernelAddress))
|
2014-07-08 07:34:34 +08:00
|
|
|
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
|
2014-11-08 06:29:38 +08:00
|
|
|
if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
|
2014-07-08 07:34:34 +08:00
|
|
|
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
2014-11-08 06:29:38 +08:00
|
|
|
if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
|
2014-07-08 07:34:34 +08:00
|
|
|
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
|
2015-06-16 05:08:13 +08:00
|
|
|
if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
|
|
|
|
Fn->addFnAttr(llvm::Attribute::SafeStack);
|
2014-07-08 07:34:34 +08:00
|
|
|
}
|
2012-06-26 16:56:33 +08:00
|
|
|
|
2010-06-09 06:40:05 +08:00
|
|
|
return Fn;
|
|
|
|
}
|
|
|
|
|
2014-07-22 08:53:05 +08:00
|
|
|
/// Create a global pointer to a function that will initialize a global
|
|
|
|
/// variable. The user has requested that this pointer be emitted in a specific
|
|
|
|
/// section.
|
|
|
|
void CodeGenModule::EmitPointerToInitFunc(const VarDecl *D,
|
|
|
|
llvm::GlobalVariable *GV,
|
|
|
|
llvm::Function *InitFunc,
|
|
|
|
InitSegAttr *ISA) {
|
|
|
|
llvm::GlobalVariable *PtrArray = new llvm::GlobalVariable(
|
|
|
|
TheModule, InitFunc->getType(), /*isConstant=*/true,
|
|
|
|
llvm::GlobalValue::PrivateLinkage, InitFunc, "__cxx_init_fn_ptr");
|
|
|
|
PtrArray->setSection(ISA->getSection());
|
|
|
|
addUsedGlobal(PtrArray);
|
|
|
|
|
|
|
|
// If the GV is already in a comdat group, then we have to join it.
|
2015-01-13 06:13:53 +08:00
|
|
|
if (llvm::Comdat *C = GV->getComdat())
|
2014-07-22 08:53:05 +08:00
|
|
|
PtrArray->setComdat(C);
|
|
|
|
}
|
|
|
|
|
2010-03-20 12:15:41 +08:00
|
|
|
void
|
2010-11-06 17:44:32 +08:00
|
|
|
CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
|
2012-02-14 06:16:19 +08:00
|
|
|
llvm::GlobalVariable *Addr,
|
|
|
|
bool PerformInit) {
|
2016-02-03 06:29:48 +08:00
|
|
|
|
|
|
|
// According to E.2.3.1 in CUDA-7.5 Programming guide: __device__,
|
|
|
|
// __constant__ and __shared__ variables defined in namespace scope,
|
|
|
|
// that are of class type, cannot have a non-empty constructor. All
|
|
|
|
// the checks have been done in Sema by now. Whatever initializers
|
|
|
|
// are allowed are empty and we just need to ignore them here.
|
|
|
|
if (getLangOpts().CUDA && getLangOpts().CUDAIsDevice &&
|
|
|
|
(D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
|
|
|
|
D->hasAttr<CUDASharedAttr>()))
|
|
|
|
return;
|
|
|
|
|
2015-04-15 09:08:06 +08:00
|
|
|
// Check if we've already initialized this decl.
|
|
|
|
auto I = DelayedCXXInitPosition.find(D);
|
|
|
|
if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
|
|
|
|
return;
|
|
|
|
|
2012-02-07 08:39:47 +08:00
|
|
|
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
|
2013-09-11 04:43:12 +08:00
|
|
|
SmallString<256> FnName;
|
|
|
|
{
|
|
|
|
llvm::raw_svector_ostream Out(FnName);
|
|
|
|
getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
|
|
|
|
}
|
2010-01-08 08:50:11 +08:00
|
|
|
|
|
|
|
// Create a variable initialization function.
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
llvm::Function *Fn =
|
2015-10-31 09:28:07 +08:00
|
|
|
CreateGlobalInitOrDestructFunction(FTy, FnName.str(),
|
|
|
|
getTypes().arrangeNullaryFunction(),
|
|
|
|
D->getLocation());
|
2010-01-08 08:50:11 +08:00
|
|
|
|
2014-07-22 08:53:05 +08:00
|
|
|
auto *ISA = D->getAttr<InitSegAttr>();
|
2012-02-14 06:16:19 +08:00
|
|
|
CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
|
|
|
|
PerformInit);
|
2014-09-19 09:54:22 +08:00
|
|
|
|
2014-10-16 00:38:00 +08:00
|
|
|
llvm::GlobalVariable *COMDATKey =
|
|
|
|
supportsCOMDAT() && D->isExternallyVisible() ? Addr : nullptr;
|
2014-09-19 09:54:22 +08:00
|
|
|
|
2013-04-20 00:42:07 +08:00
|
|
|
if (D->getTLSKind()) {
|
|
|
|
// FIXME: Should we support init_priority for thread_local?
|
|
|
|
// FIXME: Ideally, initialization of instantiated thread_local static data
|
|
|
|
// members of class templates should not trigger initialization of other
|
|
|
|
// entities in the TU.
|
|
|
|
// FIXME: We only need to register one __cxa_thread_atexit function for the
|
|
|
|
// entire TU.
|
|
|
|
CXXThreadLocalInits.push_back(Fn);
|
2015-12-01 09:10:48 +08:00
|
|
|
CXXThreadLocalInitVars.push_back(D);
|
2014-07-22 08:53:05 +08:00
|
|
|
} else if (PerformInit && ISA) {
|
|
|
|
EmitPointerToInitFunc(D, Addr, Fn, ISA);
|
|
|
|
} else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
|
2013-12-19 11:02:49 +08:00
|
|
|
OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
|
2010-06-22 05:27:42 +08:00
|
|
|
PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
|
2014-10-16 00:38:00 +08:00
|
|
|
} else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
|
2013-08-23 04:07:45 +08:00
|
|
|
// C++ [basic.start.init]p2:
|
2013-09-04 08:54:24 +08:00
|
|
|
// Definitions of explicitly specialized class template static data
|
|
|
|
// members have ordered initialization. Other class template static data
|
|
|
|
// members (i.e., implicitly or explicitly instantiated specializations)
|
|
|
|
// have unordered initialization.
|
2013-08-23 04:07:45 +08:00
|
|
|
//
|
|
|
|
// As a consequence, we can put them into their own llvm.global_ctors entry.
|
2014-05-24 05:13:45 +08:00
|
|
|
//
|
2014-10-16 00:38:00 +08:00
|
|
|
// If the global is externally visible, put the initializer into a COMDAT
|
|
|
|
// group with the global being initialized. On most platforms, this is a
|
|
|
|
// minor startup time optimization. In the MS C++ ABI, there are no guard
|
|
|
|
// variables, so this COMDAT key is required for correctness.
|
|
|
|
AddGlobalCtor(Fn, 65535, COMDATKey);
|
2014-09-11 03:28:48 +08:00
|
|
|
} else if (D->hasAttr<SelectAnyAttr>()) {
|
2015-01-13 05:24:10 +08:00
|
|
|
// SelectAny globals will be comdat-folded. Put the initializer into a
|
|
|
|
// COMDAT group associated with the global, so the initializers get folded
|
|
|
|
// too.
|
2014-10-16 00:38:00 +08:00
|
|
|
AddGlobalCtor(Fn, 65535, COMDATKey);
|
2013-04-20 00:42:07 +08:00
|
|
|
} else {
|
2015-04-15 09:08:06 +08:00
|
|
|
I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.
|
2010-07-16 07:40:35 +08:00
|
|
|
if (I == DelayedCXXInitPosition.end()) {
|
|
|
|
CXXGlobalInits.push_back(Fn);
|
2015-04-15 09:08:06 +08:00
|
|
|
} else if (I->second != ~0U) {
|
|
|
|
assert(I->second < CXXGlobalInits.size() &&
|
|
|
|
CXXGlobalInits[I->second] == nullptr);
|
2010-07-16 07:40:35 +08:00
|
|
|
CXXGlobalInits[I->second] = Fn;
|
|
|
|
}
|
2010-06-22 02:45:05 +08:00
|
|
|
}
|
2015-04-15 09:08:06 +08:00
|
|
|
|
|
|
|
// Remember that we already emitted the initializer for this global.
|
|
|
|
DelayedCXXInitPosition[D] = ~0U;
|
2010-01-08 08:50:11 +08:00
|
|
|
}
|
|
|
|
|
2013-04-20 00:42:07 +08:00
|
|
|
void CodeGenModule::EmitCXXThreadLocalInitFunc() {
|
2014-10-05 13:05:40 +08:00
|
|
|
getCXXABI().EmitThreadLocalInitFuncs(
|
|
|
|
*this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
|
2013-04-20 00:42:07 +08:00
|
|
|
|
|
|
|
CXXThreadLocalInits.clear();
|
2014-10-05 13:05:40 +08:00
|
|
|
CXXThreadLocalInitVars.clear();
|
2013-04-20 00:42:07 +08:00
|
|
|
CXXThreadLocals.clear();
|
|
|
|
}
|
|
|
|
|
2010-03-20 12:15:41 +08:00
|
|
|
void
|
|
|
|
CodeGenModule::EmitCXXGlobalInitFunc() {
|
2010-07-16 07:40:35 +08:00
|
|
|
while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
|
|
|
|
CXXGlobalInits.pop_back();
|
|
|
|
|
2010-06-22 02:45:05 +08:00
|
|
|
if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
|
2009-12-10 08:30:05 +08:00
|
|
|
return;
|
|
|
|
|
2012-02-07 08:39:47 +08:00
|
|
|
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
|
2015-10-31 09:28:07 +08:00
|
|
|
const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
|
2010-03-20 12:15:41 +08:00
|
|
|
|
2012-11-07 06:44:45 +08:00
|
|
|
// Create our global initialization function.
|
2010-06-22 02:45:05 +08:00
|
|
|
if (!PrioritizedCXXGlobalInits.empty()) {
|
2014-10-05 13:05:40 +08:00
|
|
|
SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
|
2010-06-22 03:49:38 +08:00
|
|
|
llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
|
2012-11-07 06:44:45 +08:00
|
|
|
PrioritizedCXXGlobalInits.end());
|
|
|
|
// Iterate over "chunks" of ctors with same priority and emit each chunk
|
|
|
|
// into separate function. Note - everything is sorted first by priority,
|
|
|
|
// second - by lex order, so we emit ctor functions in proper order.
|
|
|
|
for (SmallVectorImpl<GlobalInitData >::iterator
|
|
|
|
I = PrioritizedCXXGlobalInits.begin(),
|
|
|
|
E = PrioritizedCXXGlobalInits.end(); I != E; ) {
|
|
|
|
SmallVectorImpl<GlobalInitData >::iterator
|
|
|
|
PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
|
|
|
|
|
|
|
|
LocalCXXGlobalInits.clear();
|
|
|
|
unsigned Priority = I->first.priority;
|
|
|
|
// Compute the function suffix from priority. Prepend with zeroes to make
|
|
|
|
// sure the function names are also ordered as priorities.
|
|
|
|
std::string PrioritySuffix = llvm::utostr(Priority);
|
2014-05-07 04:32:45 +08:00
|
|
|
// Priority is always <= 65535 (enforced by sema).
|
2012-11-07 06:44:45 +08:00
|
|
|
PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix;
|
2014-10-05 13:05:40 +08:00
|
|
|
llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
|
2015-10-31 09:28:07 +08:00
|
|
|
FTy, "_GLOBAL__I_" + PrioritySuffix, FI);
|
2014-10-05 13:05:40 +08:00
|
|
|
|
2012-11-07 06:44:45 +08:00
|
|
|
for (; I < PrioE; ++I)
|
|
|
|
LocalCXXGlobalInits.push_back(I->second);
|
|
|
|
|
2013-04-27 05:32:52 +08:00
|
|
|
CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);
|
2012-11-07 06:44:45 +08:00
|
|
|
AddGlobalCtor(Fn, Priority);
|
|
|
|
}
|
2015-06-20 23:51:52 +08:00
|
|
|
PrioritizedCXXGlobalInits.clear();
|
2010-06-22 02:45:05 +08:00
|
|
|
}
|
2014-08-27 06:10:15 +08:00
|
|
|
|
|
|
|
SmallString<128> FileName;
|
2014-05-07 04:32:45 +08:00
|
|
|
SourceManager &SM = Context.getSourceManager();
|
2014-08-27 06:10:15 +08:00
|
|
|
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 {
|
2015-05-12 20:47:05 +08:00
|
|
|
FileName = "<null>";
|
2014-08-27 06:10:15 +08:00
|
|
|
}
|
|
|
|
|
2014-05-07 04:32:45 +08:00
|
|
|
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] = '_';
|
|
|
|
}
|
2014-08-27 06:10:15 +08:00
|
|
|
|
2014-05-07 04:32:45 +08:00
|
|
|
llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
|
2015-10-31 09:28:07 +08:00
|
|
|
FTy, llvm::Twine("_GLOBAL__sub_I_", FileName), FI);
|
2012-11-07 06:44:45 +08:00
|
|
|
|
2013-04-27 05:32:52 +08:00
|
|
|
CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
|
2010-03-20 12:15:41 +08:00
|
|
|
AddGlobalCtor(Fn);
|
2012-11-07 06:44:45 +08:00
|
|
|
|
2011-05-06 23:24:04 +08:00
|
|
|
CXXGlobalInits.clear();
|
2010-03-20 12:15:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CodeGenModule::EmitCXXGlobalDtorFunc() {
|
|
|
|
if (CXXGlobalDtors.empty())
|
|
|
|
return;
|
|
|
|
|
2012-02-07 08:39:47 +08:00
|
|
|
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2010-03-20 12:15:41 +08:00
|
|
|
// Create our global destructor function.
|
2015-10-31 09:28:07 +08:00
|
|
|
const CGFunctionInfo &FI = getTypes().arrangeNullaryFunction();
|
|
|
|
llvm::Function *Fn =
|
|
|
|
CreateGlobalInitOrDestructFunction(FTy, "_GLOBAL__D_a", FI);
|
2010-03-20 12:15:41 +08:00
|
|
|
|
2012-04-07 02:21:03 +08:00
|
|
|
CodeGenFunction(*this).GenerateCXXGlobalDtorsFunc(Fn, CXXGlobalDtors);
|
2010-03-20 12:15:41 +08:00
|
|
|
AddGlobalDtor(Fn);
|
|
|
|
}
|
|
|
|
|
2010-11-06 17:44:32 +08:00
|
|
|
/// Emit the code necessary to initialize the given global variable.
|
2010-03-20 12:15:41 +08:00
|
|
|
void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
|
2010-11-06 17:44:32 +08:00
|
|
|
const VarDecl *D,
|
2012-02-14 06:16:19 +08:00
|
|
|
llvm::GlobalVariable *Addr,
|
|
|
|
bool PerformInit) {
|
2012-10-16 15:22:28 +08:00
|
|
|
// Check if we need to emit debug info for variable initializer.
|
2013-08-27 04:33:21 +08:00
|
|
|
if (D->hasAttr<NoDebugAttr>())
|
2014-05-21 13:09:00 +08:00
|
|
|
DebugInfo = nullptr; // disable debug info indefinitely for this function
|
2012-07-24 09:40:49 +08:00
|
|
|
|
2015-01-14 15:10:46 +08:00
|
|
|
CurEHLocation = D->getLocStart();
|
|
|
|
|
2012-07-24 09:40:49 +08:00
|
|
|
StartFunction(GlobalDecl(D), getContext().VoidTy, Fn,
|
2012-02-17 11:33:10 +08:00
|
|
|
getTypes().arrangeNullaryFunction(),
|
2014-04-11 07:21:53 +08:00
|
|
|
FunctionArgList(), D->getLocation(),
|
|
|
|
D->getInit()->getExprLoc());
|
2010-01-08 08:50:11 +08:00
|
|
|
|
2011-07-02 05:54:36 +08:00
|
|
|
// Use guarded initialization if the global variable is weak. This
|
|
|
|
// occurs for, e.g., instantiated static data members and
|
|
|
|
// definitions explicitly marked weak.
|
2014-05-24 05:13:45 +08:00
|
|
|
if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
|
2012-02-14 06:16:19 +08:00
|
|
|
EmitCXXGuardedInit(*D, Addr, PerformInit);
|
2010-11-06 17:44:32 +08:00
|
|
|
} else {
|
2012-02-14 06:16:19 +08:00
|
|
|
EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
|
2010-10-27 06:47:47 +08:00
|
|
|
}
|
2010-01-08 08:50:11 +08:00
|
|
|
|
|
|
|
FinishFunction();
|
2010-03-20 12:15:41 +08:00
|
|
|
}
|
2009-12-10 08:30:05 +08:00
|
|
|
|
2013-04-27 05:32:52 +08:00
|
|
|
void
|
|
|
|
CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
|
2014-10-05 13:05:40 +08:00
|
|
|
ArrayRef<llvm::Function *> Decls,
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address Guard) {
|
2014-04-12 07:45:01 +08:00
|
|
|
{
|
2015-02-04 04:00:54 +08:00
|
|
|
auto NL = ApplyDebugLocation::CreateEmpty(*this);
|
2014-04-12 07:45:01 +08:00
|
|
|
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
|
|
|
|
getTypes().arrangeNullaryFunction(), FunctionArgList());
|
|
|
|
// Emit an artificial location for this function.
|
2015-02-04 04:00:54 +08:00
|
|
|
auto AL = ApplyDebugLocation::CreateArtificial(*this);
|
2014-04-12 07:45:01 +08:00
|
|
|
|
2014-05-21 13:09:00 +08:00
|
|
|
llvm::BasicBlock *ExitBlock = nullptr;
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
if (Guard.isValid()) {
|
2014-04-12 07:45:01 +08:00
|
|
|
// If we have a guard variable, check whether we've already performed
|
|
|
|
// these initializations. This happens for TLS initialization functions.
|
|
|
|
llvm::Value *GuardVal = Builder.CreateLoad(Guard);
|
|
|
|
llvm::Value *Uninit = Builder.CreateIsNull(GuardVal,
|
|
|
|
"guard.uninitialized");
|
|
|
|
llvm::BasicBlock *InitBlock = createBasicBlock("init");
|
|
|
|
ExitBlock = createBasicBlock("exit");
|
|
|
|
Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
|
|
|
|
EmitBlock(InitBlock);
|
2015-11-12 03:19:26 +08:00
|
|
|
// Mark as initialized before initializing anything else. If the
|
|
|
|
// initializers use previously-initialized thread_local vars, that's
|
|
|
|
// probably supposed to be OK, but the standard doesn't say.
|
|
|
|
Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
|
2014-04-12 07:45:01 +08:00
|
|
|
}
|
2013-04-20 00:42:07 +08:00
|
|
|
|
2014-04-12 07:45:01 +08:00
|
|
|
RunCleanupsScope Scope(*this);
|
2011-06-16 07:02:42 +08:00
|
|
|
|
2014-04-12 07:45:01 +08:00
|
|
|
// When building in Objective-C++ ARC mode, create an autorelease pool
|
|
|
|
// around the global initializers.
|
|
|
|
if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {
|
|
|
|
llvm::Value *token = EmitObjCAutoreleasePoolPush();
|
|
|
|
EmitObjCAutoreleasePoolCleanup(token);
|
|
|
|
}
|
2013-04-27 05:32:52 +08:00
|
|
|
|
2014-04-12 07:45:01 +08:00
|
|
|
for (unsigned i = 0, e = Decls.size(); i != e; ++i)
|
|
|
|
if (Decls[i])
|
|
|
|
EmitRuntimeCall(Decls[i]);
|
2010-03-20 12:15:41 +08:00
|
|
|
|
2014-04-12 07:45:01 +08:00
|
|
|
Scope.ForceCleanup();
|
2013-04-20 00:42:07 +08:00
|
|
|
|
2014-04-12 07:45:01 +08:00
|
|
|
if (ExitBlock) {
|
|
|
|
Builder.CreateBr(ExitBlock);
|
|
|
|
EmitBlock(ExitBlock);
|
|
|
|
}
|
2013-04-20 00:42:07 +08:00
|
|
|
}
|
|
|
|
|
2010-03-20 12:15:41 +08:00
|
|
|
FinishFunction();
|
|
|
|
}
|
|
|
|
|
2012-04-07 02:21:03 +08:00
|
|
|
void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn,
|
2010-06-19 13:52:45 +08:00
|
|
|
const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
|
2010-03-20 12:15:41 +08:00
|
|
|
&DtorsAndObjects) {
|
2014-04-12 07:45:01 +08:00
|
|
|
{
|
2015-02-04 04:00:54 +08:00
|
|
|
auto NL = ApplyDebugLocation::CreateEmpty(*this);
|
2014-04-12 07:45:01 +08:00
|
|
|
StartFunction(GlobalDecl(), getContext().VoidTy, Fn,
|
|
|
|
getTypes().arrangeNullaryFunction(), FunctionArgList());
|
|
|
|
// Emit an artificial location for this function.
|
2015-02-04 04:00:54 +08:00
|
|
|
auto AL = ApplyDebugLocation::CreateArtificial(*this);
|
2014-04-12 07:45:01 +08:00
|
|
|
|
|
|
|
// Emit the dtors, in reverse order from construction.
|
|
|
|
for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
|
|
|
|
llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
|
|
|
|
llvm::CallInst *CI = Builder.CreateCall(Callee,
|
|
|
|
DtorsAndObjects[e - i - 1].second);
|
|
|
|
// Make sure the call and the callee agree on calling convention.
|
|
|
|
if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
|
|
|
|
CI->setCallingConv(F->getCallingConv());
|
|
|
|
}
|
2010-04-27 04:35:54 +08:00
|
|
|
}
|
2010-03-20 12:15:41 +08:00
|
|
|
|
|
|
|
FinishFunction();
|
2009-12-10 08:30:05 +08:00
|
|
|
}
|
|
|
|
|
2011-07-13 11:01:35 +08:00
|
|
|
/// generateDestroyHelper - Generates a helper function which, when
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
/// invoked, destroys the given object. The address of the object
|
|
|
|
/// should be in global memory.
|
2013-08-28 07:57:18 +08:00
|
|
|
llvm::Function *CodeGenFunction::generateDestroyHelper(
|
Compute and preserve alignment more faithfully in IR-generation.
Introduce an Address type to bundle a pointer value with an
alignment. Introduce APIs on CGBuilderTy to work with Address
values. Change core APIs on CGF/CGM to traffic in Address where
appropriate. Require alignments to be non-zero. Update a ton
of code to compute and propagate alignment information.
As part of this, I've promoted CGBuiltin's EmitPointerWithAlignment
helper function to CGF and made use of it in a number of places in
the expression emitter.
The end result is that we should now be significantly more correct
when performing operations on objects that are locally known to
be under-aligned. Since alignment is not reliably tracked in the
type system, there are inherent limits to this, but at least we
are no longer confused by standard operations like derived-to-base
conversions and array-to-pointer decay. I've also fixed a large
number of bugs where we were applying the complete-object alignment
to a pointer instead of the non-virtual alignment, although most of
these were hidden by the very conservative approach we took with
member alignment.
Also, because IRGen now reliably asserts on zero alignments, we
should no longer be subject to an absurd but frustrating recurring
bug where an incomplete type would report a zero alignment and then
we'd naively do a alignmentAtOffset on it and emit code using an
alignment equal to the largest power-of-two factor of the offset.
We should also now be emitting much more aggressive alignment
attributes in the presence of over-alignment. In particular,
field access now uses alignmentAtOffset instead of min.
Several times in this patch, I had to change the existing
code-generation pattern in order to more effectively use
the Address APIs. For the most part, this seems to be a strict
improvement, like doing pointer arithmetic with GEPs instead of
ptrtoint. That said, I've tried very hard to not change semantics,
but it is likely that I've failed in a few places, for which I
apologize.
ABIArgInfo now always carries the assumed alignment of indirect and
indirect byval arguments. In order to cut down on what was already
a dauntingly large patch, I changed the code to never set align
attributes in the IR on non-byval indirect arguments. That is,
we still generate code which assumes that indirect arguments have
the given alignment, but we don't express this information to the
backend except where it's semantically required (i.e. on byvals).
This is likely a minor regression for those targets that did provide
this information, but it'll be trivial to add it back in a later
patch.
I partially punted on applying this work to CGBuiltin. Please
do not add more uses of the CreateDefaultAligned{Load,Store}
APIs; they will be going away eventually.
llvm-svn: 246985
2015-09-08 16:05:57 +08:00
|
|
|
Address addr, QualType type, Destroyer *destroyer,
|
2013-08-28 07:57:18 +08:00
|
|
|
bool useEHCleanupForArray, const VarDecl *VD) {
|
2011-03-09 12:27:21 +08:00
|
|
|
FunctionArgList args;
|
2014-05-21 13:09:00 +08:00
|
|
|
ImplicitParamDecl dst(getContext(), nullptr, SourceLocation(), nullptr,
|
If a declaration is loaded, and then a module import adds a redeclaration, then
ensure that querying the first declaration for its most recent declaration
checks for redeclarations from the imported module.
This works as follows:
* The 'most recent' pointer on a canonical declaration grows a pointer to the
external AST source and a generation number (space- and time-optimized for
the case where there is no external source).
* Each time the 'most recent' pointer is queried, if it has an external source,
we check whether it's up to date, and update it if not.
* The ancillary data stored on the canonical declaration is allocated lazily
to avoid filling it in for declarations that end up being non-canonical.
We'll still perform a redundant (ASTContext) allocation if someone asks for
the most recent declaration from a decl before setPreviousDecl is called,
but such cases are probably all bugs, and are now easy to find.
Some finessing is still in order here -- in particular, we use a very general
mechanism for handling the DefinitionData pointer on CXXRecordData, and a more
targeted approach would be more compact.
Also, the MayHaveOutOfDateDef mechanism should now be expunged, since it was
addressing only a corner of the full problem space here. That's not covered
by this patch.
Early performance benchmarks show that this makes no measurable difference to
Clang performance without modules enabled (and fixes a major correctness issue
with modules enabled). I'll revert if a full performance comparison shows any
problems.
llvm-svn: 209046
2014-05-17 07:01:30 +08:00
|
|
|
getContext().VoidPtrTy);
|
2011-03-09 12:27:21 +08:00
|
|
|
args.push_back(&dst);
|
2014-02-01 06:54:50 +08:00
|
|
|
|
|
|
|
const CGFunctionInfo &FI = CGM.getTypes().arrangeFreeFunctionDeclaration(
|
|
|
|
getContext().VoidTy, args, FunctionType::ExtInfo(), /*variadic=*/false);
|
2012-02-17 11:33:10 +08:00
|
|
|
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI);
|
SanitizerBlacklist: blacklist functions by their source location.
This commit changes the way we blacklist functions in ASan, TSan,
MSan and UBSan. We used to treat function as "blacklisted"
and turned off instrumentation in it in two cases:
1) Function is explicitly blacklisted by its mangled name.
This part is not changed.
2) Function is located in llvm::Module, whose identifier is
contained in the list of blacklisted sources. This is completely
wrong, as llvm::Module may not correspond to the actual source
file function is defined in. Also, function can be defined in
a header, in which case user had to blacklist the .cpp file
this header was #include'd into, not the header itself.
Such functions could cause other problems - for instance, if the
header was included in multiple source files, compiled
separately and linked into a single executable, we could end up
with both instrumented and non-instrumented version of the same
function participating in the same link.
After this change we will make blacklisting decision based on
the SourceLocation of a function definition. If a function is
not explicitly defined in the source file, (for example, the
function is compiler-generated and responsible for
initialization/destruction of a global variable), then it will
be blacklisted if the corresponding global variable is defined
in blacklisted source file, and will be instrumented otherwise.
After this commit, the active users of blacklist files may have
to revisit them. This is a backwards-incompatible change, but
I don't think it's possible or makes sense to support the
old incorrect behavior.
I plan to make similar change for blacklisting GlobalVariables
(which is ASan-specific).
llvm-svn: 219997
2014-10-17 08:20:19 +08:00
|
|
|
llvm::Function *fn = CGM.CreateGlobalInitOrDestructFunction(
|
2015-10-31 09:28:07 +08:00
|
|
|
FTy, "__cxx_global_array_dtor", FI, VD->getLocation());
|
2010-06-09 06:17:27 +08:00
|
|
|
|
2015-01-14 15:10:46 +08:00
|
|
|
CurEHLocation = VD->getLocStart();
|
|
|
|
|
2014-04-11 09:13:04 +08:00
|
|
|
StartFunction(VD, getContext().VoidTy, fn, FI, args);
|
2010-06-09 06:17:27 +08:00
|
|
|
|
2011-07-13 11:01:35 +08:00
|
|
|
emitDestroy(addr, type, destroyer, useEHCleanupForArray);
|
2010-06-09 06:17:27 +08:00
|
|
|
|
|
|
|
FinishFunction();
|
|
|
|
|
2011-07-13 11:01:35 +08:00
|
|
|
return fn;
|
2010-06-09 06:17:27 +08:00
|
|
|
}
|