According to the C++ standard, `dynamic_cast` of pointers either returns
a pointer (7.6.1.7) or results in undefined behavior (11.9.5). This
patch marks `__dynamic_cast` as `willreturn` to remove unused calls.
Fixes#77606.
With opaque pointers, `CreatePointerBitCastOrAddrSpaceCast` can be replaced with `CreateAddrSpaceCast`.
Replace or remove uses of `CreatePointerBitCastOrAddrSpaceCast`.
Opaque pointer cleanup effort.
Summary:
This patch reworks how we handle global constructors in OpenMP.
Previously, we emitted individual kernels that were all registered and
called individually. In order to provide more generic support, this
patch moves all handling of this to the target backend and the runtime
plugin. This has the benefit of supporting the GNU extensions for
constructors an destructors, removing a class of failures related to
shared library destruction order, and allows targets other than OpenMP
to use the same support without needing to change the frontend.
This is primarily done by calling kernels that the backend emits to
iterate a list of ctor / dtor functions. For x64, this is automatic and
we get it for free with the standard `dlopen` handling. For AMDGPU, we
emit `amdgcn.device.init` and `amdgcn.device.fini` functions which
handle everything atuomatically and simply need to be called. For NVPTX,
a patch https://github.com/llvm/llvm-project/pull/71549 provides the
kernels to call, but the runtime needs to set up the array manually by
pulling out all the known constructor / destructor functions.
One concession that this patch requires is the change that for GPU
targets in OpenMP offloading we will use `llvm.global_dtors` instead of
using `atexit`. This is because `atexit` is a separate runtime function
that does not mesh well with the handling we're trying to do here. This
should be equivalent in all cases except for cases where we would need
to destruct manually such as:
```
struct S { ~S() { foo(); } };
void foo() {
static S s;
}
```
However this is broken in many other ways on the GPU, so it is not
regressing any support, simply increasing the scope of what we can
handle.
This changes the handling of ctors / dtors. This patch now outputs a
information message regarding the deprecation if the old format is used.
This will be completely removed in a later release.
Depends on: https://github.com/llvm/llvm-project/pull/71549
This patch converts `ImplicitParamDecl::ImplicitParamKind` into a scoped enum at namespace scope, making it eligible for forward declaring. This is useful for `preferred_type` annotations on bit-fields.
Link: https://lists.llvm.org/pipermail/cfe-dev/2021-August/068740.html ("[Exception Handling] Could we mark __cxa_end_catch as nounwind conditionally?"
Link: https://github.com/llvm/llvm-project/issues/57375
A catch handler calls `__cxa_begin_catch` and `__cxa_end_catch`. For a catch-all
clause or a catch clause matching a record type, we:
* assume that the exception object may have a throwing destructor
* emit `invoke void @__cxa_end_catch` (as the call is not marked as the `nounwind` attribute).
* emit a landing pad to destroy local variables and call `_Unwind_Resume`
```
struct A { ~A(); };
struct B { int x; };
void opaque();
void foo() {
A a;
try { opaque(); } catch (...) { } // the exception object has an unknown type and may throw
try { opaque(); } catch (B b) { } // B::~B is nothrow, but we do not utilize this
}
```
Per C++ [dcl.fct.def.coroutine], a coroutine's function body implies a `catch (...)`.
Our code generation pessimizes even simple code, like:
```
UserFacing foo() {
A a;
opaque();
co_return;
// For `invoke void @__cxa_end_catch()`, the landing pad destroys the
// promise_type and deletes the coro frame.
}
```
Throwing destructors are typically discouraged. In many environments, the
destructors of exception objects are guaranteed to never throw, making our
conservative code generation approach seem wasteful.
Furthermore, throwing destructors tend not to work well in practice:
* GCC does not emit call site records for the region containing `__cxa_end_catch`. This has been a long time, since 2000.
* If a catch-all clause catches an exception object that throws, both GCC and Clang using libstdc++ leak the allocated exception object.
To avoid code generation pessimization, add an opt-in driver option
-fassume-nothrow-exception-dtor to assume that `__cxa_end_catch` calls have the
`nounwind` attribute. This implies that thrown exception objects' destructors
will never throw.
To detect misuses, diagnose throw expressions with a potentially-throwing
destructor. Technically, it is possible that a potentially-throwing destructor
never throws when called transitively by `__cxa_end_catch`, but these cases seem
rare enough to justify a relaxed mode.
Reviewed By: ChuanqiXu
Differential Revision: https://reviews.llvm.org/D108905
This patch introduces a new enumerator `Invalid = 0`, shifting other enumerators by +1. Contrary to how it might sound, this actually affirms status quo of how this enum is stored in `clang::Decl`:
```
/// If 0, we have not computed the linkage of this declaration.
/// Otherwise, it is the linkage + 1.
mutable unsigned CacheValidAndLinkage : 3;
```
This patch makes debuggers to not be mistaken about enumerator stored in this bit-field. It also converts `clang::Linkage` to a scoped enum.
- Update CodeGenTypeCache to use a single union for all pointers in
address space zero.
- Introduce a UnqualPtrTy in CodeGenTypeCache, and use that (for
example instead of llvm::PointerType::getUnqual) in some places.
- Drop some redundant bit/pointers casts from ptr to ptr.
Continuing the discussion in
https://discourse.llvm.org/t/codegen-layout-of-si-class-type-info-doesnt-match-the-actual-size/73274
Before we had this code:
@_ZTVN10__cxxabiv117__class_type_infoE = external global ptr
now we'll produce:
@_ZTVN10__cxxabiv117__class_type_infoE = external global [0 x ptr]
This is because we may not know the exact size of this data, and clang
issues gep inbounds with idx=2. Before, that gep would always result in
poison.
After https://reviews.llvm.org/D153092, for targets that use a non-default AS for globals, an "interesting" situation arises around typeid and its paired type, type_info:
- on the AST level, the type_info interface is defined with default / generic addresses, be it for function arguments, or for this;
- in IR, type_info values are globals, and thus pointers to type_info values are pointers to global
This leads to a mismatch between the function signature / formal type of the argument, and its actual type. Currently we try to handle such mismatches via `bitcast`, but that is wrong in this case, since an `ascast` is required. This patch ensures that iff the pointer to `type_info` points to a non-default AS, an ascast is inserted so as to match the `typeid` interface / return value type.
Reviewed by: yaxunl
Differential Revision: https://reviews.llvm.org/D157452
`__dynamic_cast` relies on `type_info`, which its signature assumed to be in the generic / default address space. This patch corrects the oversight (we know that `type_info` resides in the GlobalVar address space) and adds an associated test.
Reviewed By: yaxunl
Differential Revision: https://reviews.llvm.org/D155870
- When the destination is a final class type that does not derive from
the source type, the cast always fails and is now emitted as a null
pointer or call to __cxa_bad_cast.
- When the destination is a final class type that does derive from the
source type, emit a direct comparison against the corresponding base
class vptr value(s). There may be more than one such value in the case
of multiple inheritance; check them all.
For now, this is supported only for the Itanium ABI. I expect the same thing is
possible for the MS ABI too, but I don't know what guarantees are made about
vfptr uniqueness.
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D154658
All data structures and values associated with handling virtual functions / inheritance, as well as RTTI, are globals and thus can only reside in the global address space. This was not taken fully taken into account because for most targets, global & generic appear to coincide. However, on targets where global & generic ASes differ (e.g. AMDGPU), this was problematic, since it led to the generation of invalid bitcasts (which would trigger asserts in Debug) and less than optimal code. This patch does two things:
ensures that vtables, vptrs, vtts, typeinfo are generated in the right AS, and populated accordingly;
removes a bunch of bitcasts which look like left-overs from the typed ptr era.
Reviewed By: yxsamliu
Differential Revision: https://reviews.llvm.org/D153092
`CGBuilderTy::CreateElementBitCast()` no longer does what its name suggests.
Remove remaining in-tree uses by one of the following methods.
* drop the call entirely
* fold it to an `Address` construction
* replace it with `Address::withElementType()`
This is a NFC cleanup effort.
Reviewed By: barannikov88, nikic, jrtc27
Differential Revision: https://reviews.llvm.org/D154285
Partial progress towards replacing in-tree uses of `Type::getPointerTo()`.
This needs to be done before deprecating the API.
Reviewed By: nikic, barannikov88
Differential Revision: https://reviews.llvm.org/D152321
Correctly account for the fact that certain targets do not use the generic address space for the implicit VTT argument. This entails adjusting `ItaniumCXXABI::buildStructorSignature`, `ItaniumCXXABI::addImplicitStructorParams` and `ItaniumCXXABI::getImplicitConstructorArgs` to use the target's global variable address space. The associated test is temporarily marked `XFAIL` as additional fixes are needed.
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D150746
Reported by Coverity static analyzer tool:
Inside "ItaniumCXXABI.cpp" file, in <unnamed>::ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(clang::CodeGen::CodeGenFunction &, clang::Expr const *, clang::CodeGen::Address, llvm::Value *&, llvm::Value *, clang::MemberPointerType const *): Return value of function which returns null is dereferenced without checking.
//returned_null: getAs returns nullptr (checked 130 out of 156 times).
//var_assigned: Assigning: FPT = nullptr return value from getAs.
const FunctionProtoType *FPT =
MPT->getPointeeType()->getAs<FunctionProtoType>();
auto *RD =
cast<CXXRecordDecl>(MPT->getClass()->castAs<RecordType>()->getDecl());
// Dereference null return value (NULL_RETURNS)
//dereference: Dereferencing a pointer that might be nullptr FPT when calling arrangeCXXMethodType.
llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(
CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr));
This patch uses castAs instead of getAs which will assert if the type doesn't match.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D151054
This patch adds a new method setNoSanitizeMetadata() for Instruction, and use it in SanitizerMetadata and SanitizerCoverage.
Reviewed By: nickdesaulniers, MaskRay
Differential Revision: https://reviews.llvm.org/D150632
This patch introduces a new type __externref_t that denotes a WebAssembly opaque
reference type. It also implements builtin __builtin_wasm_ref_null_extern(),
that returns a null value of __externref_t. This lays the ground work
for further builtins and reference types.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D122215
As the diagnostic message shows, we should remove -fmodules-ts flag in
clang/llvm17. Since clang/llvm16 is already branched. We can remove the
depreacared flag now.
This patch introduces a new type __externref_t that denotes a WebAssembly opaque
reference type. It also implements builtin __builtin_wasm_ref_null_extern(),
that returns a null value of __externref_t. This lays the ground work
for further builtins and reference types.
Differential Revision: https://reviews.llvm.org/D122215
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated. The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.
This is part of an effort to migrate from llvm::Optional to
std::optional:
https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
Mixing LLVM and Clang address spaces can result in subtle bugs, and there
is no need for this hook to use the LLVM IR level address spaces.
Most of this change is just replacing zero with LangAS::Default,
but it also allows us to remove a few calls to getTargetAddressSpace().
This also removes a stale comment+workaround in
CGDebugInfo::CreatePointerLikeType(): ASTContext::getTypeSize() does
return the expected size for ReferenceType (and handles address spaces).
Differential Revision: https://reviews.llvm.org/D138295
When generating __clang_call_terminate use SetLLVMFunctionAttributes
to set the default function attributes, like we do for all the other
functions generated by clang. This fixes a problem where target
features from the command line weren't being applied to this function.
Differential Revision: https://reviews.llvm.org/D138679
Initialisation Guard Variables should take their DLL storage class
from the guarded variable. Otherwise, there will be a link error if
the compiler inlines a reference to the guard variable into another
module but that guard variable is not exported from the defining
module.
This is required for platforms such as PlayStation and
windows-itanium, that are aiming for source compatibility with MSVC
w.r.t. dllimport/export annotations, given Clang's existing design
which allows for inlining of a dllimport function as long as all the
variables/functions referenced are also marked dllimport.
A similar change exists for the MSVC ABI:
https://reviews.llvm.org/D4136.
I have added a run test for windows-itanium for this issue to the
build recipe: https://reviews.llvm.org/D88124.
Differential Revision: https://reviews.llvm.org/D138463
Previously, Itanium ABI guard variables were set after initialization was
complete for non-block declared variables with static and thread storage
duration. That resulted in initialization of such variables being restarted
in cases where the variable was referenced while it was still under
construction. Per C++20 [class.cdtor]p2, such references are permitted
(though the value obtained by such an access is unspecified). The late
initialization resulted in recursive reinitialization loops for cases like
this:
template<typename T>
struct ct {
struct mc {
mc() { ct<T>::smf(); }
void mf() const {}
};
thread_local static mc tlsdm;
static void smf() { tlsdm.mf(); }
};
template<typename T>
thread_local typename ct<T>::mc ct<T>::tlsdm;
int main() {
ct<int>::smf();
}
With this change, guard variables are set before initialization is started
so as to avoid such reinitialization loops.
Fixes https://github.com/llvm/llvm-project/issues/57828
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D135919
This switches everything to use the memory attribute proposed in
https://discourse.llvm.org/t/rfc-unify-memory-effect-attributes/65579.
The old argmemonly, inaccessiblememonly and inaccessiblemem_or_argmemonly
attributes are dropped. The readnone, readonly and writeonly attributes
are restricted to parameters only.
The old attributes are auto-upgraded both in bitcode and IR.
The bitcode upgrade is a policy requirement that has to be retained
indefinitely. The IR upgrade is mainly there so it's not necessary
to update all tests using memory attributes in this patch, which
is already large enough. We could drop that part after migrating
tests, or retain it longer term, to make it easier to import IR
from older LLVM versions.
High-level Function/CallBase APIs like doesNotAccessMemory() or
setDoesNotAccessMemory() are mapped transparently to the memory
attribute. Code that directly manipulates attributes (e.g. via
AttributeList) on the other hand needs to switch to working with
the memory attribute instead.
Differential Revision: https://reviews.llvm.org/D135780
Performing a load before calling __cxa_guard_acquire is supposed to be
an optimization, but it isn't much of one if we're just going to emit a
call to __atomic_load_1 instead. Instead, just skip the load, and
let __cxa_guard_acquire do whatever it wants.
(In practice, on such targets, the C++ library is just built with
threading turned off, so the result isn't actually threadsafe, but
there's not really anything clang can do about that.)
The alternative here is that we try to define some ABI for threadsafe
init that allows the speculative load without full atomics. Almost any
target without full atomics has a load that's s "atomic enough" for this
purpose. But it's not clear how we emit an "atomic enough" load in LLVM
IR, and there isn't any ABI document we can refer to.
Or I guess we could turn off -fthreadsafe-statics by default on
Cortex-M0, but that seems like it would be surprising.
Fixes https://github.com/llvm/llvm-project/issues/58184
Differential Revision: https://reviews.llvm.org/D135628
This option forces constructors and non-deleting destructors to return
`this` pointer in C++ ABI (except for Microsoft ABI, on which this flag
has no effect).
This is similar to ARM32, Apple ARM64, or Fuchsia C++ ABI, but can be
applied to any target triple.
Differential Revision: https://reviews.llvm.org/D119209
Full context in
https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=107017.
Instrumenting hwasan with globals results in a linker error under the
relative vtables abi:
```
ld.lld: error:
libunwind.cpp:(.rodata..L_ZTVN9libunwind12UnwindCursorINS_17LocalAddressSpaceENS_15Registers_arm64EEE.hwasan+0x8):
relocation R_AARCH64_PLT32 out of range: 6845471433603167792 is not in
[-2147483648, 2147483647]; references
libunwind::AbstractUnwindCursor::~AbstractUnwindCursor()
>>> defined in
libunwind/src/CMakeFiles/unwind_shared.dir/libunwind.cpp.obj
```
This is because the tag is included in the vtable address when
calculating the offset between the vtable and virtual function. A
temporary solution until we can resolve this is to just disable hwasan
instrumentation on relative vtables specifically, which can be done in
the frontend.
Differential Revision: https://reviews.llvm.org/D132425
Fixes https://github.com/llvm/llvm-project/issues/55804
The lexing order is already bookkept in DelayedCXXInitPosition but we
were not using it based on the wrong assumption that inline variable is
unordered. This patch fixes it by ordering entries in llvm.global_ctors
by orders in DelayedCXXInitPosition.
for llvm.global_ctors entries without a lexing order, ordering them by
the insertion order.
(This *mostly* orders the template instantiation in
https://reviews.llvm.org/D126341 intuitively, minus one tweak for which I'll
submit a separate patch.)
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D127233
This is successor for D125291. This revision would try to use
@llvm.threadlocal.address in clang to access TLS variable. The reason
why the OpenMP tests contains a lot of change is that they uses
utils/update_cc_test_checks.py to update their tests.
Reviewed By: nikic
Differential Revision: https://reviews.llvm.org/D129833
Turning on opaque pointers has uncovered an issue with WPD where we currently pattern match away `assume(type.test)` in WPD so that a later LTT doesn't resolve the type test to undef and introduce an `assume(false)`. The pattern matching can fail in cases where we transform two `assume(type.test)`s into `assume(phi(type.test.1, type.test.2))`.
Currently we create `assume(type.test)` for all virtual calls that might be devirtualized. This is to support `-Wl,--lto-whole-program-visibility`.
To prevent this, all virtual calls that may not be in the same LTO module instead use a new `llvm.public.type.test` intrinsic in place of the `llvm.type.test`. Then when we know if `-Wl,--lto-whole-program-visibility` is passed or not, we can either replace all `llvm.public.type.test` with `llvm.type.test`, or replace all `llvm.public.type.test` with `true`. This prevents WPD from trying to pattern match away `assume(type.test)` for public virtual calls when failing the pattern matching will result in miscompiles.
Reviewed By: tejohnson
Differential Revision: https://reviews.llvm.org/D128955
In preparation for the removal in D128719, this stops creating
insertvalue constant expressions (well, unless they are directly
used in LLVM IR).
Differential Revision: https://reviews.llvm.org/D128792
This removes the extractvalue constant expression, as part of
https://discourse.llvm.org/t/rfc-remove-most-constant-expressions/63179.
extractvalue is already not supported in bitcode, so we do not need
to worry about bitcode auto-upgrade.
Uses of ConstantExpr::getExtractValue() should be replaced with
IRBuilder::CreateExtractValue() (if the fact that the result is
constant is not important) or ConstantFoldExtractValueInstruction()
(if it is). Though for this particular case, it is also possible
and usually preferable to use getAggregateElement() instead.
The C API function LLVMConstExtractValue() is removed, as the
underlying constant expression no longer exists. Instead,
LLVMBuildExtractValue() should be used (which will constant fold
or create an instruction). Depending on the use-case,
LLVMGetAggregateElement() may also be used instead.
Differential Revision: https://reviews.llvm.org/D125795
The option mdefault-visibility-export-mapping is created to allow
mapping default visibility to an explicit shared library export
(e.g. dllexport). Exactly how and if this is manifested is target
dependent (since it depends on how they map dllexport in the IR).
Three values are provided for the option:
* none: the default and behavior without the option, no additional export linkage information is created.
* explicit: add the export for entities with explict default visibility from the source, including RTTI
* all: add the export for all entities with default visibility
This option is useful for targets which do not export symbols as part of
their usual default linkage behaviour (e.g. AIX), such targets
traditionally specified such information in external files (e.g. export
lists), but this mapping allows them to use the visibility information
typically used for this purpose on other (e.g. ELF) platforms.
This relands commit: 8c8a2679a20f621994fa904bcfc68775e7345edc
with fixes for the compile time and assert problems that were reported
by:
* making shouldMapVisibilityToDLLExport inline and provide an early return
in the case where no mapping is in effect (aka non-AIX platforms)
* don't try to export RTTI types which we will give internal linkage to
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D126340
This caused assertions, see comment on the code review:
llvm/clang/lib/AST/Decl.cpp:1510:
clang::LinkageInfo clang::LinkageComputer::getLVForDecl(const clang::NamedDecl *, clang::LVComputationKind):
Assertion `D->getCachedLinkage() == LV.getLinkage()' failed.
> The option mdefault-visibility-export-mapping is created to allow
> mapping default visibility to an explicit shared library export
> (e.g. dllexport). Exactly how and if this is manifested is target
> dependent (since it depends on how they map dllexport in the IR).
>
> Three values are provided for the option:
>
> * none: the default and behavior without the option, no additional export linkage information is created.
> * explicit: add the export for entities with explict default visibility from the source, including RTTI
> * all: add the export for all entities with default visibility
>
> This option is useful for targets which do not export symbols as part of
> their usual default linkage behaviour (e.g. AIX), such targets
> traditionally specified such information in external files (e.g. export
> lists), but this mapping allows them to use the visibility information
> typically used for this purpose on other (e.g. ELF) platforms.
>
> Reviewed By: MaskRay
>
> Differential Revision: https://reviews.llvm.org/D126340
This reverts commit 8c8a2679a20f621994fa904bcfc68775e7345edc.
The option mdefault-visibility-export-mapping is created to allow
mapping default visibility to an explicit shared library export
(e.g. dllexport). Exactly how and if this is manifested is target
dependent (since it depends on how they map dllexport in the IR).
Three values are provided for the option:
* none: the default and behavior without the option, no additional export linkage information is created.
* explicit: add the export for entities with explict default visibility from the source, including RTTI
* all: add the export for all entities with default visibility
This option is useful for targets which do not export symbols as part of
their usual default linkage behaviour (e.g. AIX), such targets
traditionally specified such information in external files (e.g. export
lists), but this mapping allows them to use the visibility information
typically used for this purpose on other (e.g. ELF) platforms.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D126340