Merge llvm, clang, compiler-rt, libc++, lld, and lldb release_80 branch

r354130, resolve conflicts, and bump version numbers.
This commit is contained in:
Dimitry Andric 2019-02-15 21:44:42 +00:00
68 changed files with 814 additions and 509 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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; }

View File

@ -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
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.setUnavailable(LibFunc_cabsf);
TLI.setUnavailable(LibFunc_cabsl);
TLI.setUnavailable(LibFunc_cbrt);
TLI.setUnavailable(LibFunc_cbrtf);
TLI.setUnavailable(LibFunc_cbrtl);
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_log1p);
TLI.setUnavailable(LibFunc_log1pf);
TLI.setUnavailable(LibFunc_log1pl);
TLI.setUnavailable(LibFunc_logb);
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);
// Win32 does not fully support C99 math functions.
if (!hasPartialC99) {
TLI.setUnavailable(LibFunc_acosh);
TLI.setUnavailable(LibFunc_acoshf);
TLI.setUnavailable(LibFunc_asinh);
TLI.setUnavailable(LibFunc_asinhf);
TLI.setUnavailable(LibFunc_atanh);
TLI.setUnavailable(LibFunc_atanhf);
TLI.setAvailableWithName(LibFunc_cabs, "_cabs");
TLI.setUnavailable(LibFunc_cabsf);
TLI.setUnavailable(LibFunc_cbrt);
TLI.setUnavailable(LibFunc_cbrtf);
TLI.setAvailableWithName(LibFunc_copysign, "_copysign");
TLI.setAvailableWithName(LibFunc_copysignf, "_copysignf");
TLI.setUnavailable(LibFunc_exp2);
TLI.setUnavailable(LibFunc_exp2f);
TLI.setUnavailable(LibFunc_expm1);
TLI.setUnavailable(LibFunc_expm1f);
TLI.setUnavailable(LibFunc_fmax);
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);
TLI.setUnavailable(LibFunc_fmin);
TLI.setUnavailable(LibFunc_fminf);
TLI.setUnavailable(LibFunc_log1p);
TLI.setUnavailable(LibFunc_log1pf);
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_rint);
TLI.setUnavailable(LibFunc_rintf);
TLI.setUnavailable(LibFunc_round);
TLI.setUnavailable(LibFunc_roundf);
TLI.setUnavailable(LibFunc_trunc);
TLI.setUnavailable(LibFunc_truncf);
}
// 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()) {

View File

@ -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;

View File

@ -3364,10 +3364,11 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
}
if (FileNumber == -1) {
if (!getContext().getAsmInfo()->hasSingleParameterDotFile())
return Error(DirectiveLoc,
"target does not support '.file' without a number");
getStreamer().EmitFileDirective(Filename);
// 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,
// we turn off the -g option, directly use the existing debug info instead.

View 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();

View File

@ -505,9 +505,13 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
Function.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
Info.Name = readString(Ctx);
else
Info.Name = Import.Field;
Signature = &Signatures[Import.SigIndex];
Info.Name = Import.Field;
Info.Module = Import.Module;
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];
Info.Name = Import.Field;
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;
}

View File

@ -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

View File

@ -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()) {

View File

@ -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;

View File

@ -649,10 +649,12 @@ def FPR128Op : RegisterOperand<FPR128, "printOperand"> {
// ARMv8.1a atomic CASP register operands
def WSeqPairs : RegisterTuples<[sube32, subo32],
[(rotl GPR32, 0), (rotl GPR32, 1)]>;
def XSeqPairs : RegisterTuples<[sube64, subo64],
[(rotl GPR64, 0), (rotl GPR64, 1)]>;
def WSeqPairs : RegisterTuples<[sube32, subo32],
[(decimate (rotl GPR32, 0), 2),
(decimate (rotl GPR32, 1), 2)]>;
def XSeqPairs : RegisterTuples<[sube64, subo64],
[(decimate (rotl GPR64, 0), 2),
(decimate (rotl GPR64, 1), 2)]>;
def WSeqPairsClass : RegisterClass<"AArch64", [untyped], 32,
(add WSeqPairs)>{

View File

@ -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;
}

View File

@ -5618,55 +5618,96 @@ 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;
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();
auto *ICmp = CCReg.getNode();
if (ICmp->getOpcode() != SystemZISD::ICMP)
return false;
SDNode *Select = ICmp->getOperand(0).getNode();
if (Select->getOpcode() != SystemZISD::SELECT_CCMASK)
auto *CompareLHS = ICmp->getOperand(0).getNode();
auto *CompareRHS = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
if (!CompareRHS)
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));
if (!TrueVal)
return false;
auto *FalseVal = dyn_cast<ConstantSDNode>(Select->getOperand(1));
if (!FalseVal)
return false;
if (CompareVal->getZExtValue() == FalseVal->getZExtValue())
Invert = !Invert;
else if (CompareVal->getZExtValue() != TrueVal->getZExtValue())
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;
// 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));
if (!NewCCValid || !NewCCMask)
return false;
CCValid = NewCCValid->getZExtValue();
CCMask = NewCCMask->getZExtValue();
if (Invert)
CCMask ^= CCValid;
// Verify that the ICMP compares against one of select values.
auto *TrueVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(0));
if (!TrueVal)
return false;
auto *FalseVal = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(1));
if (!FalseVal)
return false;
if (CompareRHS->getZExtValue() == FalseVal->getZExtValue())
Invert = !Invert;
else if (CompareRHS->getZExtValue() != TrueVal->getZExtValue())
return false;
// Return the updated CCReg link.
CCReg = Select->getOperand(4);
return true;
// Compute the effective CC mask for the new branch or select.
auto *NewCCValid = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(2));
auto *NewCCMask = dyn_cast<ConstantSDNode>(CompareLHS->getOperand(3));
if (!NewCCValid || !NewCCMask)
return false;
CCValid = NewCCValid->getZExtValue();
CCMask = NewCCMask->getZExtValue();
if (Invert)
CCMask ^= CCValid;
// Return the updated CCReg link.
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(

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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());
MainWrapper->setName("main");
MainWrapper->setLinkage(Main->getLinkage());
MainWrapper->setVisibility(Main->getVisibility());
Main->setLinkage(Function::PrivateLinkage);
Main->setVisibility(Function::DefaultVisibility);
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());
}
}
return true;

View File

@ -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.

View File

@ -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];
}

View File

@ -3652,7 +3652,40 @@ 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.
}];
}
def ArtificialDocs : Documentation {

View File

@ -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

View File

@ -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<

View File

@ -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;
}
@ -133,6 +138,6 @@ class OpenCLOptions {
friend class ASTReader;
};
} // end namespace clang
} // end namespace clang
#endif

View File

@ -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">,

View File

@ -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;

View File

@ -1369,7 +1369,6 @@ class Sema {
void PopCompoundScope();
sema::CompoundScopeInfo &getCurCompoundScope() const;
bool isCurCompoundStmtAStmtExpr() const;
bool hasAnyUnrecoverableErrorsInThisFunction() const;
@ -3690,17 +3689,16 @@ 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 =
ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
/*DiscardedValue*/ true);
ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(),
/*DiscardedValue*/ true);
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.

View File

@ -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.

View File

@ -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 });
}

View File

@ -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);

View File

@ -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;

View File

@ -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())

View File

@ -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

View File

@ -1059,10 +1059,9 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// OpenCL definitions.
if (LangOpts.OpenCL) {
#define OPENCLEXT(Ext) \
if (TI.getSupportedOpenCLOpts().isSupported(#Ext, \
LangOpts.OpenCLVersion)) \
Builder.defineMacro(#Ext);
#define OPENCLEXT(Ext) \
if (TI.getSupportedOpenCLOpts().isSupported(#Ext, LangOpts)) \
Builder.defineMacro(#Ext);
#include "clang/Basic/OpenCLExtensions.def"
auto Arch = TI.getTriple().getArch();

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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)) {

View File

@ -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.

View File

@ -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);

View File

@ -10622,16 +10622,16 @@ 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() &&
// We don't want to warn for system macro.
!S.SourceMgr.isInSystemMacro(E->getOperatorLoc()))
// 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.
DiagnoseImpCast(S, E->getRHS(), E->getLHS()->getType(), E->getOperatorLoc(),
diag::warn_impcast_float_result_precision);

View File

@ -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;

View File

@ -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;

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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());

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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.
///
@ -3269,8 +3269,8 @@ class TreeTransform {
bool DeducibleTSTContext);
};
template <typename Derived>
StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) {
template<typename Derived>
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.

View File

@ -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();

View File

@ -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);
}

View File

@ -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})

View File

@ -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})

View File

@ -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
------------------------

View File

@ -173,4 +173,5 @@ document soon.
AtomLLD
WebAssembly
windows_support
missingkeyfunction
ReleaseNotes

View File

@ -1,5 +1,5 @@
Missing Key Method
==================
Missing Key Function
====================
If your build failed with a linker error something like this::

View File

@ -1,3 +1,3 @@
/* $FreeBSD$ */
#define FREEBSD_CC_VERSION 1300002
#define FREEBSD_CC_VERSION 1300003

View File

@ -8,4 +8,4 @@
#define CLANG_VENDOR "FreeBSD "
#define SVN_REVISION "353167"
#define SVN_REVISION "354130"

View File

@ -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"

View File

@ -1,2 +1,2 @@
/* $FreeBSD$ */
#define LLVM_REVISION "svn-r353167"
#define LLVM_REVISION "svn-r354130"