Merge llvm, clang, compiler-rt, libc++, lld, and lldb release_80 branch
r354130, resolve conflicts, and bump version numbers.
This commit is contained in:
commit
640dd76f2c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/clang800-import/; revision=344177
@ -25,7 +25,7 @@ struct ioctl_desc {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
const unsigned ioctl_table_max = 1202;
|
||||
const unsigned ioctl_table_max = 1200;
|
||||
static ioctl_desc ioctl_table[ioctl_table_max];
|
||||
static unsigned ioctl_table_size = 0;
|
||||
|
||||
@ -298,9 +298,6 @@ static void ioctl_table_fill() {
|
||||
_(IRFRAMETTY_GET_DEVICE, WRITE, sizeof(unsigned int));
|
||||
_(IRFRAMETTY_GET_DONGLE, WRITE, sizeof(unsigned int));
|
||||
_(IRFRAMETTY_SET_DONGLE, READ, sizeof(unsigned int));
|
||||
/* Entries from file: dev/isa/satlinkio.h */
|
||||
_(SATIORESET, NONE, 0);
|
||||
_(SATIOGID, WRITE, struct_satlink_id_sz);
|
||||
/* Entries from file: dev/isa/isvio.h */
|
||||
_(ISV_CMD, READWRITE, struct_isv_cmd_sz);
|
||||
/* Entries from file: dev/isa/wtreg.h */
|
||||
@ -649,8 +646,8 @@ static void ioctl_table_fill() {
|
||||
_(SPKRTUNE, NONE, 0);
|
||||
_(SPKRGETVOL, WRITE, sizeof(unsigned int));
|
||||
_(SPKRSETVOL, READ, sizeof(unsigned int));
|
||||
/* Entries from file: dev/nvmm/nvmm_ioctl.h */
|
||||
#if 0 /* WIP */
|
||||
/* Entries from file: dev/nvmm/nvmm_ioctl.h */
|
||||
_(NVMM_IOC_CAPABILITY, WRITE, struct_nvmm_ioc_capability_sz);
|
||||
_(NVMM_IOC_MACHINE_CREATE, READWRITE, struct_nvmm_ioc_machine_create_sz);
|
||||
_(NVMM_IOC_MACHINE_DESTROY, READ, struct_nvmm_ioc_machine_destroy_sz);
|
||||
@ -659,7 +656,7 @@ static void ioctl_table_fill() {
|
||||
_(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz);
|
||||
_(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz);
|
||||
_(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz);
|
||||
_(NVMM_IOC_VCPU_INJECT, READWRITE, struct_nvmm_ioc_vcpu_inject_sz);
|
||||
_(NVMM_IOC_VCPU_INJECT, READ, struct_nvmm_ioc_vcpu_inject_sz);
|
||||
_(NVMM_IOC_VCPU_RUN, READWRITE, struct_nvmm_ioc_vcpu_run_sz);
|
||||
_(NVMM_IOC_GPA_MAP, READ, struct_nvmm_ioc_gpa_map_sz);
|
||||
_(NVMM_IOC_GPA_UNMAP, READ, struct_nvmm_ioc_gpa_unmap_sz);
|
||||
|
@ -122,7 +122,6 @@
|
||||
#include <dev/ic/nvmeio.h>
|
||||
#include <dev/ir/irdaio.h>
|
||||
#include <dev/isa/isvio.h>
|
||||
#include <dev/isa/satlinkio.h>
|
||||
#include <dev/isa/wtreg.h>
|
||||
#include <dev/iscsi/iscsi_ioctl.h>
|
||||
#include <dev/nvmm/nvmm_ioctl.h>
|
||||
@ -639,7 +638,6 @@ unsigned struct_rf_recon_req_sz = sizeof(rf_recon_req);
|
||||
unsigned struct_rio_conf_sz = sizeof(rio_conf);
|
||||
unsigned struct_rio_interface_sz = sizeof(rio_interface);
|
||||
unsigned struct_rio_stats_sz = sizeof(rio_stats);
|
||||
unsigned struct_satlink_id_sz = sizeof(satlink_id);
|
||||
unsigned struct_scan_io_sz = sizeof(scan_io);
|
||||
unsigned struct_scbusaccel_args_sz = sizeof(scbusaccel_args);
|
||||
unsigned struct_scbusiodetach_args_sz = sizeof(scbusiodetach_args);
|
||||
@ -1105,9 +1103,6 @@ unsigned IOCTL_IRDA_GET_TURNAROUNDMASK = IRDA_GET_TURNAROUNDMASK;
|
||||
unsigned IOCTL_IRFRAMETTY_GET_DEVICE = IRFRAMETTY_GET_DEVICE;
|
||||
unsigned IOCTL_IRFRAMETTY_GET_DONGLE = IRFRAMETTY_GET_DONGLE;
|
||||
unsigned IOCTL_IRFRAMETTY_SET_DONGLE = IRFRAMETTY_SET_DONGLE;
|
||||
unsigned IOCTL_SATIORESET = SATIORESET;
|
||||
unsigned IOCTL_SATIOGID = SATIOGID;
|
||||
unsigned IOCTL_SATIOSBUFSIZE = SATIOSBUFSIZE;
|
||||
unsigned IOCTL_ISV_CMD = ISV_CMD;
|
||||
unsigned IOCTL_WTQICMD = WTQICMD;
|
||||
unsigned IOCTL_ISCSI_GET_VERSION = ISCSI_GET_VERSION;
|
||||
|
@ -803,7 +803,6 @@ extern unsigned struct_rf_recon_req_sz;
|
||||
extern unsigned struct_rio_conf_sz;
|
||||
extern unsigned struct_rio_interface_sz;
|
||||
extern unsigned struct_rio_stats_sz;
|
||||
extern unsigned struct_satlink_id_sz;
|
||||
extern unsigned struct_scan_io_sz;
|
||||
extern unsigned struct_scbusaccel_args_sz;
|
||||
extern unsigned struct_scbusiodetach_args_sz;
|
||||
@ -1266,9 +1265,6 @@ extern unsigned IOCTL_IRDA_GET_TURNAROUNDMASK;
|
||||
extern unsigned IOCTL_IRFRAMETTY_GET_DEVICE;
|
||||
extern unsigned IOCTL_IRFRAMETTY_GET_DONGLE;
|
||||
extern unsigned IOCTL_IRFRAMETTY_SET_DONGLE;
|
||||
extern unsigned IOCTL_SATIORESET;
|
||||
extern unsigned IOCTL_SATIOGID;
|
||||
extern unsigned IOCTL_SATIOSBUFSIZE;
|
||||
extern unsigned IOCTL_ISV_CMD;
|
||||
extern unsigned IOCTL_WTQICMD;
|
||||
extern unsigned IOCTL_ISCSI_GET_VERSION;
|
||||
|
@ -165,7 +165,8 @@ struct WasmSymbolInfo {
|
||||
StringRef Name;
|
||||
uint8_t Kind;
|
||||
uint32_t Flags;
|
||||
StringRef Module; // For undefined symbols the module name of the import
|
||||
StringRef ImportModule; // For undefined symbols the module of the import
|
||||
StringRef ImportName; // For undefined symbols the name of the import
|
||||
union {
|
||||
// For function or global symbols, the index in function or global index
|
||||
// space.
|
||||
@ -284,6 +285,7 @@ const unsigned WASM_SYMBOL_BINDING_LOCAL = 0x2;
|
||||
const unsigned WASM_SYMBOL_VISIBILITY_DEFAULT = 0x0;
|
||||
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
|
||||
const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
|
||||
const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
|
||||
|
||||
#define WASM_RELOC(name, value) name = value,
|
||||
|
||||
|
@ -19,7 +19,8 @@ class MCSymbolWasm : public MCSymbol {
|
||||
bool IsWeak = false;
|
||||
bool IsHidden = false;
|
||||
bool IsComdat = false;
|
||||
std::string ModuleName;
|
||||
Optional<std::string> ImportModule;
|
||||
Optional<std::string> ImportName;
|
||||
wasm::WasmSignature *Signature = nullptr;
|
||||
Optional<wasm::WasmGlobalType> GlobalType;
|
||||
Optional<wasm::WasmEventType> EventType;
|
||||
@ -32,7 +33,7 @@ class MCSymbolWasm : public MCSymbol {
|
||||
// Use a module name of "env" for now, for compatibility with existing tools.
|
||||
// This is temporary, and may change, as the ABI is not yet stable.
|
||||
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
|
||||
: MCSymbol(SymbolKindWasm, Name, isTemporary), ModuleName("env") {}
|
||||
: MCSymbol(SymbolKindWasm, Name, isTemporary) {}
|
||||
static bool classof(const MCSymbol *S) { return S->isWasm(); }
|
||||
|
||||
const MCExpr *getSize() const { return SymbolSize; }
|
||||
@ -55,8 +56,21 @@ class MCSymbolWasm : public MCSymbol {
|
||||
bool isComdat() const { return IsComdat; }
|
||||
void setComdat(bool isComdat) { IsComdat = isComdat; }
|
||||
|
||||
const StringRef getModuleName() const { return ModuleName; }
|
||||
void setModuleName(StringRef Name) { ModuleName = Name; }
|
||||
const StringRef getImportModule() const {
|
||||
if (ImportModule.hasValue()) {
|
||||
return ImportModule.getValue();
|
||||
}
|
||||
return "env";
|
||||
}
|
||||
void setImportModule(StringRef Name) { ImportModule = Name; }
|
||||
|
||||
const StringRef getImportName() const {
|
||||
if (ImportName.hasValue()) {
|
||||
return ImportName.getValue();
|
||||
}
|
||||
return getName();
|
||||
}
|
||||
void setImportName(StringRef Name) { ImportName = Name; }
|
||||
|
||||
const wasm::WasmSignature *getSignature() const { return Signature; }
|
||||
void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
|
||||
|
@ -161,25 +161,66 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
|
||||
}
|
||||
|
||||
if (T.isOSWindows() && !T.isOSCygMing()) {
|
||||
// Win32 does not support long double
|
||||
// XXX: The earliest documentation available at the moment is for VS2015/VC19:
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/floating-point-support?view=vs-2015
|
||||
// XXX: In order to use an MSVCRT older than VC19,
|
||||
// the specific library version must be explicit in the target triple,
|
||||
// e.g., x86_64-pc-windows-msvc18.
|
||||
bool hasPartialC99 = true;
|
||||
if (T.isKnownWindowsMSVCEnvironment()) {
|
||||
unsigned Major, Minor, Micro;
|
||||
T.getEnvironmentVersion(Major, Minor, Micro);
|
||||
hasPartialC99 = (Major == 0 || Major >= 19);
|
||||
}
|
||||
|
||||
// Latest targets support C89 math functions, in part.
|
||||
bool isARM = (T.getArch() == Triple::aarch64 ||
|
||||
T.getArch() == Triple::arm);
|
||||
bool hasPartialFloat = (isARM ||
|
||||
T.getArch() == Triple::x86_64);
|
||||
|
||||
// Win32 does not support float C89 math functions, in general.
|
||||
if (!hasPartialFloat) {
|
||||
TLI.setUnavailable(LibFunc_acosf);
|
||||
TLI.setUnavailable(LibFunc_asinf);
|
||||
TLI.setUnavailable(LibFunc_atan2f);
|
||||
TLI.setUnavailable(LibFunc_atanf);
|
||||
TLI.setUnavailable(LibFunc_ceilf);
|
||||
TLI.setUnavailable(LibFunc_cosf);
|
||||
TLI.setUnavailable(LibFunc_coshf);
|
||||
TLI.setUnavailable(LibFunc_expf);
|
||||
TLI.setUnavailable(LibFunc_floorf);
|
||||
TLI.setUnavailable(LibFunc_fmodf);
|
||||
TLI.setUnavailable(LibFunc_log10f);
|
||||
TLI.setUnavailable(LibFunc_logf);
|
||||
TLI.setUnavailable(LibFunc_modff);
|
||||
TLI.setUnavailable(LibFunc_powf);
|
||||
TLI.setUnavailable(LibFunc_sinf);
|
||||
TLI.setUnavailable(LibFunc_sinhf);
|
||||
TLI.setUnavailable(LibFunc_sqrtf);
|
||||
TLI.setUnavailable(LibFunc_tanf);
|
||||
TLI.setUnavailable(LibFunc_tanhf);
|
||||
}
|
||||
if (!isARM)
|
||||
TLI.setUnavailable(LibFunc_fabsf);
|
||||
TLI.setUnavailable(LibFunc_frexpf);
|
||||
TLI.setUnavailable(LibFunc_ldexpf);
|
||||
|
||||
// Win32 does not support long double C89 math functions.
|
||||
TLI.setUnavailable(LibFunc_acosl);
|
||||
TLI.setUnavailable(LibFunc_asinl);
|
||||
TLI.setUnavailable(LibFunc_atanl);
|
||||
TLI.setUnavailable(LibFunc_atan2l);
|
||||
TLI.setUnavailable(LibFunc_atanl);
|
||||
TLI.setUnavailable(LibFunc_ceill);
|
||||
TLI.setUnavailable(LibFunc_copysignl);
|
||||
TLI.setUnavailable(LibFunc_cosl);
|
||||
TLI.setUnavailable(LibFunc_coshl);
|
||||
TLI.setUnavailable(LibFunc_expl);
|
||||
TLI.setUnavailable(LibFunc_fabsf); // Win32 and Win64 both lack fabsf
|
||||
TLI.setUnavailable(LibFunc_fabsl);
|
||||
TLI.setUnavailable(LibFunc_floorl);
|
||||
TLI.setUnavailable(LibFunc_fmaxl);
|
||||
TLI.setUnavailable(LibFunc_fminl);
|
||||
TLI.setUnavailable(LibFunc_fmodl);
|
||||
TLI.setUnavailable(LibFunc_frexpl);
|
||||
TLI.setUnavailable(LibFunc_ldexpf);
|
||||
TLI.setUnavailable(LibFunc_ldexpl);
|
||||
TLI.setUnavailable(LibFunc_log10l);
|
||||
TLI.setUnavailable(LibFunc_logl);
|
||||
TLI.setUnavailable(LibFunc_modfl);
|
||||
TLI.setUnavailable(LibFunc_powl);
|
||||
@ -189,81 +230,66 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
|
||||
TLI.setUnavailable(LibFunc_tanl);
|
||||
TLI.setUnavailable(LibFunc_tanhl);
|
||||
|
||||
// Win32 only has C89 math
|
||||
// Win32 does not fully support C99 math functions.
|
||||
if (!hasPartialC99) {
|
||||
TLI.setUnavailable(LibFunc_acosh);
|
||||
TLI.setUnavailable(LibFunc_acoshf);
|
||||
TLI.setUnavailable(LibFunc_acoshl);
|
||||
TLI.setUnavailable(LibFunc_asinh);
|
||||
TLI.setUnavailable(LibFunc_asinhf);
|
||||
TLI.setUnavailable(LibFunc_asinhl);
|
||||
TLI.setUnavailable(LibFunc_atanh);
|
||||
TLI.setUnavailable(LibFunc_atanhf);
|
||||
TLI.setUnavailable(LibFunc_atanhl);
|
||||
TLI.setUnavailable(LibFunc_cabs);
|
||||
TLI.setAvailableWithName(LibFunc_cabs, "_cabs");
|
||||
TLI.setUnavailable(LibFunc_cabsf);
|
||||
TLI.setUnavailable(LibFunc_cabsl);
|
||||
TLI.setUnavailable(LibFunc_cbrt);
|
||||
TLI.setUnavailable(LibFunc_cbrtf);
|
||||
TLI.setUnavailable(LibFunc_cbrtl);
|
||||
TLI.setAvailableWithName(LibFunc_copysign, "_copysign");
|
||||
TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf");
|
||||
TLI.setUnavailable(LibFunc_exp2);
|
||||
TLI.setUnavailable(LibFunc_exp2f);
|
||||
TLI.setUnavailable(LibFunc_exp2l);
|
||||
TLI.setUnavailable(LibFunc_expm1);
|
||||
TLI.setUnavailable(LibFunc_expm1f);
|
||||
TLI.setUnavailable(LibFunc_expm1l);
|
||||
TLI.setUnavailable(LibFunc_log2);
|
||||
TLI.setUnavailable(LibFunc_log2f);
|
||||
TLI.setUnavailable(LibFunc_log2l);
|
||||
TLI.setUnavailable(LibFunc_fmax);
|
||||
TLI.setUnavailable(LibFunc_fmaxf);
|
||||
TLI.setUnavailable(LibFunc_fmin);
|
||||
TLI.setUnavailable(LibFunc_fminf);
|
||||
TLI.setUnavailable(LibFunc_log1p);
|
||||
TLI.setUnavailable(LibFunc_log1pf);
|
||||
TLI.setUnavailable(LibFunc_log1pl);
|
||||
TLI.setUnavailable(LibFunc_logb);
|
||||
TLI.setUnavailable(LibFunc_log2);
|
||||
TLI.setUnavailable(LibFunc_log2f);
|
||||
TLI.setAvailableWithName(LibFunc_logb, "_logb");
|
||||
if (hasPartialFloat)
|
||||
TLI.setAvailableWithName(LibFunc_logbf, "_logbf");
|
||||
else
|
||||
TLI.setUnavailable(LibFunc_logbf);
|
||||
TLI.setUnavailable(LibFunc_logbl);
|
||||
TLI.setUnavailable(LibFunc_nearbyint);
|
||||
TLI.setUnavailable(LibFunc_nearbyintf);
|
||||
TLI.setUnavailable(LibFunc_nearbyintl);
|
||||
TLI.setUnavailable(LibFunc_rint);
|
||||
TLI.setUnavailable(LibFunc_rintf);
|
||||
TLI.setUnavailable(LibFunc_rintl);
|
||||
TLI.setUnavailable(LibFunc_round);
|
||||
TLI.setUnavailable(LibFunc_roundf);
|
||||
TLI.setUnavailable(LibFunc_roundl);
|
||||
TLI.setUnavailable(LibFunc_trunc);
|
||||
TLI.setUnavailable(LibFunc_truncf);
|
||||
TLI.setUnavailable(LibFunc_truncl);
|
||||
|
||||
// Win32 provides some C99 math with mangled names
|
||||
TLI.setAvailableWithName(LibFunc_copysign, "_copysign");
|
||||
|
||||
if (T.getArch() == Triple::x86) {
|
||||
// Win32 on x86 implements single-precision math functions as macros
|
||||
TLI.setUnavailable(LibFunc_acosf);
|
||||
TLI.setUnavailable(LibFunc_asinf);
|
||||
TLI.setUnavailable(LibFunc_atanf);
|
||||
TLI.setUnavailable(LibFunc_atan2f);
|
||||
TLI.setUnavailable(LibFunc_ceilf);
|
||||
TLI.setUnavailable(LibFunc_copysignf);
|
||||
TLI.setUnavailable(LibFunc_cosf);
|
||||
TLI.setUnavailable(LibFunc_coshf);
|
||||
TLI.setUnavailable(LibFunc_expf);
|
||||
TLI.setUnavailable(LibFunc_floorf);
|
||||
TLI.setUnavailable(LibFunc_fminf);
|
||||
TLI.setUnavailable(LibFunc_fmaxf);
|
||||
TLI.setUnavailable(LibFunc_fmodf);
|
||||
TLI.setUnavailable(LibFunc_logf);
|
||||
TLI.setUnavailable(LibFunc_log10f);
|
||||
TLI.setUnavailable(LibFunc_modff);
|
||||
TLI.setUnavailable(LibFunc_powf);
|
||||
TLI.setUnavailable(LibFunc_sinf);
|
||||
TLI.setUnavailable(LibFunc_sinhf);
|
||||
TLI.setUnavailable(LibFunc_sqrtf);
|
||||
TLI.setUnavailable(LibFunc_tanf);
|
||||
TLI.setUnavailable(LibFunc_tanhf);
|
||||
}
|
||||
|
||||
// Win32 does *not* provide these functions, but they are
|
||||
// generally available on POSIX-compliant systems:
|
||||
// Win32 does not support long double C99 math functions.
|
||||
TLI.setUnavailable(LibFunc_acoshl);
|
||||
TLI.setUnavailable(LibFunc_asinhl);
|
||||
TLI.setUnavailable(LibFunc_atanhl);
|
||||
TLI.setUnavailable(LibFunc_cabsl);
|
||||
TLI.setUnavailable(LibFunc_cbrtl);
|
||||
TLI.setUnavailable(LibFunc_copysignl);
|
||||
TLI.setUnavailable(LibFunc_exp2l);
|
||||
TLI.setUnavailable(LibFunc_expm1l);
|
||||
TLI.setUnavailable(LibFunc_fmaxl);
|
||||
TLI.setUnavailable(LibFunc_fminl);
|
||||
TLI.setUnavailable(LibFunc_log1pl);
|
||||
TLI.setUnavailable(LibFunc_log2l);
|
||||
TLI.setUnavailable(LibFunc_logbl);
|
||||
TLI.setUnavailable(LibFunc_nearbyintl);
|
||||
TLI.setUnavailable(LibFunc_rintl);
|
||||
TLI.setUnavailable(LibFunc_roundl);
|
||||
TLI.setUnavailable(LibFunc_truncl);
|
||||
|
||||
// Win32 does not support these functions, but
|
||||
// they are generally available on POSIX-compliant systems.
|
||||
TLI.setUnavailable(LibFunc_access);
|
||||
TLI.setUnavailable(LibFunc_bcmp);
|
||||
TLI.setUnavailable(LibFunc_bcopy);
|
||||
@ -318,12 +344,6 @@ static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T,
|
||||
TLI.setUnavailable(LibFunc_utime);
|
||||
TLI.setUnavailable(LibFunc_utimes);
|
||||
TLI.setUnavailable(LibFunc_write);
|
||||
|
||||
// Win32 does *not* provide provide these functions, but they are
|
||||
// specified by C99:
|
||||
TLI.setUnavailable(LibFunc_atoll);
|
||||
TLI.setUnavailable(LibFunc_frexpf);
|
||||
TLI.setUnavailable(LibFunc_llabs);
|
||||
}
|
||||
|
||||
switch (T.getOS()) {
|
||||
|
@ -559,6 +559,11 @@ static void AttemptToFoldSymbolOffsetDifference(
|
||||
if (Asm->isThumbFunc(&SA))
|
||||
Addend |= 1;
|
||||
|
||||
// If symbol is labeled as micromips, we set low-bit to ensure
|
||||
// correct offset in .gcc_except_table
|
||||
if (Asm->getBackend().isMicroMips(&SA))
|
||||
Addend |= 1;
|
||||
|
||||
// Clear the symbol expr pointers to indicate we have folded these
|
||||
// operands.
|
||||
A = B = nullptr;
|
||||
|
@ -3364,9 +3364,10 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
|
||||
}
|
||||
|
||||
if (FileNumber == -1) {
|
||||
if (!getContext().getAsmInfo()->hasSingleParameterDotFile())
|
||||
return Error(DirectiveLoc,
|
||||
"target does not support '.file' without a number");
|
||||
// Ignore the directive if there is no number and the target doesn't support
|
||||
// numberless .file directives. This allows some portability of assembler
|
||||
// between different object file formats.
|
||||
if (getContext().getAsmInfo()->hasSingleParameterDotFile())
|
||||
getStreamer().EmitFileDirective(Filename);
|
||||
} else {
|
||||
// In case there is a -g option as well as debug info from directive .file,
|
||||
|
@ -982,7 +982,8 @@ void WasmObjectWriter::writeLinkingMetaDataSection(
|
||||
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
|
||||
case wasm::WASM_SYMBOL_TYPE_EVENT:
|
||||
encodeULEB128(Sym.ElementIndex, W.OS);
|
||||
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
|
||||
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
|
||||
(Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
writeString(Sym.Name);
|
||||
break;
|
||||
case wasm::WASM_SYMBOL_TYPE_DATA:
|
||||
@ -1162,8 +1163,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
MCSymbolWasm *MemorySym =
|
||||
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__linear_memory"));
|
||||
wasm::WasmImport MemImport;
|
||||
MemImport.Module = MemorySym->getModuleName();
|
||||
MemImport.Field = MemorySym->getName();
|
||||
MemImport.Module = MemorySym->getImportModule();
|
||||
MemImport.Field = MemorySym->getImportName();
|
||||
MemImport.Kind = wasm::WASM_EXTERNAL_MEMORY;
|
||||
Imports.push_back(MemImport);
|
||||
|
||||
@ -1173,8 +1174,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
MCSymbolWasm *TableSym =
|
||||
cast<MCSymbolWasm>(Ctx.getOrCreateSymbol("__indirect_function_table"));
|
||||
wasm::WasmImport TableImport;
|
||||
TableImport.Module = TableSym->getModuleName();
|
||||
TableImport.Field = TableSym->getName();
|
||||
TableImport.Module = TableSym->getImportModule();
|
||||
TableImport.Field = TableSym->getImportName();
|
||||
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
|
||||
TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
|
||||
Imports.push_back(TableImport);
|
||||
@ -1200,8 +1201,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
if (!WS.isDefined() && !WS.isComdat()) {
|
||||
if (WS.isFunction()) {
|
||||
wasm::WasmImport Import;
|
||||
Import.Module = WS.getModuleName();
|
||||
Import.Field = WS.getName();
|
||||
Import.Module = WS.getImportModule();
|
||||
Import.Field = WS.getImportName();
|
||||
Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
|
||||
Import.SigIndex = getFunctionType(WS);
|
||||
Imports.push_back(Import);
|
||||
@ -1211,8 +1212,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
report_fatal_error("undefined global symbol cannot be weak");
|
||||
|
||||
wasm::WasmImport Import;
|
||||
Import.Module = WS.getModuleName();
|
||||
Import.Field = WS.getName();
|
||||
Import.Module = WS.getImportModule();
|
||||
Import.Field = WS.getImportName();
|
||||
Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
|
||||
Import.Global = WS.getGlobalType();
|
||||
Imports.push_back(Import);
|
||||
@ -1222,8 +1223,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
report_fatal_error("undefined event symbol cannot be weak");
|
||||
|
||||
wasm::WasmImport Import;
|
||||
Import.Module = WS.getModuleName();
|
||||
Import.Field = WS.getName();
|
||||
Import.Module = WS.getImportModule();
|
||||
Import.Field = WS.getImportName();
|
||||
Import.Kind = wasm::WASM_EXTERNAL_EVENT;
|
||||
Import.Event.Attribute = wasm::WASM_EVENT_ATTRIBUTE_EXCEPTION;
|
||||
Import.Event.SigIndex = getEventType(WS);
|
||||
@ -1448,6 +1449,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm,
|
||||
Flags |= wasm::WASM_SYMBOL_BINDING_LOCAL;
|
||||
if (WS.isUndefined())
|
||||
Flags |= wasm::WASM_SYMBOL_UNDEFINED;
|
||||
if (WS.getName() != WS.getImportName())
|
||||
Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME;
|
||||
|
||||
wasm::WasmSymbolInfo Info;
|
||||
Info.Name = WS.getName();
|
||||
|
@ -505,9 +505,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
Function.SymbolName = Info.Name;
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
|
||||
Signature = &Signatures[Import.SigIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.Name = Import.Field;
|
||||
Info.Module = Import.Module;
|
||||
Signature = &Signatures[Import.SigIndex];
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -530,8 +534,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
Global.SymbolName = Info.Name;
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.Name = Import.Field;
|
||||
GlobalType = &Import.Global;
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -585,9 +594,14 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
|
||||
|
||||
} else {
|
||||
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
|
||||
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
|
||||
Info.Name = readString(Ctx);
|
||||
else
|
||||
Info.Name = Import.Field;
|
||||
EventType = &Import.Event;
|
||||
Signature = &Signatures[EventType->SigIndex];
|
||||
Info.Name = Import.Field;
|
||||
Info.ImportName = Import.Field;
|
||||
Info.ImportModule = Import.Module;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -202,6 +202,12 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
|
||||
char buf[len];
|
||||
::pthread_getname_np(::pthread_self(), buf, len);
|
||||
|
||||
Name.append(buf, buf + strlen(buf));
|
||||
#elif defined(__OpenBSD__)
|
||||
constexpr uint32_t len = get_max_thread_name_length_impl();
|
||||
char buf[len];
|
||||
::pthread_get_name_np(::pthread_self(), buf, len);
|
||||
|
||||
Name.append(buf, buf + strlen(buf));
|
||||
#elif defined(__linux__)
|
||||
#if HAVE_PTHREAD_GETNAME_NP
|
||||
|
@ -2292,6 +2292,31 @@ void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB,
|
||||
}
|
||||
}
|
||||
|
||||
void AArch64InstrInfo::copyGPRRegTuple(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
DebugLoc DL, unsigned DestReg,
|
||||
unsigned SrcReg, bool KillSrc,
|
||||
unsigned Opcode, unsigned ZeroReg,
|
||||
llvm::ArrayRef<unsigned> Indices) const {
|
||||
const TargetRegisterInfo *TRI = &getRegisterInfo();
|
||||
unsigned NumRegs = Indices.size();
|
||||
|
||||
#ifndef NDEBUG
|
||||
uint16_t DestEncoding = TRI->getEncodingValue(DestReg);
|
||||
uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg);
|
||||
assert(DestEncoding % NumRegs == 0 && SrcEncoding % NumRegs == 0 &&
|
||||
"GPR reg sequences should not be able to overlap");
|
||||
#endif
|
||||
|
||||
for (unsigned SubReg = 0; SubReg != NumRegs; ++SubReg) {
|
||||
const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode));
|
||||
AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI);
|
||||
MIB.addReg(ZeroReg);
|
||||
AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI);
|
||||
MIB.addImm(0);
|
||||
}
|
||||
}
|
||||
|
||||
void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock::iterator I,
|
||||
const DebugLoc &DL, unsigned DestReg,
|
||||
@ -2431,6 +2456,22 @@ void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
||||
return;
|
||||
}
|
||||
|
||||
if (AArch64::XSeqPairsClassRegClass.contains(DestReg) &&
|
||||
AArch64::XSeqPairsClassRegClass.contains(SrcReg)) {
|
||||
static const unsigned Indices[] = {AArch64::sube64, AArch64::subo64};
|
||||
copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRXrs,
|
||||
AArch64::XZR, Indices);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AArch64::WSeqPairsClassRegClass.contains(DestReg) &&
|
||||
AArch64::WSeqPairsClassRegClass.contains(SrcReg)) {
|
||||
static const unsigned Indices[] = {AArch64::sube32, AArch64::subo32};
|
||||
copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRWrs,
|
||||
AArch64::WZR, Indices);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AArch64::FPR128RegClass.contains(DestReg) &&
|
||||
AArch64::FPR128RegClass.contains(SrcReg)) {
|
||||
if (Subtarget.hasNEON()) {
|
||||
|
@ -122,6 +122,10 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
|
||||
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc, unsigned Opcode,
|
||||
llvm::ArrayRef<unsigned> Indices) const;
|
||||
void copyGPRRegTuple(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
DebugLoc DL, unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc, unsigned Opcode, unsigned ZeroReg,
|
||||
llvm::ArrayRef<unsigned> Indices) const;
|
||||
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
|
||||
bool KillSrc) const override;
|
||||
|
@ -650,9 +650,11 @@ def FPR128Op : RegisterOperand<FPR128, "printOperand"> {
|
||||
|
||||
|
||||
def WSeqPairs : RegisterTuples<[sube32, subo32],
|
||||
[(rotl GPR32, 0), (rotl GPR32, 1)]>;
|
||||
[(decimate (rotl GPR32, 0), 2),
|
||||
(decimate (rotl GPR32, 1), 2)]>;
|
||||
def XSeqPairs : RegisterTuples<[sube64, subo64],
|
||||
[(rotl GPR64, 0), (rotl GPR64, 1)]>;
|
||||
[(decimate (rotl GPR64, 0), 2),
|
||||
(decimate (rotl GPR64, 1), 2)]>;
|
||||
|
||||
def WSeqPairsClass : RegisterClass<"AArch64", [untyped], 32,
|
||||
(add WSeqPairs)>{
|
||||
|
@ -1779,8 +1779,8 @@ static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst,
|
||||
if (RegNo & 0x1)
|
||||
return Fail;
|
||||
|
||||
unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo);
|
||||
Inst.addOperand(MCOperand::createReg(Register));
|
||||
unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2);
|
||||
Inst.addOperand(MCOperand::createReg(Reg));
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
@ -5618,45 +5618,45 @@ SDValue SystemZTargetLowering::combineBSWAP(
|
||||
static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) {
|
||||
// We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
|
||||
// set by the CCReg instruction using the CCValid / CCMask masks,
|
||||
// If the CCReg instruction is itself a (ICMP (SELECT_CCMASK)) testing
|
||||
// the condition code set by some other instruction, see whether we
|
||||
// can directly use that condition code.
|
||||
bool Invert = false;
|
||||
// If the CCReg instruction is itself a ICMP testing the condition
|
||||
// code set by some other instruction, see whether we can directly
|
||||
// use that condition code.
|
||||
|
||||
// Verify that we have an appropriate mask for a EQ or NE comparison.
|
||||
// Verify that we have an ICMP against some constant.
|
||||
if (CCValid != SystemZ::CCMASK_ICMP)
|
||||
return false;
|
||||
auto *ICmp = CCReg.getNode();
|
||||
if (ICmp->getOpcode() != SystemZISD::ICMP)
|
||||
return false;
|
||||
auto *CompareLHS = ICmp->getOperand(0).getNode();
|
||||
auto *CompareRHS = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
|
||||
if (!CompareRHS)
|
||||
return false;
|
||||
|
||||
// Optimize the case where CompareLHS is a SELECT_CCMASK.
|
||||
if (CompareLHS->getOpcode() == SystemZISD::SELECT_CCMASK) {
|
||||
// Verify that we have an appropriate mask for a EQ or NE comparison.
|
||||
bool Invert = false;
|
||||
if (CCMask == SystemZ::CCMASK_CMP_NE)
|
||||
Invert = !Invert;
|
||||
else if (CCMask != SystemZ::CCMASK_CMP_EQ)
|
||||
return false;
|
||||
|
||||
// Verify that we have an ICMP that is the user of a SELECT_CCMASK.
|
||||
SDNode *ICmp = CCReg.getNode();
|
||||
if (ICmp->getOpcode() != SystemZISD::ICMP)
|
||||
return false;
|
||||
SDNode *Select = ICmp->getOperand(0).getNode();
|
||||
if (Select->getOpcode() != SystemZISD::SELECT_CCMASK)
|
||||
return false;
|
||||
|
||||
// Verify that the ICMP compares against one of select values.
|
||||
auto *CompareVal = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
|
||||
if (!CompareVal)
|
||||
return false;
|
||||
auto *TrueVal = dyn_cast<ConstantSDNode>(Select->getOperand(0));
|
||||
auto *TrueVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(0));
|
||||
if (!TrueVal)
|
||||
return false;
|
||||
auto *FalseVal = dyn_cast<ConstantSDNode>(Select->getOperand(1));
|
||||
auto *FalseVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(1));
|
||||
if (!FalseVal)
|
||||
return false;
|
||||
if (CompareVal->getZExtValue() == FalseVal->getZExtValue())
|
||||
if (CompareRHS->getZExtValue() == FalseVal->getZExtValue())
|
||||
Invert = !Invert;
|
||||
else if (CompareVal->getZExtValue() != TrueVal->getZExtValue())
|
||||
else if (CompareRHS->getZExtValue() != TrueVal->getZExtValue())
|
||||
return false;
|
||||
|
||||
// Compute the effective CC mask for the new branch or select.
|
||||
auto *NewCCValid = dyn_cast<ConstantSDNode>(Select->getOperand(2));
|
||||
auto *NewCCMask = dyn_cast<ConstantSDNode>(Select->getOperand(3));
|
||||
auto *NewCCValid = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(2));
|
||||
auto *NewCCMask = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(3));
|
||||
if (!NewCCValid || !NewCCMask)
|
||||
return false;
|
||||
CCValid = NewCCValid->getZExtValue();
|
||||
@ -5665,10 +5665,51 @@ static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) {
|
||||
CCMask ^= CCValid;
|
||||
|
||||
// Return the updated CCReg link.
|
||||
CCReg = Select->getOperand(4);
|
||||
CCReg = CompareLHS->getOperand(4);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Optimize the case where CompareRHS is (SRA (SHL (IPM))).
|
||||
if (CompareLHS->getOpcode() == ISD::SRA) {
|
||||
auto *SRACount = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(1));
|
||||
if (!SRACount || SRACount->getZExtValue() != 30)
|
||||
return false;
|
||||
auto *SHL = CompareLHS->getOperand(0).getNode();
|
||||
if (SHL->getOpcode() != ISD::SHL)
|
||||
return false;
|
||||
auto *SHLCount = dyn_cast<ConstantSDNode>(SHL->getOperand(1));
|
||||
if (!SHLCount || SHLCount->getZExtValue() != 30 - SystemZ::IPM_CC)
|
||||
return false;
|
||||
auto *IPM = SHL->getOperand(0).getNode();
|
||||
if (IPM->getOpcode() != SystemZISD::IPM)
|
||||
return false;
|
||||
|
||||
// Avoid introducing CC spills (because SRA would clobber CC).
|
||||
if (!CompareLHS->hasOneUse())
|
||||
return false;
|
||||
// Verify that the ICMP compares against zero.
|
||||
if (CompareRHS->getZExtValue() != 0)
|
||||
return false;
|
||||
|
||||
// Compute the effective CC mask for the new branch or select.
|
||||
switch (CCMask) {
|
||||
case SystemZ::CCMASK_CMP_EQ: break;
|
||||
case SystemZ::CCMASK_CMP_NE: break;
|
||||
case SystemZ::CCMASK_CMP_LT: CCMask = SystemZ::CCMASK_CMP_GT; break;
|
||||
case SystemZ::CCMASK_CMP_GT: CCMask = SystemZ::CCMASK_CMP_LT; break;
|
||||
case SystemZ::CCMASK_CMP_LE: CCMask = SystemZ::CCMASK_CMP_GE; break;
|
||||
case SystemZ::CCMASK_CMP_GE: CCMask = SystemZ::CCMASK_CMP_LE; break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
// Return the updated CCReg link.
|
||||
CCReg = IPM->getOperand(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::combineBR_CCMASK(
|
||||
SDNode *N, DAGCombinerInfo &DCI) const {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
|
@ -557,80 +557,6 @@ bool SystemZInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If Reg is a virtual register, return its definition, otherwise return null.
|
||||
static MachineInstr *getDef(unsigned Reg,
|
||||
const MachineRegisterInfo *MRI) {
|
||||
if (TargetRegisterInfo::isPhysicalRegister(Reg))
|
||||
return nullptr;
|
||||
return MRI->getUniqueVRegDef(Reg);
|
||||
}
|
||||
|
||||
// Return true if MI is a shift of type Opcode by Imm bits.
|
||||
static bool isShift(MachineInstr *MI, unsigned Opcode, int64_t Imm) {
|
||||
return (MI->getOpcode() == Opcode &&
|
||||
!MI->getOperand(2).getReg() &&
|
||||
MI->getOperand(3).getImm() == Imm);
|
||||
}
|
||||
|
||||
// If the destination of MI has no uses, delete it as dead.
|
||||
static void eraseIfDead(MachineInstr *MI, const MachineRegisterInfo *MRI) {
|
||||
if (MRI->use_nodbg_empty(MI->getOperand(0).getReg()))
|
||||
MI->eraseFromParent();
|
||||
}
|
||||
|
||||
// Compare compares SrcReg against zero. Check whether SrcReg contains
|
||||
// the result of an IPM sequence whose input CC survives until Compare,
|
||||
// and whether Compare is therefore redundant. Delete it and return
|
||||
// true if so.
|
||||
static bool removeIPMBasedCompare(MachineInstr &Compare, unsigned SrcReg,
|
||||
const MachineRegisterInfo *MRI,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
MachineInstr *LGFR = nullptr;
|
||||
MachineInstr *RLL = getDef(SrcReg, MRI);
|
||||
if (RLL && RLL->getOpcode() == SystemZ::LGFR) {
|
||||
LGFR = RLL;
|
||||
RLL = getDef(LGFR->getOperand(1).getReg(), MRI);
|
||||
}
|
||||
if (!RLL || !isShift(RLL, SystemZ::RLL, 31))
|
||||
return false;
|
||||
|
||||
MachineInstr *SRL = getDef(RLL->getOperand(1).getReg(), MRI);
|
||||
if (!SRL || !isShift(SRL, SystemZ::SRL, SystemZ::IPM_CC))
|
||||
return false;
|
||||
|
||||
MachineInstr *IPM = getDef(SRL->getOperand(1).getReg(), MRI);
|
||||
if (!IPM || IPM->getOpcode() != SystemZ::IPM)
|
||||
return false;
|
||||
|
||||
// Check that there are no assignments to CC between the IPM and Compare,
|
||||
if (IPM->getParent() != Compare.getParent())
|
||||
return false;
|
||||
MachineBasicBlock::iterator MBBI = IPM, MBBE = Compare.getIterator();
|
||||
for (++MBBI; MBBI != MBBE; ++MBBI) {
|
||||
MachineInstr &MI = *MBBI;
|
||||
if (MI.modifiesRegister(SystemZ::CC, TRI))
|
||||
return false;
|
||||
}
|
||||
|
||||
Compare.eraseFromParent();
|
||||
if (LGFR)
|
||||
eraseIfDead(LGFR, MRI);
|
||||
eraseIfDead(RLL, MRI);
|
||||
eraseIfDead(SRL, MRI);
|
||||
eraseIfDead(IPM, MRI);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SystemZInstrInfo::optimizeCompareInstr(
|
||||
MachineInstr &Compare, unsigned SrcReg, unsigned SrcReg2, int Mask,
|
||||
int Value, const MachineRegisterInfo *MRI) const {
|
||||
assert(!SrcReg2 && "Only optimizing constant comparisons so far");
|
||||
bool IsLogical = (Compare.getDesc().TSFlags & SystemZII::IsLogical) != 0;
|
||||
return Value == 0 && !IsLogical &&
|
||||
removeIPMBasedCompare(Compare, SrcReg, MRI, &RI);
|
||||
}
|
||||
|
||||
bool SystemZInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
|
||||
ArrayRef<MachineOperand> Pred,
|
||||
unsigned TrueReg, unsigned FalseReg,
|
||||
|
@ -208,9 +208,6 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
|
||||
int *BytesAdded = nullptr) const override;
|
||||
bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
|
||||
unsigned &SrcReg2, int &Mask, int &Value) const override;
|
||||
bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
|
||||
unsigned SrcReg2, int Mask, int Value,
|
||||
const MachineRegisterInfo *MRI) const override;
|
||||
bool canInsertSelect(const MachineBasicBlock&, ArrayRef<MachineOperand> Cond,
|
||||
unsigned, unsigned, int&, int&, int&) const override;
|
||||
void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
|
||||
|
@ -164,17 +164,17 @@ static SDValue emitCLC(SelectionDAG &DAG, const SDLoc &DL, SDValue Chain,
|
||||
}
|
||||
|
||||
// Convert the current CC value into an integer that is 0 if CC == 0,
|
||||
// less than zero if CC == 1 and greater than zero if CC >= 2.
|
||||
// greater than zero if CC == 1 and less than zero if CC >= 2.
|
||||
// The sequence starts with IPM, which puts CC into bits 29 and 28
|
||||
// of an integer and clears bits 30 and 31.
|
||||
static SDValue addIPMSequence(const SDLoc &DL, SDValue CCReg,
|
||||
SelectionDAG &DAG) {
|
||||
SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, CCReg);
|
||||
SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i32, IPM,
|
||||
DAG.getConstant(SystemZ::IPM_CC, DL, MVT::i32));
|
||||
SDValue ROTL = DAG.getNode(ISD::ROTL, DL, MVT::i32, SRL,
|
||||
DAG.getConstant(31, DL, MVT::i32));
|
||||
return ROTL;
|
||||
SDValue SHL = DAG.getNode(ISD::SHL, DL, MVT::i32, IPM,
|
||||
DAG.getConstant(30 - SystemZ::IPM_CC, DL, MVT::i32));
|
||||
SDValue SRA = DAG.getNode(ISD::SRA, DL, MVT::i32, SHL,
|
||||
DAG.getConstant(30, DL, MVT::i32));
|
||||
return SRA;
|
||||
}
|
||||
|
||||
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp(
|
||||
@ -184,7 +184,8 @@ std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForMemcmp(
|
||||
if (auto *CSize = dyn_cast<ConstantSDNode>(Size)) {
|
||||
uint64_t Bytes = CSize->getZExtValue();
|
||||
assert(Bytes > 0 && "Caller should have handled 0-size case");
|
||||
SDValue CCReg = emitCLC(DAG, DL, Chain, Src1, Src2, Bytes);
|
||||
// Swap operands to invert CC == 1 vs. CC == 2 cases.
|
||||
SDValue CCReg = emitCLC(DAG, DL, Chain, Src2, Src1, Bytes);
|
||||
Chain = CCReg.getValue(1);
|
||||
return std::make_pair(addIPMSequence(DL, CCReg, DAG), Chain);
|
||||
}
|
||||
@ -232,7 +233,8 @@ std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::EmitTargetCodeForStrcmp(
|
||||
SDValue Src2, MachinePointerInfo Op1PtrInfo,
|
||||
MachinePointerInfo Op2PtrInfo) const {
|
||||
SDVTList VTs = DAG.getVTList(Src1.getValueType(), MVT::i32, MVT::Other);
|
||||
SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src1, Src2,
|
||||
// Swap operands to invert CC == 1 vs. CC == 2 cases.
|
||||
SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src2, Src1,
|
||||
DAG.getConstant(0, DL, MVT::i32));
|
||||
SDValue CCReg = Unused.getValue(1);
|
||||
Chain = Unused.getValue(2);
|
||||
|
@ -113,8 +113,15 @@ void WebAssemblyTargetAsmStreamer::emitEventType(const MCSymbolWasm *Sym) {
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitImportModule(const MCSymbolWasm *Sym,
|
||||
StringRef ModuleName) {
|
||||
OS << "\t.import_module\t" << Sym->getName() << ", " << ModuleName << '\n';
|
||||
StringRef ImportModule) {
|
||||
OS << "\t.import_module\t" << Sym->getName() << ", "
|
||||
<< ImportModule << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitImportName(const MCSymbolWasm *Sym,
|
||||
StringRef ImportName) {
|
||||
OS << "\t.import_name\t" << Sym->getName() << ", "
|
||||
<< ImportName << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
|
||||
|
@ -45,7 +45,10 @@ class WebAssemblyTargetStreamer : public MCTargetStreamer {
|
||||
virtual void emitEventType(const MCSymbolWasm *Sym) = 0;
|
||||
/// .import_module
|
||||
virtual void emitImportModule(const MCSymbolWasm *Sym,
|
||||
StringRef ModuleName) = 0;
|
||||
StringRef ImportModule) = 0;
|
||||
/// .import_name
|
||||
virtual void emitImportName(const MCSymbolWasm *Sym,
|
||||
StringRef ImportName) = 0;
|
||||
|
||||
protected:
|
||||
void emitValueType(wasm::ValType Type);
|
||||
@ -67,7 +70,8 @@ class WebAssemblyTargetAsmStreamer final : public WebAssemblyTargetStreamer {
|
||||
void emitIndIdx(const MCExpr *Value) override;
|
||||
void emitGlobalType(const MCSymbolWasm *Sym) override;
|
||||
void emitEventType(const MCSymbolWasm *Sym) override;
|
||||
void emitImportModule(const MCSymbolWasm *Sym, StringRef ModuleName) override;
|
||||
void emitImportModule(const MCSymbolWasm *Sym, StringRef ImportModule) override;
|
||||
void emitImportName(const MCSymbolWasm *Sym, StringRef ImportName) override;
|
||||
};
|
||||
|
||||
/// This part is for Wasm object output
|
||||
@ -82,7 +86,9 @@ class WebAssemblyTargetWasmStreamer final : public WebAssemblyTargetStreamer {
|
||||
void emitGlobalType(const MCSymbolWasm *Sym) override {}
|
||||
void emitEventType(const MCSymbolWasm *Sym) override {}
|
||||
void emitImportModule(const MCSymbolWasm *Sym,
|
||||
StringRef ModuleName) override {}
|
||||
StringRef ImportModule) override {}
|
||||
void emitImportName(const MCSymbolWasm *Sym,
|
||||
StringRef ImportName) override {}
|
||||
};
|
||||
|
||||
/// This part is for null output
|
||||
@ -98,6 +104,7 @@ class WebAssemblyTargetNullStreamer final : public WebAssemblyTargetStreamer {
|
||||
void emitGlobalType(const MCSymbolWasm *) override {}
|
||||
void emitEventType(const MCSymbolWasm *) override {}
|
||||
void emitImportModule(const MCSymbolWasm *, StringRef) override {}
|
||||
void emitImportName(const MCSymbolWasm *, StringRef) override {}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -111,9 +111,16 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||
F.hasFnAttribute("wasm-import-module")) {
|
||||
StringRef Name =
|
||||
F.getFnAttribute("wasm-import-module").getValueAsString();
|
||||
Sym->setModuleName(Name);
|
||||
Sym->setImportModule(Name);
|
||||
getTargetStreamer()->emitImportModule(Sym, Name);
|
||||
}
|
||||
if (TM.getTargetTriple().isOSBinFormatWasm() &&
|
||||
F.hasFnAttribute("wasm-import-name")) {
|
||||
StringRef Name =
|
||||
F.getFnAttribute("wasm-import-name").getValueAsString();
|
||||
Sym->setImportName(Name);
|
||||
getTargetStreamer()->emitImportName(Sym, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,6 @@ using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "wasm-fix-function-bitcasts"
|
||||
|
||||
static cl::opt<bool>
|
||||
TemporaryWorkarounds("wasm-temporary-workarounds",
|
||||
cl::desc("Apply certain temporary workarounds"),
|
||||
cl::init(true), cl::Hidden);
|
||||
|
||||
namespace {
|
||||
class FixFunctionBitcasts final : public ModulePass {
|
||||
StringRef getPassName() const override {
|
||||
@ -227,6 +222,17 @@ static Function *CreateWrapper(Function *F, FunctionType *Ty) {
|
||||
return Wrapper;
|
||||
}
|
||||
|
||||
// Test whether a main function with type FuncTy should be rewritten to have
|
||||
// type MainTy.
|
||||
bool shouldFixMainFunction(FunctionType *FuncTy, FunctionType *MainTy) {
|
||||
// Only fix the main function if it's the standard zero-arg form. That way,
|
||||
// the standard cases will work as expected, and users will see signature
|
||||
// mismatches from the linker for non-standard cases.
|
||||
return FuncTy->getReturnType() == MainTy->getReturnType() &&
|
||||
FuncTy->getNumParams() == 0 &&
|
||||
!FuncTy->isVarArg();
|
||||
}
|
||||
|
||||
bool FixFunctionBitcasts::runOnModule(Module &M) {
|
||||
LLVM_DEBUG(dbgs() << "********** Fix Function Bitcasts **********\n");
|
||||
|
||||
@ -243,14 +249,14 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
|
||||
// "int main(int argc, char *argv[])", create an artificial call with it
|
||||
// bitcasted to that type so that we generate a wrapper for it, so that
|
||||
// the C runtime can call it.
|
||||
if (!TemporaryWorkarounds && !F.isDeclaration() && F.getName() == "main") {
|
||||
if (F.getName() == "main") {
|
||||
Main = &F;
|
||||
LLVMContext &C = M.getContext();
|
||||
Type *MainArgTys[] = {Type::getInt32Ty(C),
|
||||
PointerType::get(Type::getInt8PtrTy(C), 0)};
|
||||
FunctionType *MainTy = FunctionType::get(Type::getInt32Ty(C), MainArgTys,
|
||||
/*isVarArg=*/false);
|
||||
if (F.getFunctionType() != MainTy) {
|
||||
if (shouldFixMainFunction(F.getFunctionType(), MainTy)) {
|
||||
LLVM_DEBUG(dbgs() << "Found `main` function with incorrect type: "
|
||||
<< *F.getFunctionType() << "\n");
|
||||
Value *Args[] = {UndefValue::get(MainArgTys[0]),
|
||||
@ -298,12 +304,18 @@ bool FixFunctionBitcasts::runOnModule(Module &M) {
|
||||
Main->setName("__original_main");
|
||||
Function *MainWrapper =
|
||||
cast<Function>(CallMain->getCalledValue()->stripPointerCasts());
|
||||
delete CallMain;
|
||||
if (Main->isDeclaration()) {
|
||||
// The wrapper is not needed in this case as we don't need to export
|
||||
// it to anyone else.
|
||||
MainWrapper->eraseFromParent();
|
||||
} else {
|
||||
// Otherwise give the wrapper the same linkage as the original main
|
||||
// function, so that it can be called from the same places.
|
||||
MainWrapper->setName("main");
|
||||
MainWrapper->setLinkage(Main->getLinkage());
|
||||
MainWrapper->setVisibility(Main->getVisibility());
|
||||
Main->setLinkage(Function::PrivateLinkage);
|
||||
Main->setVisibility(Function::DefaultVisibility);
|
||||
delete CallMain;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -321,6 +321,7 @@ static cl::opt<unsigned long long> ClOriginBase("msan-origin-base",
|
||||
cl::desc("Define custom MSan OriginBase"),
|
||||
cl::Hidden, cl::init(0));
|
||||
|
||||
static const char *const kMsanModuleCtorName = "msan.module_ctor";
|
||||
static const char *const kMsanInitName = "__msan_init";
|
||||
|
||||
namespace {
|
||||
@ -586,6 +587,8 @@ class MemorySanitizer {
|
||||
|
||||
/// An empty volatile inline asm that prevents callback merge.
|
||||
InlineAsm *EmptyAsm;
|
||||
|
||||
Function *MsanCtorFunction;
|
||||
};
|
||||
|
||||
/// A legacy function pass for msan instrumentation.
|
||||
@ -839,6 +842,8 @@ Value *MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore, int size) {
|
||||
}
|
||||
|
||||
/// Module-level initialization.
|
||||
///
|
||||
/// inserts a call to __msan_init to the module's constructor list.
|
||||
void MemorySanitizer::initializeModule(Module &M) {
|
||||
auto &DL = M.getDataLayout();
|
||||
|
||||
@ -913,7 +918,22 @@ void MemorySanitizer::initializeModule(Module &M) {
|
||||
OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
|
||||
|
||||
if (!CompileKernel) {
|
||||
getOrCreateInitFunction(M, kMsanInitName);
|
||||
std::tie(MsanCtorFunction, std::ignore) =
|
||||
getOrCreateSanitizerCtorAndInitFunctions(
|
||||
M, kMsanModuleCtorName, kMsanInitName,
|
||||
/*InitArgTypes=*/{},
|
||||
/*InitArgs=*/{},
|
||||
// This callback is invoked when the functions are created the first
|
||||
// time. Hook them into the global ctors list in that case:
|
||||
[&](Function *Ctor, Function *) {
|
||||
if (!ClWithComdat) {
|
||||
appendToGlobalCtors(M, Ctor, 0);
|
||||
return;
|
||||
}
|
||||
Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
|
||||
Ctor->setComdat(MsanCtorComdat);
|
||||
appendToGlobalCtors(M, Ctor, 0, Ctor);
|
||||
});
|
||||
|
||||
if (TrackOrigins)
|
||||
M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
|
||||
@ -4458,6 +4478,8 @@ static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
|
||||
}
|
||||
|
||||
bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
|
||||
if (!CompileKernel && (&F == MsanCtorFunction))
|
||||
return false;
|
||||
MemorySanitizerVisitor Visitor(F, *this, TLI);
|
||||
|
||||
// Clear out readonly/readnone attributes.
|
||||
|
@ -103,13 +103,6 @@ def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
|
||||
[{S->isInstanceMethod()}],
|
||||
"Objective-C instance methods">;
|
||||
|
||||
def ObjCInterfaceDeclInitMethod : SubsetSubject<ObjCMethod,
|
||||
[{S->getMethodFamily() == OMF_init &&
|
||||
(isa<ObjCInterfaceDecl>(S->getDeclContext()) ||
|
||||
(isa<ObjCCategoryDecl>(S->getDeclContext()) &&
|
||||
cast<ObjCCategoryDecl>(S->getDeclContext())->IsClassExtension()))}],
|
||||
"init methods of interface or class extension declarations">;
|
||||
|
||||
def Struct : SubsetSubject<Record,
|
||||
[{!S->isUnion()}], "structs">;
|
||||
|
||||
@ -329,6 +322,7 @@ def TargetMSP430 : TargetArch<["msp430"]>;
|
||||
def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
|
||||
def TargetX86 : TargetArch<["x86"]>;
|
||||
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
|
||||
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
|
||||
def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
|
||||
let OSes = ["Win32"];
|
||||
}
|
||||
@ -1500,6 +1494,22 @@ def AMDGPUNumVGPR : InheritableAttr {
|
||||
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
|
||||
}
|
||||
|
||||
def WebAssemblyImportModule : InheritableAttr,
|
||||
TargetSpecificAttr<TargetWebAssembly> {
|
||||
let Spellings = [Clang<"import_module">];
|
||||
let Args = [StringArgument<"ImportModule">];
|
||||
let Documentation = [WebAssemblyImportModuleDocs];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
}
|
||||
|
||||
def WebAssemblyImportName : InheritableAttr,
|
||||
TargetSpecificAttr<TargetWebAssembly> {
|
||||
let Spellings = [Clang<"import_name">];
|
||||
let Args = [StringArgument<"ImportName">];
|
||||
let Documentation = [WebAssemblyImportNameDocs];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
}
|
||||
|
||||
def NoSplitStack : InheritableAttr {
|
||||
let Spellings = [GCC<"no_split_stack">];
|
||||
let Subjects = SubjectList<[Function], ErrorDiag>;
|
||||
@ -1745,7 +1755,7 @@ def ObjCExplicitProtocolImpl : InheritableAttr {
|
||||
|
||||
def ObjCDesignatedInitializer : Attr {
|
||||
let Spellings = [Clang<"objc_designated_initializer">];
|
||||
let Subjects = SubjectList<[ObjCInterfaceDeclInitMethod], ErrorDiag>;
|
||||
let Subjects = SubjectList<[ObjCMethod], ErrorDiag>;
|
||||
let Documentation = [Undocumented];
|
||||
}
|
||||
|
||||
|
@ -3652,6 +3652,39 @@ definition (
|
||||
For more information see
|
||||
`gcc documentation <https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Microsoft-Windows-Variable-Attributes.html>`_
|
||||
or `msvc documentation <https://docs.microsoft.com/pl-pl/cpp/cpp/selectany>`_.
|
||||
}]; }
|
||||
|
||||
def WebAssemblyImportModuleDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((import_module(<module_name>)))``
|
||||
attribute for the WebAssembly target. This attribute may be attached to a
|
||||
function declaration, where it modifies how the symbol is to be imported
|
||||
within the WebAssembly linking environment.
|
||||
|
||||
WebAssembly imports use a two-level namespace scheme, consisting of a module
|
||||
name, which typically identifies a module from which to import, and a field
|
||||
name, which typically identifies a field from that module to import. By
|
||||
default, module names for C/C++ symbols are assigned automatically by the
|
||||
linker. This attribute can be used to override the default behavior, and
|
||||
reuqest a specific module name be used instead.
|
||||
}];
|
||||
}
|
||||
|
||||
def WebAssemblyImportNameDocs : Documentation {
|
||||
let Category = DocCatFunction;
|
||||
let Content = [{
|
||||
Clang supports the ``__attribute__((import_name(<name>)))``
|
||||
attribute for the WebAssembly target. This attribute may be attached to a
|
||||
function declaration, where it modifies how the symbol is to be imported
|
||||
within the WebAssembly linking environment.
|
||||
|
||||
WebAssembly imports use a two-level namespace scheme, consisting of a module
|
||||
name, which typically identifies a module from which to import, and a field
|
||||
name, which typically identifies a field from that module to import. By
|
||||
default, field names for C/C++ symbols are the same as their C/C++ symbol
|
||||
names. This attribute can be used to override the default behavior, and
|
||||
reuqest a specific field name be used instead.
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,8 @@ TARGET_HEADER_BUILTIN(_InterlockedDecrement64_rel, "LLiLLiD*", "nh", "intrin.h",
|
||||
|
||||
TARGET_HEADER_BUILTIN(_ReadWriteBarrier, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(__getReg, "ULLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_ReadStatusReg, "ii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_WriteStatusReg, "vii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_ReadStatusReg, "LLii", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_WriteStatusReg, "viLLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
TARGET_HEADER_BUILTIN(_AddressOfReturnAddress, "v*", "nh", "intrin.h", ALL_MS_LANGUAGES, "")
|
||||
|
||||
#undef BUILTIN
|
||||
|
@ -3460,6 +3460,9 @@ def warn_objc_secondary_init_missing_init_call : Warning<
|
||||
def warn_objc_implementation_missing_designated_init_override : Warning<
|
||||
"method override for the designated initializer of the superclass %objcinstance0 not found">,
|
||||
InGroup<ObjCDesignatedInit>;
|
||||
def err_designated_init_attr_non_init : Error<
|
||||
"'objc_designated_initializer' attribute only applies to init methods "
|
||||
"of interface or class extension declarations">;
|
||||
|
||||
// objc_bridge attribute diagnostics.
|
||||
def err_objc_attr_not_id : Error<
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H
|
||||
#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H
|
||||
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
|
||||
namespace clang {
|
||||
@ -42,25 +43,29 @@ class OpenCLOptions {
|
||||
|
||||
// Is supported as either an extension or an (optional) core feature for
|
||||
// OpenCL version \p CLVer.
|
||||
bool isSupported(llvm::StringRef Ext, unsigned CLVer) const {
|
||||
bool isSupported(llvm::StringRef Ext, LangOptions LO) const {
|
||||
// In C++ mode all extensions should work at least as in v2.0.
|
||||
auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
|
||||
auto I = OptMap.find(Ext)->getValue();
|
||||
return I.Supported && I.Avail <= CLVer;
|
||||
}
|
||||
|
||||
// Is supported (optional) OpenCL core features for OpenCL version \p CLVer.
|
||||
// For supported extension, return false.
|
||||
bool isSupportedCore(llvm::StringRef Ext, unsigned CLVer) const {
|
||||
bool isSupportedCore(llvm::StringRef Ext, LangOptions LO) const {
|
||||
// In C++ mode all extensions should work at least as in v2.0.
|
||||
auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
|
||||
auto I = OptMap.find(Ext)->getValue();
|
||||
return I.Supported && I.Avail <= CLVer &&
|
||||
I.Core != ~0U && CLVer >= I.Core;
|
||||
return I.Supported && I.Avail <= CLVer && I.Core != ~0U && CLVer >= I.Core;
|
||||
}
|
||||
|
||||
// Is supported OpenCL extension for OpenCL version \p CLVer.
|
||||
// For supported (optional) core feature, return false.
|
||||
bool isSupportedExtension(llvm::StringRef Ext, unsigned CLVer) const {
|
||||
bool isSupportedExtension(llvm::StringRef Ext, LangOptions LO) const {
|
||||
// In C++ mode all extensions should work at least as in v2.0.
|
||||
auto CLVer = LO.OpenCLCPlusPlus ? 200 : LO.OpenCLVersion;
|
||||
auto I = OptMap.find(Ext)->getValue();
|
||||
return I.Supported && I.Avail <= CLVer &&
|
||||
(I.Core == ~0U || CLVer < I.Core);
|
||||
return I.Supported && I.Avail <= CLVer && (I.Core == ~0U || CLVer < I.Core);
|
||||
}
|
||||
|
||||
void enable(llvm::StringRef Ext, bool V = true) {
|
||||
@ -122,10 +127,10 @@ class OpenCLOptions {
|
||||
I->second.Enabled = false;
|
||||
}
|
||||
|
||||
void enableSupportedCore(unsigned CLVer) {
|
||||
for (llvm::StringMap<Info>::iterator I = OptMap.begin(),
|
||||
E = OptMap.end(); I != E; ++I)
|
||||
if (isSupportedCore(I->getKey(), CLVer))
|
||||
void enableSupportedCore(LangOptions LO) {
|
||||
for (llvm::StringMap<Info>::iterator I = OptMap.begin(), E = OptMap.end();
|
||||
I != E; ++I)
|
||||
if (isSupportedCore(I->getKey(), LO))
|
||||
I->second.Enabled = true;
|
||||
}
|
||||
|
||||
|
@ -552,9 +552,9 @@ def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">,
|
||||
HelpText<"Compile CUDA code for both host and device (default). Has no "
|
||||
"effect on non-CUDA compilations.">;
|
||||
def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOption]>,
|
||||
HelpText<"Include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
|
||||
HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
|
||||
def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>,
|
||||
HelpText<"Do not include PTX for the follwing GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
|
||||
HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">;
|
||||
def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>,
|
||||
HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">;
|
||||
def hip_link : Flag<["--"], "hip-link">,
|
||||
|
@ -360,11 +360,6 @@ class Parser : public CodeCompletionHandler {
|
||||
/// just a regular sub-expression.
|
||||
SourceLocation ExprStatementTokLoc;
|
||||
|
||||
/// Tests whether an expression value is discarded based on token lookahead.
|
||||
/// It will return true if the lexer is currently processing the })
|
||||
/// terminating a GNU statement expression and false otherwise.
|
||||
bool isExprValueDiscarded();
|
||||
|
||||
public:
|
||||
Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies);
|
||||
~Parser() override;
|
||||
|
@ -1369,7 +1369,6 @@ class Sema {
|
||||
void PopCompoundScope();
|
||||
|
||||
sema::CompoundScopeInfo &getCurCompoundScope() const;
|
||||
bool isCurCompoundStmtAStmtExpr() const;
|
||||
|
||||
bool hasAnyUnrecoverableErrorsInThisFunction() const;
|
||||
|
||||
@ -3690,8 +3689,7 @@ class Sema {
|
||||
return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation());
|
||||
}
|
||||
FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) {
|
||||
return FullExprArg(
|
||||
ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get());
|
||||
return FullExprArg(ActOnFinishFullExpr(Arg, CC).get());
|
||||
}
|
||||
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) {
|
||||
ExprResult FE =
|
||||
@ -3700,7 +3698,7 @@ class Sema {
|
||||
return FullExprArg(FE.get());
|
||||
}
|
||||
|
||||
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true);
|
||||
StmtResult ActOnExprStmt(ExprResult Arg);
|
||||
StmtResult ActOnExprStmtError();
|
||||
|
||||
StmtResult ActOnNullStmt(SourceLocation SemiLoc,
|
||||
@ -5346,12 +5344,13 @@ class Sema {
|
||||
CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary,
|
||||
bool BoundToLvalueReference);
|
||||
|
||||
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) {
|
||||
return ActOnFinishFullExpr(
|
||||
Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue);
|
||||
ExprResult ActOnFinishFullExpr(Expr *Expr) {
|
||||
return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc()
|
||||
: SourceLocation());
|
||||
}
|
||||
ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC,
|
||||
bool DiscardedValue, bool IsConstexpr = false);
|
||||
bool DiscardedValue = false,
|
||||
bool IsConstexpr = false);
|
||||
StmtResult ActOnFinishFullStmt(Stmt *Stmt);
|
||||
|
||||
// Marks SS invalid if it represents an incomplete type.
|
||||
|
@ -331,9 +331,15 @@ class LLVM_LIBRARY_VISIBILITY PPC32TargetInfo : public PPCTargetInfo {
|
||||
break;
|
||||
}
|
||||
|
||||
if (getTriple().isOSFreeBSD()) {
|
||||
switch (getTriple().getOS()) {
|
||||
case llvm::Triple::FreeBSD:
|
||||
case llvm::Triple::NetBSD:
|
||||
case llvm::Triple::OpenBSD:
|
||||
LongDoubleWidth = LongDoubleAlign = 64;
|
||||
LongDoubleFormat = &llvm::APFloat::IEEEdouble();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// PPC32 supports atomics up to 4 bytes.
|
||||
|
@ -7052,19 +7052,16 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||
llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
|
||||
|
||||
llvm::Type *RegisterType = Int64Ty;
|
||||
llvm::Type *ValueType = Int32Ty;
|
||||
llvm::Type *Types[] = { RegisterType };
|
||||
|
||||
if (BuiltinID == AArch64::BI_ReadStatusReg) {
|
||||
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
|
||||
llvm::Value *Call = Builder.CreateCall(F, Metadata);
|
||||
|
||||
return Builder.CreateTrunc(Call, ValueType);
|
||||
return Builder.CreateCall(F, Metadata);
|
||||
}
|
||||
|
||||
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
|
||||
llvm::Value *ArgValue = EmitScalarExpr(E->getArg(1));
|
||||
ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
|
||||
|
||||
return Builder.CreateCall(F, { Metadata, ArgValue });
|
||||
}
|
||||
|
@ -1631,11 +1631,15 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
|
||||
? LangOptions::TrivialAutoVarInitKind::Uninitialized
|
||||
: getContext().getLangOpts().getTrivialAutoVarInit()));
|
||||
|
||||
auto initializeWhatIsTechnicallyUninitialized = [&]() {
|
||||
auto initializeWhatIsTechnicallyUninitialized = [&](Address Loc) {
|
||||
if (trivialAutoVarInit ==
|
||||
LangOptions::TrivialAutoVarInitKind::Uninitialized)
|
||||
return;
|
||||
|
||||
// Only initialize a __block's storage: we always initialize the header.
|
||||
if (emission.IsEscapingByRef)
|
||||
Loc = emitBlockByrefAddress(Loc, &D, /*follow=*/false);
|
||||
|
||||
CharUnits Size = getContext().getTypeSizeInChars(type);
|
||||
if (!Size.isZero()) {
|
||||
switch (trivialAutoVarInit) {
|
||||
@ -1713,7 +1717,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
|
||||
};
|
||||
|
||||
if (isTrivialInitializer(Init)) {
|
||||
initializeWhatIsTechnicallyUninitialized();
|
||||
initializeWhatIsTechnicallyUninitialized(Loc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1727,7 +1731,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
|
||||
}
|
||||
|
||||
if (!constant) {
|
||||
initializeWhatIsTechnicallyUninitialized();
|
||||
initializeWhatIsTechnicallyUninitialized(Loc);
|
||||
LValue lv = MakeAddrLValue(Loc, type);
|
||||
lv.setNonGC(true);
|
||||
return EmitExprAsInit(Init, &D, lv, capturedByInit);
|
||||
|
@ -3762,13 +3762,15 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
|
||||
}
|
||||
}
|
||||
|
||||
// Microsoft's link.exe doesn't support alignments greater than 32 for common
|
||||
// symbols, so symbols with greater alignment requirements cannot be common.
|
||||
// Microsoft's link.exe doesn't support alignments greater than 32 bytes for
|
||||
// common symbols, so symbols with greater alignment requirements cannot be
|
||||
// common.
|
||||
// Other COFF linkers (ld.bfd and LLD) support arbitrary power-of-two
|
||||
// alignments for common symbols via the aligncomm directive, so this
|
||||
// restriction only applies to MSVC environments.
|
||||
if (Context.getTargetInfo().getTriple().isKnownWindowsMSVCEnvironment() &&
|
||||
Context.getTypeAlignIfKnown(D->getType()) > 32)
|
||||
Context.getTypeAlignIfKnown(D->getType()) >
|
||||
Context.toBits(CharUnits::fromQuantity(32)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -761,6 +761,22 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo {
|
||||
|
||||
void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
|
||||
CodeGen::CodeGenModule &CGM) const override {
|
||||
TargetCodeGenInfo::setTargetAttributes(D, GV, CGM);
|
||||
if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
|
||||
if (const auto *Attr = FD->getAttr<WebAssemblyImportModuleAttr>()) {
|
||||
llvm::Function *Fn = cast<llvm::Function>(GV);
|
||||
llvm::AttrBuilder B;
|
||||
B.addAttribute("wasm-import-module", Attr->getImportModule());
|
||||
Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
|
||||
}
|
||||
if (const auto *Attr = FD->getAttr<WebAssemblyImportNameAttr>()) {
|
||||
llvm::Function *Fn = cast<llvm::Function>(GV);
|
||||
llvm::AttrBuilder B;
|
||||
B.addAttribute("wasm-import-name", Attr->getImportName());
|
||||
Fn->addAttributes(llvm::AttributeList::FunctionIndex, B);
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
|
||||
llvm::Function *Fn = cast<llvm::Function>(GV);
|
||||
if (!FD->doesThisDeclarationHaveABody() && !FD->hasPrototype())
|
||||
|
@ -1408,10 +1408,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
|
||||
DAL.AddFlagArg(
|
||||
A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
|
||||
} else {
|
||||
// Don't warn about /Oy- in 64-bit builds (where
|
||||
// Don't warn about /Oy- in x86-64 builds (where
|
||||
// SupportsForcingFramePointer is false). The flag having no effect
|
||||
// there is a compiler-internal optimization, and people shouldn't have
|
||||
// to special-case their build files for 64-bit clang-cl.
|
||||
// to special-case their build files for x86-64 clang-cl.
|
||||
A->claim();
|
||||
}
|
||||
break;
|
||||
@ -1442,8 +1442,8 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
|
||||
DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
|
||||
const OptTable &Opts = getDriver().getOpts();
|
||||
|
||||
// /Oy and /Oy- only has an effect under X86-32.
|
||||
bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
|
||||
// /Oy and /Oy- don't have an effect on X86-64
|
||||
bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64;
|
||||
|
||||
// The -O[12xd] flag actually expands to several flags. We must desugar the
|
||||
// flags so that options embedded can be negated. For example, the '-O2' flag
|
||||
|
@ -1060,8 +1060,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
||||
// OpenCL definitions.
|
||||
if (LangOpts.OpenCL) {
|
||||
#define OPENCLEXT(Ext) \
|
||||
if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \
|
||||
LangOpts.OpenCLVersion)) \
|
||||
if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \
|
||||
Builder.defineMacro(#Ext);
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
|
||||
|
@ -564,8 +564,8 @@ __nop(void) {
|
||||
#if defined(__aarch64__)
|
||||
unsigned __int64 __getReg(int);
|
||||
long _InterlockedAdd(long volatile *Addend, long Value);
|
||||
int _ReadStatusReg(int);
|
||||
void _WriteStatusReg(int, int);
|
||||
__int64 _ReadStatusReg(int);
|
||||
void _WriteStatusReg(int, __int64);
|
||||
|
||||
static inline unsigned short _byteswap_ushort (unsigned short val) {
|
||||
return __builtin_bswap16(val);
|
||||
|
@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
|
||||
|
||||
// Otherwise, eat the semicolon.
|
||||
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
|
||||
return Actions.ActOnExprStmt(Res, isExprValueDiscarded());
|
||||
return Actions.ActOnExprStmt(Res);
|
||||
}
|
||||
|
||||
ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||
|
@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
|
||||
Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
|
||||
ExprResult CombinerResult =
|
||||
Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
|
||||
D->getLocation(), /*DiscardedValue*/ false);
|
||||
D->getLocation(), /*DiscardedValue=*/true);
|
||||
Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
|
||||
|
||||
if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
|
||||
@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
|
||||
if (Actions.getLangOpts().CPlusPlus) {
|
||||
InitializerResult = Actions.ActOnFinishFullExpr(
|
||||
ParseAssignmentExpression().get(), D->getLocation(),
|
||||
/*DiscardedValue*/ false);
|
||||
/*DiscardedValue=*/true);
|
||||
} else {
|
||||
ConsumeToken();
|
||||
ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
|
||||
@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
|
||||
} else {
|
||||
InitializerResult = Actions.ActOnFinishFullExpr(
|
||||
ParseAssignmentExpression().get(), D->getLocation(),
|
||||
/*DiscardedValue*/ false);
|
||||
/*DiscardedValue=*/true);
|
||||
}
|
||||
Actions.ActOnOpenMPDeclareReductionInitializerEnd(
|
||||
D, InitializerResult.get(), OmpPrivParm);
|
||||
@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
|
||||
ExprResult LHS(ParseCastExpression(
|
||||
/*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
|
||||
ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
|
||||
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
|
||||
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
|
||||
|
||||
// Parse ')'.
|
||||
RLoc = Tok.getLocation();
|
||||
@ -1711,8 +1711,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
|
||||
SourceLocation ELoc = Tok.getLocation();
|
||||
ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
|
||||
Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
|
||||
Val =
|
||||
Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
|
||||
Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
|
||||
}
|
||||
|
||||
// Parse ')'.
|
||||
@ -1997,8 +1996,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
|
||||
Data.ColonLoc = Tok.getLocation();
|
||||
SourceLocation ELoc = ConsumeToken();
|
||||
ExprResult Tail = ParseAssignmentExpression();
|
||||
Tail =
|
||||
Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
|
||||
Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
|
||||
if (Tail.isUsable())
|
||||
Data.TailExpr = Tail.get();
|
||||
else
|
||||
|
@ -693,13 +693,12 @@ void Parser::HandlePragmaOpenCLExtension() {
|
||||
if (Name == "all") {
|
||||
if (State == Disable) {
|
||||
Opt.disableAll();
|
||||
Opt.enableSupportedCore(getLangOpts().OpenCLVersion);
|
||||
Opt.enableSupportedCore(getLangOpts());
|
||||
} else {
|
||||
PP.Diag(NameLoc, diag::warn_pragma_expected_predicate) << 1;
|
||||
}
|
||||
} else if (State == Begin) {
|
||||
if (!Opt.isKnown(Name) ||
|
||||
!Opt.isSupported(Name, getLangOpts().OpenCLVersion)) {
|
||||
if (!Opt.isKnown(Name) || !Opt.isSupported(Name, getLangOpts())) {
|
||||
Opt.support(Name);
|
||||
}
|
||||
Actions.setCurrentOpenCLExtension(Name);
|
||||
@ -709,9 +708,9 @@ void Parser::HandlePragmaOpenCLExtension() {
|
||||
Actions.setCurrentOpenCLExtension("");
|
||||
} else if (!Opt.isKnown(Name))
|
||||
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << Ident;
|
||||
else if (Opt.isSupportedExtension(Name, getLangOpts().OpenCLVersion))
|
||||
else if (Opt.isSupportedExtension(Name, getLangOpts()))
|
||||
Opt.enable(Name, State == Enable);
|
||||
else if (Opt.isSupportedCore(Name, getLangOpts().OpenCLVersion))
|
||||
else if (Opt.isSupportedCore(Name, getLangOpts()))
|
||||
PP.Diag(NameLoc, diag::warn_pragma_extension_is_core) << Ident;
|
||||
else
|
||||
PP.Diag(NameLoc, diag::warn_pragma_unsupported_extension) << Ident;
|
||||
|
@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() {
|
||||
|
||||
// Otherwise, eat the semicolon.
|
||||
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
|
||||
return Actions.ActOnExprStmt(Expr, isExprValueDiscarded());
|
||||
return Actions.ActOnExprStmt(Expr);
|
||||
}
|
||||
|
||||
/// ParseSEHTryBlockCommon
|
||||
@ -958,16 +958,6 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Parser::isExprValueDiscarded() {
|
||||
if (Actions.isCurCompoundStmtAStmtExpr()) {
|
||||
// Look to see if the next two tokens close the statement expression;
|
||||
// if so, this expression statement is the last statement in a
|
||||
// statment expression.
|
||||
return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
|
||||
/// ActOnCompoundStmt action. This expects the '{' to be the current token, and
|
||||
/// consume the '}' at the end of the block. It does not manipulate the scope
|
||||
@ -1072,7 +1062,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||
// Eat the semicolon at the end of stmt and convert the expr into a
|
||||
// statement.
|
||||
ExpectAndConsumeSemi(diag::err_expected_semi_after_expr);
|
||||
R = Actions.ActOnExprStmt(Res, isExprValueDiscarded());
|
||||
R = Actions.ActOnExprStmt(Res);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1708,16 +1698,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
|
||||
if (!Value.isInvalid()) {
|
||||
if (ForEach)
|
||||
FirstPart = Actions.ActOnForEachLValueExpr(Value.get());
|
||||
else {
|
||||
// We already know this is not an init-statement within a for loop, so
|
||||
// if we are parsing a C++11 range-based for loop, we should treat this
|
||||
// expression statement as being a discarded value expression because
|
||||
// we will err below. This way we do not warn on an unused expression
|
||||
// that was an error in the first place, like with: for (expr : expr);
|
||||
bool IsRangeBasedFor =
|
||||
getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon);
|
||||
FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor);
|
||||
}
|
||||
else
|
||||
FirstPart = Actions.ActOnExprStmt(Value);
|
||||
}
|
||||
|
||||
if (Tok.is(tok::semi)) {
|
||||
|
@ -637,7 +637,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
|
||||
// Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber
|
||||
// constraints. Clang always adds fpsr to the clobber list anyway.
|
||||
llvm::erase_if(Clobbers, [](const std::string &C) {
|
||||
return C == "fpsw" || C == "mxcsr";
|
||||
return C == "fpsr" || C == "mxcsr";
|
||||
});
|
||||
|
||||
// Build the vector of clobber StringRefs.
|
||||
|
@ -256,11 +256,12 @@ void Sema::Initialize() {
|
||||
// Initialize predefined OpenCL types and supported extensions and (optional)
|
||||
// core features.
|
||||
if (getLangOpts().OpenCL) {
|
||||
getOpenCLOptions().addSupport(Context.getTargetInfo().getSupportedOpenCLOpts());
|
||||
getOpenCLOptions().enableSupportedCore(getLangOpts().OpenCLVersion);
|
||||
getOpenCLOptions().addSupport(
|
||||
Context.getTargetInfo().getSupportedOpenCLOpts());
|
||||
getOpenCLOptions().enableSupportedCore(getLangOpts());
|
||||
addImplicitTypedef("sampler_t", Context.OCLSamplerTy);
|
||||
addImplicitTypedef("event_t", Context.OCLEventTy);
|
||||
if (getLangOpts().OpenCLVersion >= 200) {
|
||||
if (getLangOpts().OpenCLCPlusPlus || getLangOpts().OpenCLVersion >= 200) {
|
||||
addImplicitTypedef("clk_event_t", Context.OCLClkEventTy);
|
||||
addImplicitTypedef("queue_t", Context.OCLQueueTy);
|
||||
addImplicitTypedef("reserve_id_t", Context.OCLReserveIDTy);
|
||||
|
@ -10622,14 +10622,14 @@ static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E) {
|
||||
// The below checks assume source is floating point.
|
||||
if (!ResultBT || !RBT || !RBT->isFloatingPoint()) return;
|
||||
|
||||
// If source is floating point but target is not.
|
||||
if (!ResultBT->isFloatingPoint())
|
||||
return DiagnoseFloatingImpCast(S, E, E->getRHS()->getType(),
|
||||
E->getExprLoc());
|
||||
|
||||
// If both source and target are floating points.
|
||||
// Builtin FP kinds are ordered by increasing FP rank.
|
||||
if (ResultBT->getKind() < RBT->getKind() &&
|
||||
// If source is floating point but target is an integer.
|
||||
if (ResultBT->isInteger())
|
||||
DiagnoseImpCast(S, E, E->getRHS()->getType(), E->getLHS()->getType(),
|
||||
E->getExprLoc(), diag::warn_impcast_float_integer);
|
||||
// If both source and target are floating points. Builtin FP kinds are ordered
|
||||
// by increasing FP rank. FIXME: except _Float16, we currently emit a bogus
|
||||
// warning.
|
||||
else if (ResultBT->isFloatingPoint() && ResultBT->getKind() < RBT->getKind() &&
|
||||
// We don't want to warn for system macro.
|
||||
!S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
|
||||
// warn about dropping FP rank.
|
||||
|
@ -646,7 +646,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
|
||||
return StmtError();
|
||||
Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(),
|
||||
/*IsImplicit*/ true);
|
||||
Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false);
|
||||
Suspend = ActOnFinishFullExpr(Suspend.get());
|
||||
if (Suspend.isInvalid()) {
|
||||
Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
|
||||
<< ((Name == "initial_suspend") ? 0 : 1);
|
||||
@ -867,7 +867,7 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
|
||||
if (PC.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get();
|
||||
Expr *PCE = ActOnFinishFullExpr(PC.get()).get();
|
||||
|
||||
Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
|
||||
return Res;
|
||||
@ -1236,7 +1236,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
|
||||
|
||||
ExprResult NewExpr =
|
||||
S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
|
||||
NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false);
|
||||
NewExpr = S.ActOnFinishFullExpr(NewExpr.get());
|
||||
if (NewExpr.isInvalid())
|
||||
return false;
|
||||
|
||||
@ -1262,8 +1262,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
|
||||
|
||||
ExprResult DeleteExpr =
|
||||
S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
|
||||
DeleteExpr =
|
||||
S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false);
|
||||
DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get());
|
||||
if (DeleteExpr.isInvalid())
|
||||
return false;
|
||||
|
||||
@ -1348,8 +1347,7 @@ bool CoroutineStmtBuilder::makeOnException() {
|
||||
|
||||
ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc,
|
||||
"unhandled_exception", None);
|
||||
UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc,
|
||||
/*DiscardedValue*/ false);
|
||||
UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc);
|
||||
if (UnhandledException.isInvalid())
|
||||
return false;
|
||||
|
||||
@ -1402,8 +1400,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
|
||||
"get_return_object type must no longer be dependent");
|
||||
|
||||
if (FnRetType->isVoidType()) {
|
||||
ExprResult Res =
|
||||
S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false);
|
||||
ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc);
|
||||
if (Res.isInvalid())
|
||||
return false;
|
||||
|
||||
@ -1435,7 +1432,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
|
||||
if (Res.isInvalid())
|
||||
return false;
|
||||
|
||||
Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false);
|
||||
Res = S.ActOnFinishFullExpr(Res.get());
|
||||
if (Res.isInvalid())
|
||||
return false;
|
||||
|
||||
|
@ -11200,9 +11200,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
||||
// struct T { S a, b; } t = { Temp(), Temp() }
|
||||
//
|
||||
// we should destroy the first Temp before constructing the second.
|
||||
ExprResult Result =
|
||||
ActOnFinishFullExpr(Init, VDecl->getLocation(),
|
||||
/*DiscardedValue*/ false, VDecl->isConstexpr());
|
||||
ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(),
|
||||
false,
|
||||
VDecl->isConstexpr());
|
||||
if (Result.isInvalid()) {
|
||||
VDecl->setInvalidDecl();
|
||||
return;
|
||||
|
@ -5116,11 +5116,22 @@ static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
|
||||
|
||||
static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
|
||||
const ParsedAttr &AL) {
|
||||
DeclContext *Ctx = D->getDeclContext();
|
||||
|
||||
// This attribute can only be applied to methods in interfaces or class
|
||||
// extensions.
|
||||
if (!isa<ObjCInterfaceDecl>(Ctx) &&
|
||||
!(isa<ObjCCategoryDecl>(Ctx) &&
|
||||
cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
|
||||
S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
|
||||
return;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *IFace;
|
||||
if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
|
||||
if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
|
||||
IFace = CatDecl->getClassInterface();
|
||||
else
|
||||
IFace = cast<ObjCInterfaceDecl>(D->getDeclContext());
|
||||
IFace = cast<ObjCInterfaceDecl>(Ctx);
|
||||
|
||||
if (!IFace)
|
||||
return;
|
||||
@ -5577,6 +5588,51 @@ static void handleAVRSignalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
handleSimpleAttribute<AVRSignalAttr>(S, D, AL);
|
||||
}
|
||||
|
||||
static void handleWebAssemblyImportModuleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (!isFunctionOrMethod(D)) {
|
||||
S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
|
||||
<< "'import_module'" << ExpectedFunction;
|
||||
return;
|
||||
}
|
||||
|
||||
auto *FD = cast<FunctionDecl>(D);
|
||||
if (FD->isThisDeclarationADefinition()) {
|
||||
S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
StringRef Str;
|
||||
SourceLocation ArgLoc;
|
||||
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
|
||||
return;
|
||||
|
||||
FD->addAttr(::new (S.Context) WebAssemblyImportModuleAttr(
|
||||
AL.getRange(), S.Context, Str,
|
||||
AL.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
static void handleWebAssemblyImportNameAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (!isFunctionOrMethod(D)) {
|
||||
S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type)
|
||||
<< "'import_name'" << ExpectedFunction;
|
||||
return;
|
||||
}
|
||||
|
||||
auto *FD = cast<FunctionDecl>(D);
|
||||
if (FD->isThisDeclarationADefinition()) {
|
||||
S.Diag(D->getLocation(), diag::err_alias_is_definition) << FD << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
StringRef Str;
|
||||
SourceLocation ArgLoc;
|
||||
if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &ArgLoc))
|
||||
return;
|
||||
|
||||
FD->addAttr(::new (S.Context) WebAssemblyImportNameAttr(
|
||||
AL.getRange(), S.Context, Str,
|
||||
AL.getAttributeSpellingListIndex()));
|
||||
}
|
||||
|
||||
static void handleRISCVInterruptAttr(Sema &S, Decl *D,
|
||||
const ParsedAttr &AL) {
|
||||
@ -6330,6 +6386,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
|
||||
case ParsedAttr::AT_AVRSignal:
|
||||
handleAVRSignalAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_WebAssemblyImportModule:
|
||||
handleWebAssemblyImportModuleAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_WebAssemblyImportName:
|
||||
handleWebAssemblyImportNameAttr(S, D, AL);
|
||||
break;
|
||||
case ParsedAttr::AT_IBAction:
|
||||
handleSimpleAttribute<IBActionAttr>(S, D, AL);
|
||||
break;
|
||||
@ -7016,6 +7078,17 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do this check after processing D's attributes because the attribute
|
||||
// objc_method_family can change whether the given method is in the init
|
||||
// family, and it can be applied after objc_designated_initializer. This is a
|
||||
// bit of a hack, but we need it to be compatible with versions of clang that
|
||||
// processed the attribute list in the wrong order.
|
||||
if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
|
||||
cast<ObjCMethodDecl>(D)->getMethodFamily() != OMF_init) {
|
||||
Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
|
||||
D->dropAttr<ObjCDesignatedInitializerAttr>();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper for delayed processing TransparentUnion attribute.
|
||||
|
@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition(Sema &S,
|
||||
E = Seq.Perform(S, Entity, Kind, Init);
|
||||
if (E.isInvalid())
|
||||
return true;
|
||||
E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false);
|
||||
E = S.ActOnFinishFullExpr(E.get(), Loc);
|
||||
if (E.isInvalid())
|
||||
return true;
|
||||
RefVD->setInit(E.get());
|
||||
@ -3686,7 +3686,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
|
||||
// C++11 [class.base.init]p7:
|
||||
// The initialization of each base and member constitutes a
|
||||
// full-expression.
|
||||
Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false);
|
||||
Init = ActOnFinishFullExpr(Init.get(), InitLoc);
|
||||
if (Init.isInvalid()) {
|
||||
FD->setInvalidDecl();
|
||||
return;
|
||||
@ -4044,8 +4044,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init,
|
||||
// C++11 [class.base.init]p7:
|
||||
// The initialization of each base and member constitutes a
|
||||
// full-expression.
|
||||
MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(),
|
||||
/*DiscardedValue*/ false);
|
||||
MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin());
|
||||
if (MemberInit.isInvalid())
|
||||
return true;
|
||||
|
||||
@ -4100,8 +4099,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
|
||||
// C++11 [class.base.init]p7:
|
||||
// The initialization of each base and member constitutes a
|
||||
// full-expression.
|
||||
DelegationInit = ActOnFinishFullExpr(
|
||||
DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ false);
|
||||
DelegationInit = ActOnFinishFullExpr(DelegationInit.get(),
|
||||
InitRange.getBegin());
|
||||
if (DelegationInit.isInvalid())
|
||||
return true;
|
||||
|
||||
@ -4230,8 +4229,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
|
||||
// C++11 [class.base.init]p7:
|
||||
// The initialization of each base and member constitutes a
|
||||
// full-expression.
|
||||
BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(),
|
||||
/*DiscardedValue*/ false);
|
||||
BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin());
|
||||
if (BaseInit.isInvalid())
|
||||
return true;
|
||||
|
||||
|
@ -4723,9 +4723,8 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD,
|
||||
if (Result.isInvalid())
|
||||
return true;
|
||||
|
||||
Result =
|
||||
ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(),
|
||||
/*DiscardedValue*/ false);
|
||||
Result = ActOnFinishFullExpr(Result.getAs<Expr>(),
|
||||
Param->getOuterLocStart());
|
||||
if (Result.isInvalid())
|
||||
return true;
|
||||
|
||||
|
@ -7815,8 +7815,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC,
|
||||
FullExpr = IgnoredValueConversions(FullExpr.get());
|
||||
if (FullExpr.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
DiagnoseUnusedExprResult(FullExpr.get());
|
||||
}
|
||||
|
||||
FullExpr = CorrectDelayedTyposInExpr(FullExpr.get());
|
||||
|
@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation,
|
||||
/*NRVO=*/false),
|
||||
CurrentLocation, Src);
|
||||
if (!Init.isInvalid())
|
||||
Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
|
||||
Init = ActOnFinishFullExpr(Init.get());
|
||||
|
||||
if (Init.isInvalid())
|
||||
return ExprError();
|
||||
|
@ -5367,7 +5367,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
LastIteration.get(), UB.get());
|
||||
EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
|
||||
CondOp.get());
|
||||
EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
|
||||
EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
|
||||
|
||||
// If we have a combined directive that combines 'distribute', 'for' or
|
||||
// 'simd' we need to be able to access the bounds of the schedule of the
|
||||
@ -5396,8 +5396,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
LastIteration.get(), CombUB.get());
|
||||
CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
|
||||
CombCondOp.get());
|
||||
CombEUB =
|
||||
SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
|
||||
CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
|
||||
|
||||
const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
|
||||
// We expect to have at least 2 more parameters than the 'parallel'
|
||||
@ -5431,7 +5430,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
? LB.get()
|
||||
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
|
||||
Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
|
||||
Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
|
||||
Init = SemaRef.ActOnFinishFullExpr(Init.get());
|
||||
|
||||
if (isOpenMPLoopBoundSharingDirective(DKind)) {
|
||||
Expr *CombRHS =
|
||||
@ -5442,8 +5441,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
: SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
|
||||
CombInit =
|
||||
SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
|
||||
CombInit =
|
||||
SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
|
||||
CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5475,7 +5473,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
if (!Inc.isUsable())
|
||||
return 0;
|
||||
Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
|
||||
Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
|
||||
Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
|
||||
if (!Inc.isUsable())
|
||||
return 0;
|
||||
|
||||
@ -5493,8 +5491,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
// LB = LB + ST
|
||||
NextLB =
|
||||
SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
|
||||
NextLB =
|
||||
SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
|
||||
NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
|
||||
if (!NextLB.isUsable())
|
||||
return 0;
|
||||
// UB + ST
|
||||
@ -5504,8 +5501,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
// UB = UB + ST
|
||||
NextUB =
|
||||
SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
|
||||
NextUB =
|
||||
SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
|
||||
NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
|
||||
if (!NextUB.isUsable())
|
||||
return 0;
|
||||
if (isOpenMPLoopBoundSharingDirective(DKind)) {
|
||||
@ -5516,8 +5512,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
// LB = LB + ST
|
||||
CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
|
||||
CombNextLB.get());
|
||||
CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
|
||||
/*DiscardedValue*/ false);
|
||||
CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
|
||||
if (!CombNextLB.isUsable())
|
||||
return 0;
|
||||
// UB + ST
|
||||
@ -5528,8 +5523,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
// UB = UB + ST
|
||||
CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
|
||||
CombNextUB.get());
|
||||
CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
|
||||
/*DiscardedValue*/ false);
|
||||
CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
|
||||
if (!CombNextUB.isUsable())
|
||||
return 0;
|
||||
}
|
||||
@ -5550,8 +5544,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
assert(DistInc.isUsable() && "distribute inc expr was not built");
|
||||
DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
|
||||
DistInc.get());
|
||||
DistInc =
|
||||
SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
|
||||
DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
|
||||
assert(DistInc.isUsable() && "distribute inc expr was not built");
|
||||
|
||||
// Build expression: UB = min(UB, prevUB) for #for in composite or combined
|
||||
@ -5563,8 +5556,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
|
||||
PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
|
||||
CondOp.get());
|
||||
PrevEUB =
|
||||
SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
|
||||
PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
|
||||
|
||||
// Build IV <= PrevUB to be used in parallel for is in combination with
|
||||
// a distribute directive with schedule(static, 1)
|
||||
@ -5680,10 +5672,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
|
||||
Built.IterationVarRef = IV.get();
|
||||
Built.LastIteration = LastIteration.get();
|
||||
Built.NumIterations = NumIterations.get();
|
||||
Built.CalcLastIteration = SemaRef
|
||||
.ActOnFinishFullExpr(CalcLastIteration.get(),
|
||||
/*DiscardedValue*/ false)
|
||||
.get();
|
||||
Built.CalcLastIteration =
|
||||
SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
|
||||
Built.PreCond = PreCond.get();
|
||||
Built.PreInits = buildPreInits(C, Captures);
|
||||
Built.Cond = Cond.get();
|
||||
@ -10358,8 +10348,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
|
||||
PseudoDstExpr, PseudoSrcExpr);
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
AssignmentOp =
|
||||
ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
|
||||
AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
|
||||
/*DiscardedValue=*/true);
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
|
||||
@ -11357,8 +11347,7 @@ static bool actOnOMPReductionKindClause(
|
||||
BO_Assign, LHSDRE, ConditionalOp);
|
||||
}
|
||||
if (ReductionOp.isUsable())
|
||||
ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
|
||||
/*DiscardedValue*/ false);
|
||||
ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
|
||||
}
|
||||
if (!ReductionOp.isUsable())
|
||||
continue;
|
||||
@ -11688,7 +11677,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause(
|
||||
buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
|
||||
ExprResult CalcStep =
|
||||
BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
|
||||
CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
|
||||
CalcStep = ActOnFinishFullExpr(CalcStep.get());
|
||||
|
||||
// Warn about zero linear step (it would be probably better specified as
|
||||
// making corresponding variables 'const').
|
||||
@ -11776,7 +11765,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
|
||||
else
|
||||
Update = *CurPrivate;
|
||||
Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
|
||||
/*DiscardedValue*/ false);
|
||||
/*DiscardedValue=*/true);
|
||||
|
||||
// Build final: Var = InitExpr + NumIterations * Step
|
||||
ExprResult Final;
|
||||
@ -11787,7 +11776,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
|
||||
else
|
||||
Final = *CurPrivate;
|
||||
Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
|
||||
/*DiscardedValue*/ false);
|
||||
/*DiscardedValue=*/true);
|
||||
|
||||
if (!Update.isUsable() || !Final.isUsable()) {
|
||||
Updates.push_back(nullptr);
|
||||
@ -11955,7 +11944,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
|
||||
/*DiscardedValue*/ false);
|
||||
/*DiscardedValue=*/true);
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
|
||||
@ -12063,8 +12052,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
|
||||
DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
AssignmentOp =
|
||||
ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
|
||||
AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
|
||||
/*DiscardedValue=*/true);
|
||||
if (AssignmentOp.isInvalid())
|
||||
continue;
|
||||
|
||||
|
@ -42,11 +42,12 @@
|
||||
using namespace clang;
|
||||
using namespace sema;
|
||||
|
||||
StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {
|
||||
StmtResult Sema::ActOnExprStmt(ExprResult FE) {
|
||||
if (FE.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue);
|
||||
FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(),
|
||||
/*DiscardedValue*/ true);
|
||||
if (FE.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
@ -347,10 +348,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
|
||||
return getCurFunction()->CompoundScopes.back();
|
||||
}
|
||||
|
||||
bool Sema::isCurCompoundStmtAStmtExpr() const {
|
||||
return getCurCompoundScope().IsStmtExpr;
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
|
||||
ArrayRef<Stmt *> Elts, bool isStmtExpr) {
|
||||
const unsigned NumElts = Elts.size();
|
||||
@ -373,6 +370,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
|
||||
Diag(D->getLocation(), diag::ext_mixed_decls_code);
|
||||
}
|
||||
}
|
||||
// Warn about unused expressions in statements.
|
||||
for (unsigned i = 0; i != NumElts; ++i) {
|
||||
// Ignore statements that are last in a statement expression.
|
||||
if (isStmtExpr && i == NumElts - 1)
|
||||
continue;
|
||||
|
||||
DiagnoseUnusedExprResult(Elts[i]);
|
||||
}
|
||||
|
||||
// Check for suspicious empty body (null statement) in `for' and `while'
|
||||
// statements. Don't do anything for template instantiations, this just adds
|
||||
@ -464,12 +469,15 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
|
||||
|
||||
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
|
||||
void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {
|
||||
DiagnoseUnusedExprResult(SubStmt);
|
||||
cast<CaseStmt>(S)->setSubStmt(SubStmt);
|
||||
}
|
||||
|
||||
StmtResult
|
||||
Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
|
||||
Stmt *SubStmt, Scope *CurScope) {
|
||||
DiagnoseUnusedExprResult(SubStmt);
|
||||
|
||||
if (getCurFunction()->SwitchStack.empty()) {
|
||||
Diag(DefaultLoc, diag::err_default_not_in_switch);
|
||||
return SubStmt;
|
||||
@ -563,6 +571,9 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr,
|
||||
if (IsConstexpr || isa<ObjCAvailabilityCheckExpr>(Cond.get().second))
|
||||
setFunctionHasBranchProtectedScope();
|
||||
|
||||
DiagnoseUnusedExprResult(thenStmt);
|
||||
DiagnoseUnusedExprResult(elseStmt);
|
||||
|
||||
return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first,
|
||||
Cond.get().second, thenStmt, ElseLoc, elseStmt);
|
||||
}
|
||||
@ -1290,6 +1301,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
|
||||
!Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
|
||||
CommaVisitor(*this).Visit(CondVal.second);
|
||||
|
||||
DiagnoseUnusedExprResult(Body);
|
||||
|
||||
if (isa<NullStmt>(Body))
|
||||
getCurCompoundScope().setHasEmptyLoopBodies();
|
||||
|
||||
@ -1309,7 +1322,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
|
||||
return StmtError();
|
||||
Cond = CondResult.get();
|
||||
|
||||
CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false);
|
||||
CondResult = ActOnFinishFullExpr(Cond, DoLoc);
|
||||
if (CondResult.isInvalid())
|
||||
return StmtError();
|
||||
Cond = CondResult.get();
|
||||
@ -1319,6 +1332,8 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
|
||||
!Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))
|
||||
CommaVisitor(*this).Visit(Cond);
|
||||
|
||||
DiagnoseUnusedExprResult(Body);
|
||||
|
||||
return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
|
||||
}
|
||||
|
||||
@ -1763,6 +1778,11 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
|
||||
CommaVisitor(*this).Visit(Second.get().second);
|
||||
|
||||
Expr *Third = third.release().getAs<Expr>();
|
||||
|
||||
DiagnoseUnusedExprResult(First);
|
||||
DiagnoseUnusedExprResult(Third);
|
||||
DiagnoseUnusedExprResult(Body);
|
||||
|
||||
if (isa<NullStmt>(Body))
|
||||
getCurCompoundScope().setHasEmptyLoopBodies();
|
||||
|
||||
@ -1782,7 +1802,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
|
||||
if (result.isInvalid()) return StmtError();
|
||||
E = result.get();
|
||||
|
||||
ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
|
||||
ExprResult FullExpr = ActOnFinishFullExpr(E);
|
||||
if (FullExpr.isInvalid())
|
||||
return StmtError();
|
||||
return StmtResult(static_cast<Stmt*>(FullExpr.get()));
|
||||
@ -1936,8 +1956,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
|
||||
if (CollectionExprResult.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
CollectionExprResult =
|
||||
ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false);
|
||||
CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
|
||||
if (CollectionExprResult.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
@ -2574,8 +2593,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
|
||||
if (!NotEqExpr.isInvalid())
|
||||
NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
|
||||
if (!NotEqExpr.isInvalid())
|
||||
NotEqExpr =
|
||||
ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false);
|
||||
NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
|
||||
if (NotEqExpr.isInvalid()) {
|
||||
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
|
||||
<< RangeLoc << 0 << BeginRangeRef.get()->getType();
|
||||
@ -2598,7 +2616,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
|
||||
// co_await during the initial parse.
|
||||
IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
|
||||
if (!IncrExpr.isInvalid())
|
||||
IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);
|
||||
IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
|
||||
if (IncrExpr.isInvalid()) {
|
||||
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
|
||||
<< RangeLoc << 2 << BeginRangeRef.get()->getType() ;
|
||||
@ -2853,7 +2871,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
|
||||
ExprResult ExprRes = ActOnFinishFullExpr(E);
|
||||
if (ExprRes.isInvalid())
|
||||
return StmtError();
|
||||
E = ExprRes.get();
|
||||
@ -3203,8 +3221,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
ExpressionEvaluationContext::DiscardedStatement &&
|
||||
(HasDeducedReturnType || CurCap->HasImplicitReturnType)) {
|
||||
if (RetValExp) {
|
||||
ExprResult ER =
|
||||
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
|
||||
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
|
||||
if (ER.isInvalid())
|
||||
return StmtError();
|
||||
RetValExp = ER.get();
|
||||
@ -3331,8 +3348,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
}
|
||||
|
||||
if (RetValExp) {
|
||||
ExprResult ER =
|
||||
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
|
||||
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
|
||||
if (ER.isInvalid())
|
||||
return StmtError();
|
||||
RetValExp = ER.get();
|
||||
@ -3562,8 +3578,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
ExpressionEvaluationContext::DiscardedStatement &&
|
||||
FnRetType->getContainedAutoType()) {
|
||||
if (RetValExp) {
|
||||
ExprResult ER =
|
||||
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
|
||||
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
|
||||
if (ER.isInvalid())
|
||||
return StmtError();
|
||||
RetValExp = ER.get();
|
||||
@ -3657,8 +3672,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
}
|
||||
|
||||
if (RetValExp) {
|
||||
ExprResult ER =
|
||||
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
|
||||
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
|
||||
if (ER.isInvalid())
|
||||
return StmtError();
|
||||
RetValExp = ER.get();
|
||||
@ -3737,8 +3751,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
||||
}
|
||||
|
||||
if (RetValExp) {
|
||||
ExprResult ER =
|
||||
ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
|
||||
ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
|
||||
if (ER.isInvalid())
|
||||
return StmtError();
|
||||
RetValExp = ER.get();
|
||||
@ -3791,7 +3804,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
|
||||
if (Result.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false);
|
||||
Result = ActOnFinishFullExpr(Result.get());
|
||||
if (Result.isInvalid())
|
||||
return StmtError();
|
||||
Throw = Result.get();
|
||||
@ -3863,7 +3876,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
|
||||
}
|
||||
|
||||
// The operand to @synchronized is a full-expression.
|
||||
return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false);
|
||||
return ActOnFinishFullExpr(operand);
|
||||
}
|
||||
|
||||
StmtResult
|
||||
|
@ -328,7 +328,7 @@ class TreeTransform {
|
||||
/// other mechanism.
|
||||
///
|
||||
/// \returns the transformed statement.
|
||||
StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false);
|
||||
StmtResult TransformStmt(Stmt *S);
|
||||
|
||||
/// Transform the given statement.
|
||||
///
|
||||
@ -3270,7 +3270,7 @@ class TreeTransform {
|
||||
};
|
||||
|
||||
template<typename Derived>
|
||||
StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
|
||||
StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
|
||||
if (!S)
|
||||
return S;
|
||||
|
||||
@ -3294,7 +3294,7 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
|
||||
if (E.isInvalid())
|
||||
return StmtError();
|
||||
|
||||
return getSema().ActOnExprStmt(E, DiscardedValue);
|
||||
return getSema().ActOnExprStmt(E);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4715,8 +4715,7 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
|
||||
}
|
||||
if (SizeResult.isInvalid())
|
||||
return QualType();
|
||||
SizeResult =
|
||||
SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
|
||||
SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get());
|
||||
if (SizeResult.isInvalid())
|
||||
return QualType();
|
||||
|
||||
@ -6521,9 +6520,7 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
|
||||
bool SubStmtChanged = false;
|
||||
SmallVector<Stmt*, 8> Statements;
|
||||
for (auto *B : S->body()) {
|
||||
StmtResult Result =
|
||||
getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back());
|
||||
|
||||
StmtResult Result = getDerived().TransformStmt(B);
|
||||
if (Result.isInvalid()) {
|
||||
// Immediately fail if this was a DeclStmt, since it's very
|
||||
// likely that this will cause problems for future statements.
|
||||
|
@ -154,6 +154,32 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) {
|
||||
return E;
|
||||
}
|
||||
|
||||
/// Comparing internal representations of symbolic values (via
|
||||
/// SVal::operator==()) is a valid way to check if the value was updated,
|
||||
/// unless it's a LazyCompoundVal that may have a different internal
|
||||
/// representation every time it is loaded from the state. In this function we
|
||||
/// do an approximate comparison for lazy compound values, checking that they
|
||||
/// are the immediate snapshots of the tracked region's bindings within the
|
||||
/// node's respective states but not really checking that these snapshots
|
||||
/// actually contain the same set of bindings.
|
||||
bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
|
||||
const ExplodedNode *RightNode, SVal RightVal) {
|
||||
if (LeftVal == RightVal)
|
||||
return true;
|
||||
|
||||
const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
|
||||
if (!LLCV)
|
||||
return false;
|
||||
|
||||
const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
|
||||
if (!RLCV)
|
||||
return false;
|
||||
|
||||
return LLCV->getRegion() == RLCV->getRegion() &&
|
||||
LLCV->getStore() == LeftNode->getState()->getStore() &&
|
||||
RLCV->getStore() == RightNode->getState()->getStore();
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Definitions for bug reporter visitors.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1188,7 +1214,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
|
||||
if (Succ->getState()->getSVal(R) != V)
|
||||
return nullptr;
|
||||
|
||||
if (Pred->getState()->getSVal(R) == V) {
|
||||
if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) {
|
||||
Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
|
||||
if (!PS || PS->getLocationValue() != R)
|
||||
return nullptr;
|
||||
@ -1209,6 +1235,7 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
|
||||
// UndefinedVal.)
|
||||
if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
|
||||
if (const auto *VR = dyn_cast<VarRegion>(R)) {
|
||||
|
||||
const auto *Param = cast<ParmVarDecl>(VR->getDecl());
|
||||
|
||||
ProgramStateManager &StateMgr = BRC.getStateManager();
|
||||
|
@ -288,18 +288,24 @@ static void pdbMakeAbsolute(SmallVectorImpl<char> &FileName) {
|
||||
// It's not absolute in any path syntax. Relative paths necessarily refer to
|
||||
// the local file system, so we can make it native without ending up with a
|
||||
// nonsensical path.
|
||||
sys::path::native(FileName);
|
||||
if (Config->PDBSourcePath.empty()) {
|
||||
sys::path::native(FileName);
|
||||
sys::fs::make_absolute(FileName);
|
||||
return;
|
||||
}
|
||||
// Only apply native and dot removal to the relative file path. We want to
|
||||
// leave the path the user specified untouched since we assume they specified
|
||||
// it for a reason.
|
||||
sys::path::remove_dots(FileName, /*remove_dot_dots=*/true);
|
||||
|
||||
// Try to guess whether /PDBSOURCEPATH is a unix path or a windows path.
|
||||
// Since PDB's are more of a Windows thing, we make this conservative and only
|
||||
// decide that it's a unix path if we're fairly certain. Specifically, if
|
||||
// it starts with a forward slash.
|
||||
SmallString<128> AbsoluteFileName = Config->PDBSourcePath;
|
||||
sys::path::append(AbsoluteFileName, FileName);
|
||||
sys::path::Style GuessedStyle = AbsoluteFileName.startswith("/")
|
||||
? sys::path::Style::posix
|
||||
: sys::path::Style::windows;
|
||||
sys::path::append(AbsoluteFileName, GuessedStyle, FileName);
|
||||
sys::path::native(AbsoluteFileName, GuessedStyle);
|
||||
sys::path::remove_dots(AbsoluteFileName, true, GuessedStyle);
|
||||
|
||||
FileName = std::move(AbsoluteFileName);
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,7 @@ static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
|
||||
.Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
|
||||
.Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
|
||||
.Case("elf32lriscv", {ELF32LEKind, EM_RISCV})
|
||||
.Case("elf32ppc", {ELF32BEKind, EM_PPC})
|
||||
.Cases("elf32ppc", "elf32ppclinux", {ELF32BEKind, EM_PPC})
|
||||
.Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
|
||||
.Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
|
||||
.Case("elf64lriscv", {ELF64LEKind, EM_RISCV})
|
||||
|
@ -392,10 +392,11 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
|
||||
.Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
|
||||
.Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
|
||||
.Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
|
||||
.Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
|
||||
.Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
|
||||
.Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
|
||||
.Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
|
||||
.Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS})
|
||||
.Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
|
||||
.Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
|
||||
.Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
|
||||
.Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
|
||||
|
@ -13,10 +13,12 @@ lld 8.0.0 Release Notes
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document contains the release notes for the lld linker, release 8.0.0.
|
||||
Here we describe the status of lld, including major improvements
|
||||
from the previous release. All lld releases may be downloaded
|
||||
from the `LLVM releases web site <https://llvm.org/releases/>`_.
|
||||
lld is a high-performance linker that supports ELF (Unix), COFF (Windows),
|
||||
Mach-O (macOS), MinGW and WebAssembly. lld is command-line-compatible with
|
||||
GNU linkers and Microsoft link.exe and is significantly faster than the
|
||||
system default linkers.
|
||||
|
||||
nlld 8.0.0 has lots of feature improvements and bug fixes.
|
||||
|
||||
Non-comprehensive list of changes in this release
|
||||
=================================================
|
||||
@ -33,27 +35,66 @@ ELF Improvements
|
||||
non-superpages to a superpage if they are aligned to the superpage
|
||||
size. (`r342746 <https://reviews.llvm.org/rL342746>`_)
|
||||
|
||||
* lld now attempts to place a ``.note`` segment in the first page of a
|
||||
generated file, so that you can find some important information
|
||||
(``.note.gnu.build-id`` in particular) in a core file even if a core
|
||||
file is truncated by ulimit.
|
||||
(`r349524 <https://reviews.llvm.org/rL349524>`_)
|
||||
|
||||
* lld now reports an error if ``_GLOBAL_OFFSET_TABLE_`` symbol is
|
||||
defined by an input object file, as the symbol is supposed to be
|
||||
synthesized by the linker.
|
||||
(`r347854 <https://reviews.llvm.org/rL347854>`_)
|
||||
|
||||
* lld/Hexagon can now link Linux kernel and musl libc for Qualcomm
|
||||
Hexagon ISA.
|
||||
|
||||
* Initial MSP430 ISA support has landed.
|
||||
|
||||
* The following flags have been added: ``-z interpose``, ``-z global``
|
||||
|
||||
* lld now uses the ``sigrie`` instruction as a trap instruction for
|
||||
MIPS targets.
|
||||
|
||||
* lld now creates a TLS segment for AArch64 with a slightly larger
|
||||
alignment requirement, so that the loader makes a few bytes room
|
||||
before each TLS segment at runtime. The aim of this change is to
|
||||
make room to accomodate nonstandard Android TLS slots while keeping
|
||||
the compatibility with the standard AArch64 ABI.
|
||||
(`r350681 <https://reviews.llvm.org/rL350681>`_)
|
||||
|
||||
* The following flags have been added: ``--call-graph-profile``,
|
||||
``--no-call-graph-profile``, ``--warn-ifunc-textrel``,
|
||||
``-z interpose``, ``-z global``, ``-z nodefaultlib``
|
||||
|
||||
COFF Improvements
|
||||
-----------------
|
||||
|
||||
* PDB GUID is set to hash of PDB contents instead to a random byte
|
||||
sequence for build reproducibility.
|
||||
|
||||
* ``/pdbsourcepath:`` is now also used to make ``"cwd"``, ``"exe"``, ``"pdb"``
|
||||
in the env block of PDB outputs absolute if they are relative, and to make
|
||||
paths to obj files referenced in PDB outputs absolute if they are relative.
|
||||
Together with the previous item, this makes it possible to generate
|
||||
executables and PDBs that are fully deterministic and independent of the
|
||||
absolute path to the build directory, so that different machines building
|
||||
the same code in different directories can produce exactly the same output.
|
||||
|
||||
* The following flags have been added: ``/force:multiple``
|
||||
|
||||
* lld now can link against import libraries produced by GNU tools.
|
||||
|
||||
* lld can create thunks for ARM, to allow linking images over 16 MB.
|
||||
* lld can create thunks for ARM and ARM64, to allow linking larger images
|
||||
(over 16 MB for ARM and over 128 MB for ARM64)
|
||||
|
||||
* Several speed and memory usage improvements.
|
||||
|
||||
* lld now creates debug info for typedefs.
|
||||
|
||||
* lld can now link obj files produced by ``cl.exe /Z7 /Yc``.
|
||||
|
||||
* lld now understands ``%_PDB%`` and ``%_EXT%`` in ``/pdbaltpath:``.
|
||||
|
||||
* Undefined symbols are now printed in demangled form in addition to raw form.
|
||||
|
||||
MinGW Improvements
|
||||
------------------
|
||||
@ -76,11 +117,6 @@ MinGW Improvements
|
||||
Previously, the ``--build-id`` option did not actually generate a build id
|
||||
unless ``--pdb`` was specified.
|
||||
|
||||
MachO Improvements
|
||||
------------------
|
||||
|
||||
* Item 1.
|
||||
|
||||
WebAssembly Improvements
|
||||
------------------------
|
||||
|
||||
|
@ -173,4 +173,5 @@ document soon.
|
||||
AtomLLD
|
||||
WebAssembly
|
||||
windows_support
|
||||
missingkeyfunction
|
||||
ReleaseNotes
|
||||
|
@ -1,5 +1,5 @@
|
||||
Missing Key Method
|
||||
==================
|
||||
Missing Key Function
|
||||
====================
|
||||
|
||||
If your build failed with a linker error something like this::
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#define FREEBSD_CC_VERSION 1300002
|
||||
#define FREEBSD_CC_VERSION 1300003
|
||||
|
@ -8,4 +8,4 @@
|
||||
|
||||
#define CLANG_VENDOR "FreeBSD "
|
||||
|
||||
#define SVN_REVISION "353167"
|
||||
#define SVN_REVISION "354130"
|
||||
|
@ -7,4 +7,4 @@
|
||||
|
||||
#define LLD_REPOSITORY_STRING "FreeBSD"
|
||||
// <Upstream revision at import>-<Local identifier in __FreeBSD_version style>
|
||||
#define LLD_REVISION_STRING "353167-1300002"
|
||||
#define LLD_REVISION_STRING "354130-1300002"
|
||||
|
@ -1,2 +1,2 @@
|
||||
/* $FreeBSD$ */
|
||||
#define LLVM_REVISION "svn-r353167"
|
||||
#define LLVM_REVISION "svn-r354130"
|
||||
|
Loading…
Reference in New Issue
Block a user