83 changes: 83 additions & 0 deletions bolt/test/AArch64/test-indirect-branch.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
// Test how BOLT handles indirect branch sequence of instructions in
// AArch64MCPlus builder.

// clang-format off

// REQUIRES: system-linux
// RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
// RUN: %clang %cflags --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q
// RUN: llvm-bolt %t.exe -o %t.bolt --print-cfg --strict\
// RUN: -v=1 2>&1 | FileCheck %s

// Pattern 1: there is no shift amount after the 'add' instruction.
//
// adr x6, 0x219fb0 <sigall_set+0x88>
// add x6, x6, x14, lsl #2
// ldr w7, [x6]
// add x6, x6, w7, sxtw => no shift amount
// br x6
//

// Pattern 2: nop/adr pair is used in place of adrp/add
//
// nop => nop/adr instead of adrp/add
// adr x13, 0x215a18 <_nl_value_type_LC_COLLATE+0x50>
// ldrh w13, [x13, w12, uxtw #1]
// adr x12, 0x247b30 <__gettextparse+0x5b0>
// add x13, x12, w13, sxth #2
// br x13

.section .text
.align 4
.globl _start
.type _start, %function
_start:
bl test1
bl test2
// mov x0, #4
// mov w8, #93
// svc #0

// Pattern 1
// CHECK: BOLT-WARNING: Failed to match indirect branch: ShiftVAL != 2
.globl test1
.type test1, %function
test1:
mov x1, #0
adr x3, datatable
add x3, x3, x1, lsl #2
ldr w2, [x3]
add x3, x3, w2, sxtw
br x3
test1_0:
ret
test1_1:
ret
test1_2:
ret

// Pattern 2
// CHECK: BOLT-WARNING: Failed to match indirect branch: nop/adr instead of adrp/add
.globl test2
.type test2, %function
test2:
nop
adr x3, jump_table
ldrh w3, [x3, x1, lsl #1]
adr x1, test2_0
add x3, x1, w3, sxth #2
br x3
test2_0:
ret
test2_1:
ret

.section .rodata,"a",@progbits
datatable:
.word test1_0-datatable
.word test1_1-datatable
.word test1_2-datatable

jump_table:
.hword (test2_0-test2_0)>>2
.hword (test2_1-test2_0)>>2
4 changes: 4 additions & 0 deletions bolt/test/X86/register-fragments-bolt-symbols.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@
# PREAGGWARM: B X:0 #chain.warm# 1 0
# RUN: perf2bolt %t.warm.bolt -p %t.preagg.warm --pa -o %t.warm.fdata -w %t.warm.yaml \
# RUN: -v=1 | FileCheck %s --check-prefix=CHECK-BOLT-WARM
# RUN: FileCheck %s --input-file %t.warm.fdata --check-prefix=CHECK-FDATA-WARM
# RUN: FileCheck %s --input-file %t.warm.yaml --check-prefix=CHECK-YAML-WARM

# CHECK-BOLT-WARM: marking chain.warm/1(*2) as a fragment of chain
# CHECK-FDATA-WARM: chain
# CHECK-YAML-WARM: chain

# RUN: sed -i 's|chain|chain/2|g' %t.fdata
# RUN: llvm-objcopy --localize-symbol=chain %t.main.o
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/support/ThreadsafeFS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class VolatileFileSystem : public llvm::vfs::ProxyFileSystem {
llvm::StringRef FileName = llvm::sys::path::filename(Path);
if (FileName.starts_with("preamble-") && FileName.ends_with(".pch"))
return File;
return std::unique_ptr<VolatileFile>(new VolatileFile(std::move(*File)));
return std::make_unique<VolatileFile>(std::move(*File));
}

private:
Expand Down
2 changes: 1 addition & 1 deletion clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ if(WIN32 OR LLVM_WINSYSROOT)
set(RUNTIMES_${target}_CMAKE_MODULE_LINKER_FLAGS ${WINDOWS_LINK_FLAGS} CACHE STRING "")
endif()

foreach(target aarch64-unknown-linux-gnu;armv7-unknown-linux-gnueabihf;i386-unknown-linux-gnu;riscv64-unknown-linux-gnu;x86_64-unknown-linux-gnu)
foreach(target aarch64-linux-gnu;armv7-linux-gnueabihf;i386-linux-gnu;riscv64-linux-gnu;x86_64-linux-gnu)
if(LINUX_${target}_SYSROOT)
# Set the per-target builtins options.
list(APPEND BUILTIN_TARGETS "${target}")
Expand Down
18 changes: 15 additions & 3 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,6 @@ C++20 Feature Support
``<expected>`` from libstdc++ to work correctly with Clang.

- User defined constructors are allowed for copy-list-initialization with CTAD.
The example code for deduction guides for std::map in
(`cppreference <https://en.cppreference.com/w/cpp/container/map/deduction_guides>`_)
will now work.
(#GH62925).

C++23 Feature Support
Expand Down Expand Up @@ -272,6 +269,7 @@ C++2c Feature Support

- Implemented `P2809R3: Trivial infinite loops are not Undefined Behavior <https://wg21.link/P2809R3>`_.

- Implemented `P3144R2 Deleting a Pointer to an Incomplete Type Should be Ill-formed <https://wg21.link/P3144R2>`_.

Resolutions to C++ Defect Reports
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -438,6 +436,12 @@ New Compiler Flags
Matches MSVC behaviour by defining ``__STDC__`` to ``1`` when
MSVC compatibility mode is used. It has no effect for C++ code.

- ``-Wc++23-compat`` group was added to help migrating existing codebases
to C++23.

- ``-Wc++2c-compat`` group was added to help migrating existing codebases
to upcoming C++26.

Deprecated Compiler Flags
-------------------------

Expand Down Expand Up @@ -476,6 +480,10 @@ Modified Compiler Flags
evaluating to ``true`` and an empty body such as ``while(1);``)
are considered infinite, even when the ``-ffinite-loop`` flag is set.

- Diagnostics groups about compatibility with a particular C++ Standard version
now include dianostics about C++26 features that are not present in older
versions.

Removed Compiler Flags
-------------------------

Expand Down Expand Up @@ -963,6 +971,10 @@ Bug Fixes to C++ Support
- Fixed an assertion failure about invalid conversion when calling lambda. (#GH96205).
- Fixed a bug where the first operand of binary ``operator&`` would be transformed as if it was the operand
of the address of operator. (#GH97483).
- Fixed an assertion failure about a constant expression which is a known integer but is not
evaluated to an integer. (#GH96670).
- Fixed a bug where references to lambda capture inside a ``noexcept`` specifier were not correctly
instantiated. (#GH95735).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/AST/ASTConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace clang {
class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
class TagDecl;
class DeclaratorDecl;
class VarDecl;
class FunctionDecl;
class ImportDecl;
Expand Down Expand Up @@ -105,7 +106,7 @@ class ASTConsumer {
/// CompleteExternalDeclaration - Callback invoked at the end of a translation
/// unit to notify the consumer that the given external declaration should be
/// completed.
virtual void CompleteExternalDeclaration(VarDecl *D) {}
virtual void CompleteExternalDeclaration(DeclaratorDecl *D) {}

/// Callback invoked when an MSInheritanceAttr has been attached to a
/// CXXRecordDecl.
Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Basic/DiagnosticCommonKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,15 @@ def warn_target_unrecognized_env : Warning<
def err_target_unsupported_abi_with_fpu : Error<
"'%0' ABI is not supported with FPU">;

def err_ppc_impossible_musttail: Error<
"'musttail' attribute for this call is impossible because %select{"
"long calls can not be tail called on PPC|"
"indirect calls can not be tail called on PPC|"
"external calls can not be tail called on PPC}0"
>;
def err_aix_musttail_unsupported: Error<
"'musttail' attribute is not supported on AIX">;

// Source manager
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
def err_file_modified : Error<
Expand Down
34 changes: 24 additions & 10 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,8 @@ def CXX98Compat : DiagGroup<"c++98-compat",
CXXPre14Compat,
CXXPre17Compat,
CXXPre20Compat,
CXXPre23Compat]>;
CXXPre23Compat,
CXXPre26Compat]>;
// Warnings for C++11 features which are Extensions in C++98 mode.
def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
[CXX98Compat,
Expand All @@ -353,7 +354,8 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic",
CXXPre14CompatPedantic,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
CXXPre23CompatPedantic]>;
CXXPre23CompatPedantic,
CXXPre26CompatPedantic]>;

def CXX11NarrowingConstReference : DiagGroup<"c++11-narrowing-const-reference">;
def CXX11Narrowing : DiagGroup<"c++11-narrowing", [CXX11NarrowingConstReference]>;
Expand Down Expand Up @@ -384,42 +386,54 @@ def CXX11Compat : DiagGroup<"c++11-compat",
CXXPre14Compat,
CXXPre17Compat,
CXXPre20Compat,
CXXPre23Compat]>;
CXXPre23Compat,
CXXPre26Compat]>;
def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic",
[CXX11Compat,
CXXPre14CompatPedantic,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
CXXPre23CompatPedantic]>;
CXXPre23CompatPedantic,
CXXPre26CompatPedantic]>;

def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat,
CXXPre20Compat,
CXXPre23Compat]>;
CXXPre23Compat,
CXXPre26Compat]>;
def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic",
[CXX14Compat,
CXXPre17CompatPedantic,
CXXPre20CompatPedantic,
CXXPre23CompatPedantic]>;
CXXPre23CompatPedantic,
CXXPre26CompatPedantic]>;

def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister,
DeprecatedIncrementBool,
CXX17CompatMangling,
CXXPre20Compat,
CXXPre23Compat]>;
CXXPre23Compat,
CXXPre26Compat]>;
def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic",
[CXX17Compat,
CXXPre20CompatPedantic,
CXXPre23CompatPedantic]>;
CXXPre23CompatPedantic,
CXXPre26CompatPedantic]>;
def : DiagGroup<"c++1z-compat", [CXX17Compat]>;

def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre23Compat]>;
def CXX20Compat : DiagGroup<"c++20-compat", [CXXPre23Compat,
CXXPre26Compat]>;
def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic",
[CXX20Compat,
CXXPre23CompatPedantic]>;
CXXPre23CompatPedantic,
CXXPre26CompatPedantic]>;
def : DiagGroup<"c++2a-compat", [CXX20Compat]>;
def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>;

def CXX23Compat : DiagGroup<"c++23-compat", [CXXPre26Compat]>;

def CXX26Compat : DiagGroup<"c++2c-compat", [DeleteIncomplete]>;

def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7989,8 +7989,11 @@ def ext_delete_void_ptr_operand : ExtWarn<
def err_ambiguous_delete_operand : Error<
"ambiguous conversion of delete expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behavior">,
"deleting pointer to incomplete type %0 is incompatible with C++2c"
" and may cause undefined behavior">,
InGroup<DeleteIncomplete>;
def err_delete_incomplete : Error<
"cannot delete pointer to incomplete type %0">;
def err_delete_incomplete_class_type : Error<
"deleting incomplete class type %0; no conversions to pointer type">;
def err_delete_explicit_conversion : Error<
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Frontend/MultiplexConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class MultiplexConsumer : public SemaConsumer {
void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
void HandleImplicitImportDecl(ImportDecl *D) override;
void CompleteTentativeDefinition(VarDecl *D) override;
void CompleteExternalDeclaration(VarDecl *D) override;
void CompleteExternalDeclaration(DeclaratorDecl *D) override;
void AssignInheritanceModel(CXXRecordDecl *RD) override;
void HandleVTable(CXXRecordDecl *RD) override;
ASTMutationListener *GetASTMutationListener() override;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -3098,7 +3098,7 @@ class Sema final : public SemaBase {
TentativeDefinitionsType TentativeDefinitions;

/// All the external declarations encoutered and used in the TU.
SmallVector<VarDecl *, 4> ExternalDeclarations;
SmallVector<DeclaratorDecl *, 4> ExternalDeclarations;

/// Generally null except when we temporarily switch decl contexts,
/// like in \see SemaObjC::ActOnObjCTemporaryExitContainerContext.
Expand Down
9 changes: 6 additions & 3 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15859,9 +15859,12 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,

if (const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
if (CE->hasAPValueResult()) {
Result.Val = CE->getAPValueResult();
IsConst = true;
return true;
APValue APV = CE->getAPValueResult();
if (!APV.isLValue()) {
Result.Val = std::move(APV);
IsConst = true;
return true;
}
}

// The SubExpr is usually just an IntegerLiteral.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/Interp/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3995,7 +3995,7 @@ bool Compiler<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
}

for (unsigned I = StartIndex, N = InitStack.size(); I != N; ++I) {
if (!InitStack[I].emit<Emitter>(this, E))
if (!InitStack[I].template emit<Emitter>(this, E))
return false;
}
return true;
Expand Down
14 changes: 7 additions & 7 deletions clang/lib/AST/JSONNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ void JSONNodeDumper::Visit(const APValue &Value, QualType Ty) {
std::string Str;
llvm::raw_string_ostream OS(Str);
Value.printPretty(OS, Ctx, Ty);
JOS.attribute("value", OS.str());
JOS.attribute("value", Str);
}

void JSONNodeDumper::Visit(const ConceptReference *CR) {
Expand Down Expand Up @@ -802,7 +802,7 @@ void JSONNodeDumper::VisitTemplateSpecializationType(
std::string Str;
llvm::raw_string_ostream OS(Str);
TST->getTemplateName().print(OS, PrintPolicy);
JOS.attribute("templateName", OS.str());
JOS.attribute("templateName", Str);
}

void JSONNodeDumper::VisitInjectedClassNameType(
Expand All @@ -824,7 +824,7 @@ void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) {
std::string Str;
llvm::raw_string_ostream OS(Str);
NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true);
JOS.attribute("qualifier", OS.str());
JOS.attribute("qualifier", Str);
}
if (const TagDecl *TD = ET->getOwnedTagDecl())
JOS.attribute("ownedTagDecl", createBareDeclRef(TD));
Expand Down Expand Up @@ -1246,7 +1246,7 @@ void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
llvm::raw_string_ostream OS(Str);

OME->getSelector().print(OS);
JOS.attribute("selector", OS.str());
JOS.attribute("selector", Str);

switch (OME->getReceiverKind()) {
case ObjCMessageExpr::Instance:
Expand Down Expand Up @@ -1277,7 +1277,7 @@ void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {
llvm::raw_string_ostream OS(Str);

MD->getSelector().print(OS);
JOS.attribute("selector", OS.str());
JOS.attribute("selector", Str);
}
}

Expand All @@ -1286,7 +1286,7 @@ void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {
llvm::raw_string_ostream OS(Str);

OSE->getSelector().print(OS);
JOS.attribute("selector", OS.str());
JOS.attribute("selector", Str);
}

void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
Expand Down Expand Up @@ -1634,7 +1634,7 @@ void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
std::string Buffer;
llvm::raw_string_ostream SS(Buffer);
SL->outputString(SS);
JOS.attribute("value", SS.str());
JOS.attribute("value", Buffer);
}
void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
JOS.attribute("value", BLE->getValue());
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasQuadwordAtomics = true;
} else if (Feature == "+aix-shared-lib-tls-model-opt") {
HasAIXShLibTLSModelOpt = true;
} else if (Feature == "+longcall") {
UseLongCalls = true;
}
// TODO: Finish this list and add an assert that we've handled them
// all.
Expand Down Expand Up @@ -728,6 +730,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("isa-v31-instructions", IsISA3_1)
.Case("quadword-atomics", HasQuadwordAtomics)
.Case("aix-shared-lib-tls-model-opt", HasAIXShLibTLSModelOpt)
.Case("longcall", UseLongCalls)
.Default(false);
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
bool IsISA3_1 = false;
bool HasQuadwordAtomics = false;
bool HasAIXShLibTLSModelOpt = false;
bool UseLongCalls = false;

protected:
std::string ABI;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Basic/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,8 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasCF = true;
} else if (Feature == "+zu") {
HasZU = true;
} else if (Feature == "+branch-hint") {
HasBranchHint = true;
}

X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
Expand Down Expand Up @@ -1292,6 +1294,7 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("nf", HasNF)
.Case("cf", HasCF)
.Case("zu", HasZU)
.Case("branch-hint", HasBranchHint)
.Default(false);
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasCF = false;
bool HasZU = false;
bool HasInlineAsmUseGPR32 = false;
bool HasBranchHint = false;

protected:
llvm::X86::CPUKind CPU = llvm::X86::CK_None;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/BackendConsumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class BackendConsumer : public ASTConsumer {
void HandleTagDeclDefinition(TagDecl *D) override;
void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
void CompleteTentativeDefinition(VarDecl *D) override;
void CompleteExternalDeclaration(VarDecl *D) override;
void CompleteExternalDeclaration(DeclaratorDecl *D) override;
void AssignInheritanceModel(CXXRecordDecl *RD) override;
void HandleVTable(CXXRecordDecl *RD) override;

Expand Down
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5888,12 +5888,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
case Builtin::BI__builtin_printf:
case Builtin::BIprintf:
if (getTarget().getTriple().isNVPTX() ||
getTarget().getTriple().isAMDGCN()) {
getTarget().getTriple().isAMDGCN() ||
(getTarget().getTriple().isSPIRV() &&
getTarget().getTriple().getVendor() == Triple::VendorType::AMD)) {
if (getLangOpts().OpenMPIsTargetDevice)
return EmitOpenMPDevicePrintfCallExpr(E);
if (getTarget().getTriple().isNVPTX())
return EmitNVPTXDevicePrintfCallExpr(E);
if (getTarget().getTriple().isAMDGCN() && getLangOpts().HIP)
if ((getTarget().getTriple().isAMDGCN() ||
getTarget().getTriple().isSPIRV()) &&
getLangOpts().HIP)
return EmitAMDGPUDevicePrintfCallExpr(E);
}

Expand Down
29 changes: 28 additions & 1 deletion clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5751,8 +5751,35 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) {
if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>())
Call->setTailCallKind(llvm::CallInst::TCK_NoTail);
else if (IsMustTail)
else if (IsMustTail) {
if (getTarget().getTriple().isPPC()) {
if (getTarget().getTriple().isOSAIX())
CGM.getDiags().Report(Loc, diag::err_aix_musttail_unsupported);
else if (!getTarget().hasFeature("pcrelative-memops")) {
if (getTarget().hasFeature("longcall"))
CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 0;
else if (Call->isIndirectCall())
CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail) << 1;
else if (isa_and_nonnull<FunctionDecl>(TargetDecl)) {
if (!cast<FunctionDecl>(TargetDecl)->isDefined())
// The undefined callee may be a forward declaration. Without
// knowning all symbols in the module, we won't know the symbol is
// defined or not. Collect all these symbols for later diagnosing.
CGM.addUndefinedGlobalForTailCall(
{cast<FunctionDecl>(TargetDecl), Loc});
else {
llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(
GlobalDecl(cast<FunctionDecl>(TargetDecl)));
if (llvm::GlobalValue::isWeakForLinker(Linkage) ||
llvm::GlobalValue::isDiscardableIfUnused(Linkage))
CGM.getDiags().Report(Loc, diag::err_ppc_impossible_musttail)
<< 2;
}
}
}
}
Call->setTailCallKind(llvm::CallInst::TCK_MustTail);
}
}

// Add metadata for calls to MSAllocator functions
Expand Down
17 changes: 2 additions & 15 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3141,21 +3141,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
return LV;
}

if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
LValue LV = EmitFunctionDeclLValue(*this, E, FD);

// Emit debuginfo for the function declaration if the target wants to.
if (getContext().getTargetInfo().allowDebugInfoForExternalRef()) {
if (CGDebugInfo *DI = CGM.getModuleDebugInfo()) {
auto *Fn =
cast<llvm::Function>(LV.getPointer(*this)->stripPointerCasts());
if (!Fn->getSubprogram())
DI->EmitFunctionDecl(FD, FD->getLocation(), T, Fn);
}
}

return LV;
}
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
return EmitFunctionDeclLValue(*this, E, FD);

// FIXME: While we're emitting a binding from an enclosing scope, all other
// DeclRefExprs we see should be implicitly treated as if they also refer to
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/CodeGen/CGGPUBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ RValue CodeGenFunction::EmitNVPTXDevicePrintfCallExpr(const CallExpr *E) {
}

RValue CodeGenFunction::EmitAMDGPUDevicePrintfCallExpr(const CallExpr *E) {
assert(getTarget().getTriple().getArch() == llvm::Triple::amdgcn);
assert(getTarget().getTriple().isAMDGCN() ||
(getTarget().getTriple().isSPIRV() &&
getTarget().getTriple().getVendor() == llvm::Triple::AMD));
assert(E->getBuiltinCallee() == Builtin::BIprintf ||
E->getBuiltinCallee() == Builtin::BI__builtin_printf);
assert(E->getNumArgs() >= 1); // printf always has at least one arg.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ void BackendConsumer::CompleteTentativeDefinition(VarDecl *D) {
Gen->CompleteTentativeDefinition(D);
}

void BackendConsumer::CompleteExternalDeclaration(VarDecl *D) {
void BackendConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) {
Gen->CompleteExternalDeclaration(D);
}

Expand Down
34 changes: 32 additions & 2 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,21 @@ void CodeGenModule::Release() {
// that might affect the DLL storage class or the visibility, and
// before anything that might act on these.
setVisibilityFromDLLStorageClass(LangOpts, getModule());

// Check the tail call symbols are truly undefined.
if (getTriple().isPPC() && !MustTailCallUndefinedGlobals.empty()) {
for (auto &I : MustTailCallUndefinedGlobals) {
if (!I.first->isDefined())
getDiags().Report(I.second, diag::err_ppc_impossible_musttail) << 2;
else {
StringRef MangledName = getMangledName(GlobalDecl(I.first));
llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
if (!Entry || Entry->isWeakForLinker() ||
Entry->isDeclarationForLinker())
getDiags().Report(I.second, diag::err_ppc_impossible_musttail) << 2;
}
}
}
}

void CodeGenModule::EmitOpenCLMetadata() {
Expand Down Expand Up @@ -5185,8 +5200,11 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
EmitGlobalVarDefinition(D);
}

void CodeGenModule::EmitExternalDeclaration(const VarDecl *D) {
EmitExternalVarDeclaration(D);
void CodeGenModule::EmitExternalDeclaration(const DeclaratorDecl *D) {
if (auto const *V = dyn_cast<const VarDecl>(D))
EmitExternalVarDeclaration(V);
if (auto const *FD = dyn_cast<const FunctionDecl>(D))
EmitExternalFunctionDeclaration(FD);
}

CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
Expand Down Expand Up @@ -5622,6 +5640,18 @@ void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
}
}

void CodeGenModule::EmitExternalFunctionDeclaration(const FunctionDecl *FD) {
if (CGDebugInfo *DI = getModuleDebugInfo())
if (getCodeGenOpts().hasReducedDebugInfo()) {
auto *Ty = getTypes().ConvertType(FD->getType());
StringRef MangledName = getMangledName(FD);
auto *Fn = dyn_cast<llvm::Function>(
GetOrCreateLLVMFunction(MangledName, Ty, FD, /* ForVTable */ false));
if (!Fn->getSubprogram())
DI->EmitFunctionDecl(FD, FD->getLocation(), FD->getType(), Fn);
}
}

static bool isVarDeclStrongDefinition(const ASTContext &Context,
CodeGenModule &CGM, const VarDecl *D,
bool NoCommon) {
Expand Down
16 changes: 15 additions & 1 deletion clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,14 @@ class CodeGenModule : public CodeGenTypeCache {
typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
GlobalInitData;

// When a tail call is performed on an "undefined" symbol, on PPC without pc
// relative feature, the tail call is not allowed. In "EmitCall" for such
// tail calls, the "undefined" symbols may be forward declarations, their
// definitions are provided in the module after the callsites. For such tail
// calls, diagnose message should not be emitted.
llvm::SmallSetVector<std::pair<const FunctionDecl *, SourceLocation>, 4>
MustTailCallUndefinedGlobals;

struct GlobalInitPriorityCmp {
bool operator()(const GlobalInitData &LHS,
const GlobalInitData &RHS) const {
Expand Down Expand Up @@ -1338,7 +1346,7 @@ class CodeGenModule : public CodeGenTypeCache {

void EmitTentativeDefinition(const VarDecl *D);

void EmitExternalDeclaration(const VarDecl *D);
void EmitExternalDeclaration(const DeclaratorDecl *D);

void EmitVTable(CXXRecordDecl *Class);

Expand Down Expand Up @@ -1647,6 +1655,11 @@ class CodeGenModule : public CodeGenTypeCache {
return getTriple().isSPIRVLogical();
}

void addUndefinedGlobalForTailCall(
std::pair<const FunctionDecl *, SourceLocation> Global) {
MustTailCallUndefinedGlobals.insert(Global);
}

private:
bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const;

Expand Down Expand Up @@ -1690,6 +1703,7 @@ class CodeGenModule : public CodeGenTypeCache {

void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
void EmitExternalVarDeclaration(const VarDecl *D);
void EmitExternalFunctionDeclaration(const FunctionDecl *D);
void EmitAliasDefinition(GlobalDecl GD);
void emitIFuncDefinition(GlobalDecl GD);
void emitCPUDispatchDefinition(GlobalDecl GD);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/ModuleBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ namespace {
Builder->EmitTentativeDefinition(D);
}

void CompleteExternalDeclaration(VarDecl *D) override {
void CompleteExternalDeclaration(DeclaratorDecl *D) override {
Builder->EmitExternalDeclaration(D);
}

Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3029,7 +3029,7 @@ void Darwin::addClangCC1ASTargetOptions(
std::string Arg;
llvm::raw_string_ostream OS(Arg);
OS << "-target-sdk-version=" << V;
CC1ASArgs.push_back(Args.MakeArgString(OS.str()));
CC1ASArgs.push_back(Args.MakeArgString(Arg));
};

if (isTargetMacCatalyst()) {
Expand All @@ -3052,7 +3052,7 @@ void Darwin::addClangCC1ASTargetOptions(
std::string Arg;
llvm::raw_string_ostream OS(Arg);
OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();
CC1ASArgs.push_back(Args.MakeArgString(OS.str()));
CC1ASArgs.push_back(Args.MakeArgString(Arg));
} else if (const auto *MacOStoMacCatalystMapping =
SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
Expand All @@ -3063,7 +3063,7 @@ void Darwin::addClangCC1ASTargetOptions(
std::string Arg;
llvm::raw_string_ostream OS(Arg);
OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;
CC1ASArgs.push_back(Args.MakeArgString(OS.str()));
CC1ASArgs.push_back(Args.MakeArgString(Arg));
}
}
}
Expand Down
15 changes: 11 additions & 4 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3222,10 +3222,16 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,
if (Trimmed.contains(RawStringTermination))
FormattingOff = false;

if (isClangFormatOff(Trimmed))
bool IsBlockComment = false;

if (isClangFormatOff(Trimmed)) {
FormattingOff = true;
else if (isClangFormatOn(Trimmed))
} else if (isClangFormatOn(Trimmed)) {
FormattingOff = false;
} else if (Trimmed.starts_with("/*")) {
IsBlockComment = true;
Pos = Code.find("*/", SearchFrom + 2);
}

const bool EmptyLineSkipped =
Trimmed.empty() &&
Expand All @@ -3235,9 +3241,10 @@ tooling::Replacements sortCppIncludes(const FormatStyle &Style, StringRef Code,

bool MergeWithNextLine = Trimmed.ends_with("\\");
if (!FormattingOff && !MergeWithNextLine) {
if (tooling::HeaderIncludes::IncludeRegex.match(Line, &Matches)) {
if (!IsBlockComment &&
tooling::HeaderIncludes::IncludeRegex.match(Trimmed, &Matches)) {
StringRef IncludeName = Matches[2];
if (Line.contains("/*") && !Line.contains("*/")) {
if (Trimmed.contains("/*") && !Trimmed.contains("*/")) {
// #include with a start of a block comment, but without the end.
// Need to keep all the lines until the end of the comment together.
// FIXME: This is somehow simplified check that probably does not work
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Frontend/MultiplexConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
Consumer->CompleteTentativeDefinition(D);
}

void MultiplexConsumer::CompleteExternalDeclaration(VarDecl *D) {
void MultiplexConsumer::CompleteExternalDeclaration(DeclaratorDecl *D) {
for (auto &Consumer : Consumers)
Consumer->CompleteExternalDeclaration(D);
}
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,9 @@ namespace {
std::string SStr;
llvm::raw_string_ostream S(SStr);
New->printPretty(S, nullptr, PrintingPolicy(LangOpts));
const std::string &Str = S.str();

// If replacement succeeded or warning disabled return with no warning.
if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, SStr)) {
ReplacedNodes[Old] = New;
return;
}
Expand Down Expand Up @@ -2581,7 +2580,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
std::string prettyBufS;
llvm::raw_string_ostream prettyBuf(prettyBufS);
Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts));
Preamble += prettyBuf.str();
Preamble += prettyBufS;
Preamble += ",";
Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";

Expand Down Expand Up @@ -4414,7 +4413,7 @@ void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
llvm::raw_string_ostream constructorExprBuf(SStr);
GlobalConstructionExp->printPretty(constructorExprBuf, nullptr,
PrintingPolicy(LangOpts));
globalBuf += constructorExprBuf.str();
globalBuf += SStr;
globalBuf += ";\n";
InsertText(FunLocStart, globalBuf);
GlobalConstructionExp = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Interpreter/IncrementalParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class IncrementalASTConsumer final : public ASTConsumer {
void CompleteTentativeDefinition(VarDecl *D) override final {
Consumer->CompleteTentativeDefinition(D);
}
void CompleteExternalDeclaration(VarDecl *D) override final {
void CompleteExternalDeclaration(DeclaratorDecl *D) override final {
Consumer->CompleteExternalDeclaration(D);
}
void AssignInheritanceModel(CXXRecordDecl *RD) override final {
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2117,8 +2117,6 @@ static void AddOverrideResults(ResultBuilder &Results,
// Generates a new CodeCompletionResult by taking this function and
// converting it into an override declaration with only one chunk in the
// final CodeCompletionString as a TypedTextChunk.
std::string OverrideSignature;
llvm::raw_string_ostream OS(OverrideSignature);
CodeCompletionResult CCR(Method, 0);
PrintingPolicy Policy =
getCompletionPrintingPolicy(S.getASTContext(), S.getPreprocessor());
Expand Down Expand Up @@ -3186,7 +3184,6 @@ static void AddTemplateParameterChunks(
else if (const auto *TC = TTP->getTypeConstraint()) {
llvm::raw_string_ostream OS(PlaceholderStr);
TC->print(OS, Policy);
OS.flush();
} else
PlaceholderStr = "class";

Expand Down Expand Up @@ -4025,7 +4022,7 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
std::string Name;
llvm::raw_string_ostream OS(Name);
FDecl->getDeclName().print(OS, Policy);
Result.AddTextChunk(Result.getAllocator().CopyString(OS.str()));
Result.AddTextChunk(Result.getAllocator().CopyString(Name));
} else {
// Function without a declaration. Just give the return type.
Result.AddResultTypeChunk(Result.getAllocator().CopyString(
Expand Down Expand Up @@ -4343,7 +4340,7 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
std::string Str;
llvm::raw_string_ostream OS(Str);
NNS->print(OS, Policy);
Builder.AddTextChunk(Results.getAllocator().CopyString(OS.str()));
Builder.AddTextChunk(Results.getAllocator().CopyString(Str));
}
} else if (!InContext->Equals(Overridden->getDeclContext()))
continue;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10818,6 +10818,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
break;
}

// Similar to no_builtin logic above, at this point of the code
// FunctionDecl::isThisDeclarationADefinition() always returns `false`
// because Sema::ActOnStartOfFunctionDef has not been called yet.
if (Context.getTargetInfo().allowDebugInfoForExternalRef() &&
!NewFD->isInvalidDecl() &&
D.getFunctionDefinitionKind() == FunctionDefinitionKind::Declaration)
ExternalDeclarations.push_back(NewFD);

return NewFD;
}

Expand Down
12 changes: 9 additions & 3 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3719,8 +3719,11 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// The C++ standard bans deleting a pointer to a non-object type, which
// effectively bans deletion of "void*". However, most compilers support
// this, so we treat it as a warning unless we're in a SFINAE context.
Diag(StartLoc, diag::ext_delete_void_ptr_operand)
<< Type << Ex.get()->getSourceRange();
// But we still prohibit this since C++26.
Diag(StartLoc, LangOpts.CPlusPlus26 ? diag::err_delete_incomplete
: diag::ext_delete_void_ptr_operand)
<< (LangOpts.CPlusPlus26 ? Pointee : Type)
<< Ex.get()->getSourceRange();
} else if (Pointee->isFunctionType() || Pointee->isVoidType() ||
Pointee->isSizelessType()) {
return ExprError(Diag(StartLoc, diag::err_delete_operand)
Expand All @@ -3729,7 +3732,10 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
// FIXME: This can result in errors if the definition was imported from a
// module but is hidden.
if (!RequireCompleteType(StartLoc, Pointee,
diag::warn_delete_incomplete, Ex.get())) {
LangOpts.CPlusPlus26
? diag::err_delete_incomplete
: diag::warn_delete_incomplete,
Ex.get())) {
if (const RecordType *RT = PointeeElem->getAs<RecordType>())
PointeeRD = cast<CXXRecordDecl>(RT->getDecl());
}
Expand Down
3 changes: 0 additions & 3 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9811,9 +9811,6 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
// C++ [over.best.ics]p4:
// When [...] the constructor [...] is a candidate by
// - [over.match.copy] (in all cases)
// FIXME: The "second phase of [over.match.list] case can also
// theoretically happen here, but it's not clear whether we can
// ever have a parameter of the right type.
if (TD) {
SmallVector<Expr *, 8> TmpInits;
for (Expr *E : Inits)
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4704,6 +4704,12 @@ void Sema::InstantiateExceptionSpec(SourceLocation PointOfInstantiation,
return;
}

// The noexcept specification could reference any lambda captures. Ensure
// those are added to the LocalInstantiationScope.
LambdaScopeForCallOperatorInstantiationRAII PushLambdaCaptures(
*this, Decl, TemplateArgs, Scope,
/*ShouldAddDeclsFromParentScope=*/false);

SubstExceptionSpec(Decl, Template->getType()->castAs<FunctionProtoType>(),
TemplateArgs);
}
Expand Down
6 changes: 6 additions & 0 deletions clang/test/AST/Interp/records.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,12 @@ namespace DeclRefs {
constexpr B b;
static_assert(b.a.m == 100, "");
static_assert(b.a.f == 100, "");

constexpr B b2;
static_assert(b2.a.m == 100, "");
static_assert(b2.a.f == 100, "");
static_assert(b2.a.f == 101, ""); // both-error {{failed}} \
// both-note {{evaluates to '100 == 101'}}
}

namespace PointerArith {
Expand Down
22 changes: 13 additions & 9 deletions clang/test/CXX/drs/cwg5xx.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-11,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++98 %s -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++11 %s -verify=expected,cxx98-23,cxx98-11,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++14 %s -verify=expected,cxx98-23,cxx98-14,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++17 %s -verify=expected,cxx98-23,since-cxx17,cxx98-17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++20 %s -verify=expected,cxx98-23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++23 %s -verify=expected,cxx98-23,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -std=c++2c %s -verify=expected,since-cxx26,since-cxx23,since-cxx20,since-cxx17,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors

#if __cplusplus == 199711L
#define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
Expand Down Expand Up @@ -901,7 +902,8 @@ namespace cwg573 { // cwg573: no
void *d = reinterpret_cast<void*>(c);
// cxx98-error@-1 {{cast between pointer-to-function and pointer-to-object is an extension}}
void f() { delete a; }
// expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}}
int n = d - a;
// expected-error@-1 {{arithmetic on pointers to void}}
// FIXME: This is ill-formed.
Expand Down Expand Up @@ -1238,11 +1240,13 @@ namespace cwg599 { // cwg599: partial
struct V { operator int*(); operator Fn*(); };
void f(void *p, void (*q)(), S s, T t, U u, V v) {
delete p;
// expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}}
delete q;
// expected-error@-1 {{cannot delete expression of type 'void (*)()'}}
delete s;
// expected-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// cxx98-23-error@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}}
delete t;
// expected-error@-1 {{cannot delete expression of type 'T'}}
// FIXME: This is valid, but is rejected due to a non-conforming GNU
Expand Down
12 changes: 12 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-forward-declaration-inline.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify

inline int func2(int i);
int external_call2(int i) {
// expected-error@+1 {{'musttail' attribute for this call is impossible because external calls can not be tail called on PPC}}
[[clang::musttail]] return func2(i);
}

inline int func2(int i) {
return 0;
}
12 changes: 12 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-forward-declaration-weak.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify

int func2(int i);
int external_call2(int i) {
// expected-error@+1 {{'musttail' attribute for this call is impossible because external calls can not be tail called on PPC}}
[[clang::musttail]] return func2(i);
}

__attribute__((weak)) int func2(int i) {
return 0;
}
11 changes: 11 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-forward-declaration.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify=good
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify=good

int func2(int i);
int external_call2(int i) {
// good-no-diagnostics
[[clang::musttail]] return func2(i);
}
int func2(int i) {
return 0;
}
8 changes: 8 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-indirect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify
// RUN: %clang_cc1 %s -triple powerpc-unknown-linux-gnu -o /dev/null -emit-llvm -verify

void name(int *params) {
auto fn = (void (*)(int *))1;
// expected-error@+1 {{'musttail' attribute for this call is impossible because indirect calls can not be tail called on PPC}}
[[clang::musttail]] return fn(params);
}
12 changes: 12 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-inline.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify

inline int foo(int x) {
return x;
}

int bar(int x)
{
// expected-error@+1 {{'musttail' attribute for this call is impossible because external calls can not be tail called on PPC}}
[[clang::musttail]] return foo(1);
}
10 changes: 10 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-undefined.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify

int foo(int x);

int bar(int x)
{
// expected-error@+1 {{'musttail' attribute for this call is impossible because external calls can not be tail called on PPC}}
[[clang::musttail]] return foo(x);
}
13 changes: 13 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail-weak.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix
// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify=linux
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify=linux

__attribute__((weak)) int func2(int i) {
return 0;
}
int external_call2(int i) {
// linux-error@+2 {{'musttail' attribute for this call is impossible because external calls can not be tail called on PPC}}
// aix-error@+1 {{'musttail' attribute is not supported on AIX}}
[[clang::musttail]] return func2(i);
}
20 changes: 20 additions & 0 deletions clang/test/CodeGen/PowerPC/musttail.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 %s -triple powerpc64-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix
// RUN: %clang_cc1 %s -triple powerpc-ibm-aix-xcoff -o /dev/null -emit-llvm -verify=aix
// RUN: %clang_cc1 %s -triple powerpc64-unknown-linux-gnu -o /dev/null -emit-llvm -verify=good
// RUN: %clang_cc1 %s -triple powerpc-unknown-linux-gnu -o /dev/null -emit-llvm -verify=good
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -o /dev/null -emit-llvm -verify=good
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -target-feature +pcrelative-memops -o /dev/null -emit-llvm -verify=good
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -target-feature +longcall -o /dev/null -emit-llvm -verify=longcall
// RUN: %clang_cc1 %s -triple powerpc64le-unknown-linux-gnu -target-feature +pcrelative-memops -target-feature +longcall -o /dev/null -emit-llvm -verify=good

int foo(int x) {
return x;
}

int bar(int x)
{
// good-no-diagnostics
// longcall-error@+2 {{'musttail' attribute for this call is impossible because long calls can not be tail called on PPC}}
// aix-error@+1 {{'musttail' attribute is not supported on AIX}}
[[clang::musttail]] return foo(1);
}
9 changes: 9 additions & 0 deletions clang/test/CodeGen/bpf-debug-info-extern-func.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: %clang -g -target bpf -S -emit-llvm %s -o - | FileCheck %s
//
// When linking BPF object files via bpftool, BTF info is required for
// every symbol. BTF is generated from debug info. Ensure that debug info
// is emitted for extern functions referenced via variable initializers.
//
// CHECK: !DISubprogram(name: "fn"
extern void fn(void);
void (*pfn) (void) = &fn;
11 changes: 11 additions & 0 deletions clang/test/CodeGen/bpf-debug-info-unref.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %clang -g -target bpf -S -emit-llvm %s -o - | FileCheck %s
//
// No debug info is produced for unreferenced functions.
// CHECK-NOT: !DISubprogram
void unref(void);
void unref2(typeof(unref));

// No debug info for unused extern variables as well.
// CHECK-NOT: !DiGlobalVariable
extern int unused;
extern int unused2[sizeof(unused)];
8 changes: 8 additions & 0 deletions clang/test/CodeGenHIP/printf-builtin.hip
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// REQUIRES: amdgpu-registered-target
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -disable-llvm-optzns -mprintf-kind=hostcall -fno-builtin-printf -fcuda-is-device \
// RUN: -o - %s | FileCheck --check-prefixes=CHECK,HOSTCALL %s
// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -disable-llvm-optzns -mprintf-kind=hostcall -fno-builtin-printf -fcuda-is-device \
// RUN: -o - %s | FileCheck --check-prefixes=CHECK-AMDGCNSPIRV,HOSTCALL-AMDGCNSPIRV %s
// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -emit-llvm -disable-llvm-optzns -mprintf-kind=buffered -fno-builtin-printf -fcuda-is-device \
// RUN: -o - %s | FileCheck --check-prefixes=CHECK,BUFFERED %s
// RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -disable-llvm-optzns -mprintf-kind=buffered -fno-builtin-printf -fcuda-is-device \
// RUN: -o - %s | FileCheck --check-prefixes=CHECK-AMDGCNSPIRV,BUFFERED-AMDGCNSPIRV %s

#define __device__ __attribute__((device))

Expand All @@ -11,13 +15,17 @@ extern "C" __device__ int printf(const char *format, ...);
// CHECK-LABEL: @_Z4foo1v()
__device__ int foo1() {
// HOSTCALL: call i64 @__ockl_printf_begin
// HOSTCALL-AMDGCNSPIRV: call addrspace(4) i64 @__ockl_printf_begin
// BUFFERED: call ptr addrspace(1) @__printf_alloc
// BUFFERED-AMDGCNSPIRV: call addrspace(4) ptr addrspace(1) @__printf_alloc
// CHECK-NOT: call i32 (ptr, ...) @printf
// CHECK-AMDGCNSPIRV-NOT: call i32 (ptr, ...) @printf
return __builtin_printf("Hello World\n");
}

// CHECK-LABEL: @_Z4foo2v()
__device__ int foo2() {
// CHECK: call i32 (ptr, ...) @printf
// CHECK-AMDGCNSPIRV: call spir_func addrspace(4) i32 (ptr addrspace(4), ...) @printf
return printf("Hello World\n");
}
229 changes: 202 additions & 27 deletions clang/test/CodeGenHIP/printf.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion clang/test/OpenMP/deferred-diags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace TestDeleteIncompleteClassDefinition {
struct a;
struct b {
b() {
delete c; // expected-warning {{deleting pointer to incomplete type 'a' may cause undefined behavior}}
delete c; // expected-warning {{deleting pointer to incomplete type 'a' is incompatible with C++2c and may cause undefined behavior}}
}
a *c;
};
Expand Down
10 changes: 10 additions & 0 deletions clang/test/SemaCXX/eval-crashes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,13 @@ struct array {
array() : data(*new int[1][2]) {}
};
}

namespace GH96670 {
inline constexpr long ullNil = -1;

template<typename T = long, const T &Nil = ullNil>
struct Test {};

inline constexpr long lNil = -1;
Test<long, lNil> c;
}
26 changes: 17 additions & 9 deletions clang/test/SemaCXX/new-delete.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++98
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++11
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++14
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++17
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++20
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++98
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++11
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++14
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,precxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++17
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++20
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98-23,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++23
// RUN: %clang_cc1 -fsyntax-only -verify=expected,since-cxx26,cxx17,cxx20 %s -triple=i686-pc-linux-gnu -Wno-new-returns-null -std=c++2c

// FIXME Location is (frontend)
// cxx17-note@*:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
Expand Down Expand Up @@ -172,8 +174,12 @@ void bad_deletes()
{
delete 0; // expected-error {{cannot delete expression of type 'int'}}
delete [0] (int*)0; // expected-error {{expected variable name or 'this' in lambda capture list}}
delete (void*)0; // expected-warning {{cannot delete expression with pointer-to-'void' type 'void *'}}
delete (T*)0; // expected-warning {{deleting pointer to incomplete type}}
delete (void*)0;
// cxx98-23-warning@-1 {{cannot delete expression with pointer-to-'void' type 'void *'}}
// since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'void'}}
delete (T*)0;
// cxx98-23-warning@-1 {{deleting pointer to incomplete type}}
// since-cxx26-error@-2 {{cannot delete pointer to incomplete type 'T'}}
::S::delete (int*)0; // expected-error {{expected unqualified-id}}
}

Expand Down Expand Up @@ -513,8 +519,10 @@ namespace DeleteIncompleteClass {

namespace DeleteIncompleteClassPointerError {
struct A; // expected-note {{forward declaration}}
void f(A *x) { 1+delete x; } // expected-warning {{deleting pointer to incomplete type}} \
// expected-error {{invalid operands to binary expression}}
void f(A *x) { 1+delete x; }
// expected-error@-1 {{invalid operands to binary expression}}
// cxx98-23-warning@-2 {{deleting pointer to incomplete type}}
// since-cxx26-error@-3 {{cannot delete pointer to incomplete type 'A'}}
}

namespace PR10504 {
Expand Down
23 changes: 23 additions & 0 deletions clang/test/SemaTemplate/generic-lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,26 @@ template<class T1> C1<X<X<T1>>> auto t3() {
template C1<X<X<int>>> auto t3<int>();
static_assert(is_same<decltype(t3<int>()), X<X<X<int>>>>);
#endif

namespace GH95735 {

int g(int fn) {
return [f = fn](auto tpl) noexcept(noexcept(f)) { return f; }(0);
}

int foo(auto... fn) {
// FIXME: This one hits the assertion "if the exception specification is dependent,
// then the noexcept expression should be value-dependent" in the constructor of
// FunctionProtoType.
// One possible solution is to update Sema::canThrow() to consider expressions
// (e.g. DeclRefExpr/FunctionParmPackExpr) involving unexpanded parameters as Dependent.
// This would effectively add an extra value-dependent flag to the noexcept expression.
// However, I'm afraid that would also cause ABI breakage.
// [...f = fn](auto tpl) noexcept(noexcept(f)) { return 0; }(0);
[...f = fn](auto tpl) noexcept(noexcept(g(fn...))) { return 0; }(0);
return [...f = fn](auto tpl) noexcept(noexcept(g(f...))) { return 0; }(0);
}

int v = foo(42);

} // namespace GH95735
9 changes: 9 additions & 0 deletions clang/unittests/Format/SortIncludesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,15 @@ TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) {
#undef X
}

TEST_F(SortIncludesTest, BlockCommentedOutIncludes) {
StringRef Code{"/* #include \"foo.h\"\n"
"#include \"bar.h\" */\n"
"#include <chrono>"};

FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
verifyFormat(Code, sort(Code, "input.cpp", 0));
}

} // end namespace
} // end namespace format
} // end namespace clang
2 changes: 1 addition & 1 deletion clang/www/cxx_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
<tr>
<td>Deleting a Pointer to an Incomplete Type Should be Ill-formed</td>
<td><a href="https://wg21.link/P3144">P3144R2</a></td>
<td class="none" align="center">No</td>
<td class="unreleased" align="center">Clang 19</td>
</tr>
<tr>
<td>Ordering of constraints involving fold expressions</td>
Expand Down
17 changes: 13 additions & 4 deletions compiler-rt/cmake/Modules/CompilerRTUtils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,23 @@ macro(construct_compiler_rt_default_triple)
"Default triple for which compiler-rt runtimes will be built.")
endif()

if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang")
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(option_prefix "")
if (CMAKE_C_SIMULATE_ID MATCHES "MSVC")
set(option_prefix "/clang:")
endif()
execute_process(COMMAND ${CMAKE_C_COMPILER} ${option_prefix}--target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE} ${option_prefix}-print-target-triple
OUTPUT_VARIABLE COMPILER_RT_DEFAULT_TARGET_TRIPLE
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(print_target_triple ${CMAKE_C_COMPILER} ${option_prefix}--target=${COMPILER_RT_DEFAULT_TARGET_TRIPLE} ${option_prefix}-print-target-triple)
execute_process(COMMAND ${print_target_triple}
RESULT_VARIABLE result
OUTPUT_VARIABLE output
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(result EQUAL 0)
set(COMPILER_RT_DEFAULT_TARGET_TRIPLE ${output})
else()
string(REPLACE ";" " " print_target_triple "${print_target_triple}")
# TODO(#97876): Report an error.
message(WARNING "Failed to execute `${print_target_triple}` to normalize target triple.")
endif()
endif()

string(REPLACE "-" ";" LLVM_TARGET_TRIPLE_LIST ${COMPILER_RT_DEFAULT_TARGET_TRIPLE})
Expand Down
3 changes: 0 additions & 3 deletions compiler-rt/include/orc_rt/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ typedef struct {
size_t Size;
} orc_rt_CWrapperFunctionResult;

typedef struct orc_rt_CSharedOpaqueJITProcessControl
*orc_rt_SharedJITProcessControlRef;

/**
* Zero-initialize an orc_rt_CWrapperFunctionResult.
*/
Expand Down
91 changes: 91 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/AArch64CPUFeatures.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//===- AArch64CPUFeatures.inc - AArch64 CPU Features enum -------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the CPUFeatures enum for AArch64 to facilitate better
// testing of this code between LLVM and compiler-rt, primarily that the files
// are an exact match.
//
// This file has two identical copies. The primary copy lives in LLVM and
// the other one sits in compiler-rt/lib/builtins/cpu_model directory. To make
// changes in this file, first modify the primary copy and copy it over to
// compiler-rt. compiler-rt tests will fail if the two files are not synced up.
//
//===----------------------------------------------------------------------===//

#ifndef AARCH64_CPU_FEATURS_INC_H
#define AARCH64_CPU_FEATURS_INC_H

// Function Multi Versioning CPU features.
enum CPUFeatures {
FEAT_RNG,
FEAT_FLAGM,
FEAT_FLAGM2,
FEAT_FP16FML,
FEAT_DOTPROD,
FEAT_SM4,
FEAT_RDM,
FEAT_LSE,
FEAT_FP,
FEAT_SIMD,
FEAT_CRC,
FEAT_SHA1,
FEAT_SHA2,
FEAT_SHA3,
FEAT_AES,
FEAT_PMULL,
FEAT_FP16,
FEAT_DIT,
FEAT_DPB,
FEAT_DPB2,
FEAT_JSCVT,
FEAT_FCMA,
FEAT_RCPC,
FEAT_RCPC2,
FEAT_FRINTTS,
FEAT_DGH,
FEAT_I8MM,
FEAT_BF16,
FEAT_EBF16,
FEAT_RPRES,
FEAT_SVE,
FEAT_SVE_BF16,
FEAT_SVE_EBF16,
FEAT_SVE_I8MM,
FEAT_SVE_F32MM,
FEAT_SVE_F64MM,
FEAT_SVE2,
FEAT_SVE_AES,
FEAT_SVE_PMULL128,
FEAT_SVE_BITPERM,
FEAT_SVE_SHA3,
FEAT_SVE_SM4,
FEAT_SME,
FEAT_MEMTAG,
FEAT_MEMTAG2,
FEAT_MEMTAG3,
FEAT_SB,
FEAT_PREDRES,
FEAT_SSBS,
FEAT_SSBS2,
FEAT_BTI,
FEAT_LS64,
FEAT_LS64_V,
FEAT_LS64_ACCDATA,
FEAT_WFXT,
FEAT_SME_F64,
FEAT_SME_I64,
FEAT_SME2,
FEAT_RCPC3,
FEAT_MOPS,
FEAT_MAX,
FEAT_EXT = 62, // Reserved to indicate presence of additional features field
// in __aarch64_cpu_features
FEAT_INIT // Used as flag of features initialization completion
};

#endif
69 changes: 1 addition & 68 deletions compiler-rt/lib/builtins/cpu_model/aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,74 +14,7 @@

#if !defined(DISABLE_AARCH64_FMV)

// CPUFeatures must correspond to the same AArch64 features in
// AArch64TargetParser.h
enum CPUFeatures {
FEAT_RNG,
FEAT_FLAGM,
FEAT_FLAGM2,
FEAT_FP16FML,
FEAT_DOTPROD,
FEAT_SM4,
FEAT_RDM,
FEAT_LSE,
FEAT_FP,
FEAT_SIMD,
FEAT_CRC,
FEAT_SHA1,
FEAT_SHA2,
FEAT_SHA3,
FEAT_AES,
FEAT_PMULL,
FEAT_FP16,
FEAT_DIT,
FEAT_DPB,
FEAT_DPB2,
FEAT_JSCVT,
FEAT_FCMA,
FEAT_RCPC,
FEAT_RCPC2,
FEAT_FRINTTS,
FEAT_DGH,
FEAT_I8MM,
FEAT_BF16,
FEAT_EBF16,
FEAT_RPRES,
FEAT_SVE,
FEAT_SVE_BF16,
FEAT_SVE_EBF16,
FEAT_SVE_I8MM,
FEAT_SVE_F32MM,
FEAT_SVE_F64MM,
FEAT_SVE2,
FEAT_SVE_AES,
FEAT_SVE_PMULL128,
FEAT_SVE_BITPERM,
FEAT_SVE_SHA3,
FEAT_SVE_SM4,
FEAT_SME,
FEAT_MEMTAG,
FEAT_MEMTAG2,
FEAT_MEMTAG3,
FEAT_SB,
FEAT_PREDRES,
FEAT_SSBS,
FEAT_SSBS2,
FEAT_BTI,
FEAT_LS64,
FEAT_LS64_V,
FEAT_LS64_ACCDATA,
FEAT_WFXT,
FEAT_SME_F64,
FEAT_SME_I64,
FEAT_SME2,
FEAT_RCPC3,
FEAT_MOPS,
FEAT_MAX,
FEAT_EXT = 62, // Reserved to indicate presence of additional features field
// in __aarch64_cpu_features
FEAT_INIT // Used as flag of features initialization completion
};
#include "AArch64CPUFeatures.inc"

void __init_cpu_features(void);

Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/orc/error.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===-------- Error.h - Enforced error checking for ORC RT ------*- C++ -*-===//
//===-------- error.h - Enforced error checking for ORC RT ------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
;
; NOTE: if this test fails, please make sure the relevant copies are identical
; copies of each other.
;
; RUN: diff %crt_src/lib/builtins/cpu_model/AArch64CPUFeatures.inc %llvm_src/include/llvm/TargetParser/AArch64CPUFeatures.inc
2 changes: 1 addition & 1 deletion compiler-rt/test/builtins/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
config.test_source_root = os.path.dirname(__file__)

# Test suffixes.
config.suffixes = [".c", ".cpp", ".m", ".mm"]
config.suffixes = [".c", ".cpp", ".m", ".mm", ".test"]
extra_flags = ["-Wall"]
if config.compiler_id == "GNU":
# detect incorrect declarations of libgcc functions
Expand Down
7 changes: 7 additions & 0 deletions compiler-rt/test/profile/check-same-common-code.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
;
; NOTE: if this test fails, please make sure the files are identical
; copies of each other.
;
; RUN: diff %crt_src/include/profile/MIBEntryDef.inc %llvm_src/include/llvm/ProfileData/MIBEntryDef.inc
; RUN: diff %crt_src/include/profile/MemProfData.inc %llvm_src/include/llvm/ProfileData/MemProfData.inc
; RUN: diff %crt_src/include/profile/InstrProfData.inc %llvm_src/include/llvm/ProfileData/InstrProfData.inc
25 changes: 12 additions & 13 deletions libc/benchmarks/gpu/LibcGpuBenchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ void Benchmark::add_benchmark(Benchmark *benchmark) {
benchmarks.push_back(benchmark);
}

BenchmarkResult reduce_results(cpp::array<BenchmarkResult, 1024> &results) {
BenchmarkResult
reduce_results(const cpp::array<BenchmarkResult, 1024> &results) {
BenchmarkResult result;
uint64_t cycles_sum = 0;
double standard_deviation_sum = 0;
Expand Down Expand Up @@ -51,16 +52,16 @@ void Benchmark::run_benchmarks() {
uint64_t id = gpu::get_thread_id();
gpu::sync_threads();

for (Benchmark *benchmark : benchmarks)
results[id] = benchmark->run();
for (Benchmark *b : benchmarks)
results[id] = b->run();
gpu::sync_threads();
if (id == 0) {
for (Benchmark *benchmark : benchmarks) {
for (Benchmark const *b : benchmarks) {
BenchmarkResult all_results = reduce_results(results);
constexpr auto GREEN = "\033[32m";
constexpr auto RESET = "\033[0m";
log << GREEN << "[ RUN ] " << RESET << benchmark->get_name() << '\n';
log << GREEN << "[ OK ] " << RESET << benchmark->get_name() << ": "
log << GREEN << "[ RUN ] " << RESET << b->get_name() << '\n';
log << GREEN << "[ OK ] " << RESET << b->get_name() << ": "
<< all_results.cycles << " cycles, " << all_results.min << " min, "
<< all_results.max << " max, " << all_results.total_iterations
<< " iterations, " << all_results.total_time << " ns, "
Expand All @@ -82,7 +83,6 @@ BenchmarkResult benchmark(const BenchmarkOptions &options,
uint32_t samples = 0;
uint64_t total_time = 0;
uint64_t best_guess = 0;
uint64_t total_cycles = 0;
uint64_t cycles_squared = 0;
uint64_t min = UINT64_MAX;
uint64_t max = 0;
Expand All @@ -92,23 +92,22 @@ BenchmarkResult benchmark(const BenchmarkOptions &options,
for (int i = 0; i < overhead_iterations; i++)
overhead = cpp::min(overhead, LIBC_NAMESPACE::overhead());

for (uint64_t time_budget = options.max_duration; time_budget >= 0;) {
for (int64_t time_budget = options.max_duration; time_budget >= 0;) {
uint64_t sample_cycles = 0;
const clock_t start = static_cast<double>(clock());
for (uint32_t i = 0; i < iterations; i++) {
auto wrapper_intermediate = wrapper_func();
uint64_t result = wrapper_intermediate - overhead;
max = cpp::max(max, result);
min = cpp::min(min, result);
sample_cycles += result;
uint64_t current_result = wrapper_intermediate - overhead;
max = cpp::max(max, current_result);
min = cpp::min(min, current_result);
sample_cycles += current_result;
}
const clock_t end = clock();
const clock_t duration_ns =
((end - start) * 1000 * 1000 * 1000) / CLOCKS_PER_SEC;
total_time += duration_ns;
time_budget -= duration_ns;
samples++;
total_cycles += sample_cycles;
cycles_squared += sample_cycles * sample_cycles;

total_iterations += iterations;
Expand Down
4 changes: 2 additions & 2 deletions libc/benchmarks/gpu/LibcGpuBenchmark.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ struct BenchmarkOptions {
uint32_t max_iterations = 10000000;
uint32_t min_samples = 4;
uint32_t max_samples = 1000;
uint64_t min_duration = 0; // in nanoseconds (ns)
uint64_t max_duration = 1000 * 1000 * 1000; // 1e9 nanoseconds = 1 second
int64_t min_duration = 0; // in nanoseconds (ns)
int64_t max_duration = 1000 * 1000 * 1000; // 1e9 nanoseconds = 1 second
double epsilon = 0.01;
double scaling_factor = 1.4;
};
Expand Down
1 change: 1 addition & 0 deletions libc/config/baremetal/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.sqrt
libc.src.math.sqrtf
libc.src.math.sqrtl
libc.src.math.tan
libc.src.math.tanf
libc.src.math.tanhf
libc.src.math.trunc
Expand Down
1 change: 1 addition & 0 deletions libc/config/baremetal/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.sqrt
libc.src.math.sqrtf
libc.src.math.sqrtl
libc.src.math.tan
libc.src.math.tanf
libc.src.math.tanhf
libc.src.math.trunc
Expand Down
1 change: 1 addition & 0 deletions libc/config/darwin/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.coshf
libc.src.math.cos
libc.src.math.cosf
libc.src.math.cospif
libc.src.math.erff
libc.src.math.exp
libc.src.math.expf
Expand Down
9 changes: 9 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper

# dlfcn.h entrypoints
libc.src.dlfcn.dlclose
libc.src.dlfcn.dlerror
libc.src.dlfcn.dlopen
libc.src.dlfcn.dlsym

# errno.h entrypoints
libc.src.errno.errno

Expand Down Expand Up @@ -284,6 +290,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.dup3
libc.src.unistd.execve
libc.src.unistd.fchdir
libc.src.unistd.fpathconf
libc.src.unistd.fsync
libc.src.unistd.ftruncate
libc.src.unistd.getcwd
Expand All @@ -295,6 +302,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.link
libc.src.unistd.linkat
libc.src.unistd.lseek
libc.src.unistd.pathconf
libc.src.unistd.pread
libc.src.unistd.pwrite
libc.src.unistd.read
Expand Down Expand Up @@ -346,6 +354,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.cos
libc.src.math.cosf
libc.src.math.coshf
libc.src.math.cospif
libc.src.math.erff
libc.src.math.exp
libc.src.math.exp10
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/aarch64/headers.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(TARGET_PUBLIC_HEADERS
libc.include.assert
libc.include.ctype
libc.include.dlfcn
libc.include.errno
libc.include.features
libc.include.fenv
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.dup3
libc.src.unistd.execve
libc.src.unistd.fchdir
libc.src.unistd.fpathconf
libc.src.unistd.fsync
libc.src.unistd.ftruncate
libc.src.unistd.getcwd
Expand All @@ -300,6 +301,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.link
libc.src.unistd.linkat
libc.src.unistd.lseek
libc.src.unistd.pathconf
libc.src.unistd.pread
libc.src.unistd.pwrite
libc.src.unistd.read
Expand Down Expand Up @@ -354,6 +356,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.cos
libc.src.math.cosf
libc.src.math.coshf
libc.src.math.cospif
libc.src.math.erff
libc.src.math.exp
libc.src.math.exp10
Expand Down
9 changes: 9 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.ctype.tolower
libc.src.ctype.toupper

# dlfcn.h entrypoints
libc.src.dlfcn.dlclose
libc.src.dlfcn.dlerror
libc.src.dlfcn.dlopen
libc.src.dlfcn.dlsym

# errno.h entrypoints
libc.src.errno.errno

Expand Down Expand Up @@ -302,6 +308,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.dup3
libc.src.unistd.execve
libc.src.unistd.fchdir
libc.src.unistd.fpathconf
libc.src.unistd.fsync
libc.src.unistd.ftruncate
libc.src.unistd.getcwd
Expand All @@ -313,6 +320,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.link
libc.src.unistd.linkat
libc.src.unistd.lseek
libc.src.unistd.pathconf
libc.src.unistd.pipe
libc.src.unistd.pread
libc.src.unistd.pwrite
Expand Down Expand Up @@ -371,6 +379,7 @@ set(TARGET_LIBM_ENTRYPOINTS
libc.src.math.cos
libc.src.math.cosf
libc.src.math.coshf
libc.src.math.cospif
libc.src.math.erff
libc.src.math.exp
libc.src.math.exp10
Expand Down
1 change: 1 addition & 0 deletions libc/config/linux/x86_64/headers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.assert
libc.include.ctype
libc.include.dirent
libc.include.dlfcn
libc.include.errno
libc.include.fcntl
libc.include.features
Expand Down
4 changes: 4 additions & 0 deletions libc/docs/dev/undefined_behavior.rst
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@ The C23 standard states that if the value of the ``rnd`` argument of the
the value of a math rounding direction macro, the direction of rounding is
unspecified. LLVM's libc chooses to use the ``FP_INT_TONEAREST`` rounding
direction in this case.

Non-const Constant Return Values
--------------------------------
Some libc functions, like ``dlerror()``, return ``char *`` instead of ``const char *`` and then tell the caller they promise not to to modify this value. Any modification of this value is undefined behavior.
4 changes: 2 additions & 2 deletions libc/docs/math/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ Basic Operations
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| f16div | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.4 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| f16fma | |check| | |check| | |check| | N/A | |check| | 7.12.14.5 | F.10.11 |
| f16fma | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.5 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| f16sub | |check|\* | |check|\* | |check|\* | N/A | |check| | 7.12.14.2 | F.10.11 |
+------------------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down Expand Up @@ -274,7 +274,7 @@ Higher Math Functions
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| cosh | |check| | | | | | 7.12.5.4 | F.10.2.4 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| cospi | | | | | | 7.12.4.12 | F.10.1.12 |
| cospi | |check| | | | | | 7.12.4.12 | F.10.1.12 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
| dsqrt | N/A | N/A | | N/A | | 7.12.14.6 | F.10.11 |
+-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+
Expand Down
27 changes: 27 additions & 0 deletions libc/hdr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,24 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.sys_epoll_macros
)

add_proxy_header_library(
sys_stat_macros
HDRS
sys_stat_macros.h
FULL_BUILD_DEPENDS
libc.include.sys_stat
libc.include.llvm-libc-macros.sys_stat_macros
)

add_proxy_header_library(
unistd_macros
HDRS
unistd_macros.h
FULL_BUILD_DEPENDS
libc.include.unistd
libc.include.llvm-libc-macros.unistd_macros
)

add_proxy_header_library(
time_macros
HDRS
Expand All @@ -97,4 +115,13 @@ add_proxy_header_library(
libc.include.float
)

add_proxy_header_library(
limits_macros
HDRS
limits_macros.h
FULL_BUILD_DEPENDS
libc.include.limits
libc.include.llvm-libc-macros.limits_macros
)

add_subdirectory(types)
22 changes: 22 additions & 0 deletions libc/hdr/limits_macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Definition of macros from limits.h --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_HDR_LIMITS_MACROS_H
#define LLVM_LIBC_HDR_LIMITS_MACROS_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-macros/limits-macros.h"

#else // Overlay mode

#include <limits.h>

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_LIMITS_MACROS_H
5 changes: 5 additions & 0 deletions libc/hdr/math_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

#else // Overlay mode

// GCC will include CXX headers when __cplusplus is defined. This behavior
// can be suppressed by defining _GLIBCXX_INCLUDE_NEXT_C_HEADERS.
#if defined(__GNUC__) && !defined(__clang__)
#define _GLIBCXX_INCLUDE_NEXT_C_HEADERS
#endif
#include <math.h>

// Some older math.h header does not have FP_INT_* constants yet.
Expand Down
22 changes: 22 additions & 0 deletions libc/hdr/sys_stat_macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Definition of macros from sys/stat.h ------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_HDR_SYS_STAT_MACROS_H
#define LLVM_LIBC_HDR_SYS_STAT_MACROS_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-macros/sys-stat-macros.h"

#else // Overlay mode

#include <sys/stat.h>

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_SYS_STAT_MACROS_H
22 changes: 22 additions & 0 deletions libc/hdr/unistd_macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===-- Definition of macros from unistd.h --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_HDR_UNISTD_MACROS_H
#define LLVM_LIBC_HDR_UNISTD_MACROS_H

#ifdef LIBC_FULL_BUILD

#include "include/llvm-libc-macros/unistd-macros.h"

#else // Overlay mode

#include <unistd.h>

#endif // LLVM_LIBC_FULL_BUILD

#endif // LLVM_LIBC_HDR_UNISTD_MACROS_H
9 changes: 9 additions & 0 deletions libc/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@ add_gen_header(
.llvm_libc_common_h
)

add_gen_header(
dlfcn
DEF_FILE dlfcn.h.def
GEN_HDR dlfcn.h
DEPENDS
.llvm-libc-macros.dlfcn_macros
.llvm_libc_common_h
)

add_gen_header(
features
DEF_FILE features.h.def
Expand Down
17 changes: 17 additions & 0 deletions libc/include/dlfcn.h.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//===-- C standard library header dlfcn.h ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_DLFCN_H
#define LLVM_LIBC_DLFCN_H

#include "__llvm-libc-common.h"
#include "llvm-libc-macros/dlfcn-macros.h"

%%public_api()

#endif // LLVM_LIBC_DLFCN_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-macros/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,9 @@ add_macro_header(
HDR
stdckdint-macros.h
)

add_macro_header(
dlfcn_macros
HDR
dlfcn-macros.h
)
23 changes: 23 additions & 0 deletions libc/include/llvm-libc-macros/dlfcn-macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Definition of macros from dlfcn.h ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_MACROS_DLFCN_MACROS_H
#define LLVM_LIBC_MACROS_DLFCN_MACROS_H

#define RTLD_LAZY 0x00001
#define RTLD_NOW 0x00002
#define RTLD_GLOBAL 0x00100
#define RTLD_LOCAL 0

// Non-standard stuff here
#define RTLD_BINDING_MASK 0x3
#define RTLD_NOLOAD 0x00004
#define RTLD_DEEPBIND 0x00008
#define RTLD_NODELETE 0x01000

#endif // LLVM_LIBC_MACROS_DLFCN_MACROS_H
12 changes: 12 additions & 0 deletions libc/include/llvm-libc-macros/limits-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,4 +225,16 @@
#define ULLONG_MIN 0ULL
#endif // ULLONG_MIN

#ifndef _POSIX_MAX_CANON
#define _POSIX_MAX_CANON 255
#endif

#ifndef _POSIX_MAX_INPUT
#define _POSIX_MAX_INPUT 255
#endif

#ifndef _POSIX_NAME_MAX
#define _POSIX_PATH_MAX 256
#endif

#endif // LLVM_LIBC_MACROS_LIMITS_MACROS_H
27 changes: 27 additions & 0 deletions libc/include/llvm-libc-macros/linux/unistd-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,33 @@
#define _SC_PAGESIZE 1
#define _SC_PAGE_SIZE _SC_PAGESIZE

#define _PC_FILESIZEBITS 0
#define _PC_LINK_MAX 1
#define _PC_MAX_CANON 2
#define _PC_MAX_INPUT 3
#define _PC_NAME_MAX 4
#define _PC_PATH_MAX 5
#define _PC_PIPE_BUF 6
#define _PC_2_SYMLINKS 7
#define _PC_ALLOC_SIZE_MIN 8
#define _PC_REC_INCR_XFER_SIZE 9
#define _PC_REC_MAX_XFER_SIZE 10
#define _PC_REC_MIN_XFER_SIZE 11
#define _PC_REC_XFER_ALIGN 12
#define _PC_SYMLINK_MAX 13
#define _PC_CHOWN_RESTRICTED 14
#define _PC_NO_TRUNC 15
#define _PC_VDISABLE 16
#define _PC_ASYNC_IO 17
#define _PC_PRIO_IO 18
#define _PC_SYNC_IO 19

// TODO: Move these limit macros to a separate file
#define _POSIX_CHOWN_RESTRICTED 1
#define _POSIX_PIPE_BUF 512
#define _POSIX_NO_TRUNC 1
#define _POSIX_VDISABLE '\0'

// Macro to set up the call to the __llvm_libc_syscall function
// This is to prevent the call from having fewer than 6 arguments, since six
// arguments are always passed to the syscall. Unnecessary arguments are
Expand Down
14 changes: 13 additions & 1 deletion libc/spec/linux.td
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,19 @@ def Linux : StandardSpec<"Linux"> {
[], // Macros
[], // Types
[], // Enumerations
[] // Functions
[
FunctionSpec<
"prctl",
RetValSpec<IntType>,
[
ArgSpec<IntType>,
ArgSpec<UnsignedLongType>,
ArgSpec<UnsignedLongType>,
ArgSpec<UnsignedLongType>,
ArgSpec<UnsignedLongType>,
]
>,
] // Functions
>;

HeaderSpec SysRandom = HeaderSpec<
Expand Down
4 changes: 4 additions & 0 deletions libc/spec/llvm_libc_ext.td
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ def LLVMLibcExt : StandardSpec<"llvm_libc_ext"> {
GuardedFunctionSpec<"f16divf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16divl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,

GuardedFunctionSpec<"f16fma", RetValSpec<Float16Type>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16fmaf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16fmal", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,

GuardedFunctionSpec<"f16sqrt", RetValSpec<Float16Type>, [ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16sqrtf", RetValSpec<Float16Type>, [ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16sqrtl", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
Expand Down
35 changes: 35 additions & 0 deletions libc/spec/posix.td
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,40 @@ def POSIX : StandardSpec<"POSIX"> {
[] // Functions
>;

HeaderSpec DlFcn = HeaderSpec<
"dlfcn.h",
[
Macro<"RTLD_LAZY">,
Macro<"RTLD_NOW">,
Macro<"RTLD_GLOBAL">,
Macro<"RTLD_LOCAL">,
],
[], // Types
[], // Enumerations
[
FunctionSpec<
"dlclose",
RetValSpec<IntType>,
[ArgSpec<VoidPtr>]
>,
FunctionSpec<
"dlerror",
RetValSpec<CharPtr>,
[]
>,
FunctionSpec<
"dlopen",
RetValSpec<VoidPtr>,
[ArgSpec<ConstCharPtr>, ArgSpec<IntType>]
>,
FunctionSpec<
"dlsym",
RetValSpec<VoidPtr>,
[ArgSpec<VoidRestrictedPtr>, ArgSpec<ConstCharRestrictedPtr>]
>,
]
>;

HeaderSpec FCntl = HeaderSpec<
"fcntl.h",
[], // Macros
Expand Down Expand Up @@ -1690,6 +1724,7 @@ def POSIX : StandardSpec<"POSIX"> {
ArpaInet,
CType,
Dirent,
DlFcn,
Errno,
FCntl,
PThread,
Expand Down
3 changes: 0 additions & 3 deletions libc/spec/stdc.td
Original file line number Diff line number Diff line change
Expand Up @@ -477,9 +477,6 @@ def StdC : StandardSpec<"stdc"> {
FunctionSpec<"fma", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
FunctionSpec<"fmaf", RetValSpec<FloatType>, [ArgSpec<FloatType>, ArgSpec<FloatType>, ArgSpec<FloatType>]>,

GuardedFunctionSpec<"f16fma", RetValSpec<Float16Type>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>, ArgSpec<DoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16fmaf", RetValSpec<Float16Type>, [ArgSpec<FloatType>, ArgSpec<FloatType>, ArgSpec<FloatType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16fmal", RetValSpec<Float16Type>, [ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>, ArgSpec<LongDoubleType>], "LIBC_TYPES_HAS_FLOAT16">,
GuardedFunctionSpec<"f16fmaf128", RetValSpec<Float16Type>, [ArgSpec<Float128Type>, ArgSpec<Float128Type>, ArgSpec<Float128Type>], "LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128">,

FunctionSpec<"fmod", RetValSpec<DoubleType>, [ArgSpec<DoubleType>, ArgSpec<DoubleType>]>,
Expand Down
1 change: 1 addition & 0 deletions libc/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_subdirectory(__support)

add_subdirectory(ctype)
add_subdirectory(dlfcn)
add_subdirectory(errno)
add_subdirectory(fenv)
add_subdirectory(inttypes)
Expand Down
2 changes: 2 additions & 0 deletions libc/src/__support/File/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# TODO: migrate to proxy headers
add_object_library(
file
SRCS
Expand All @@ -8,6 +9,7 @@ add_object_library(
libc.include.fcntl
libc.include.stdio
libc.include.sys_syscall
libc.include.sys_stat
libc.src.__support.CPP.new
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
Expand Down
4 changes: 3 additions & 1 deletion libc/src/__support/threads/sleep.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ LIBC_INLINE void sleep_briefly() {
__builtin_amdgcn_s_sleep(2);
#elif defined(LIBC_TARGET_ARCH_IS_X86)
__builtin_ia32_pause();
#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)
#elif defined(LIBC_TARGET_ARCH_IS_AARCH64) && __has_builtin(__builtin_arm_isb)
__builtin_arm_isb(0xf);
#elif defined(LIBC_TARGET_ARCH_IS_AARCH64)
asm volatile("isb\n" ::: "memory");
#else
// Simply do nothing if sleeping isn't supported on this platform.
#endif
Expand Down
40 changes: 40 additions & 0 deletions libc/src/dlfcn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
add_entrypoint_object(
dlclose
SRCS
dlclose.cpp
HDRS
dlclose.h
)

add_entrypoint_object(
dlerror
SRCS
dlerror.cpp
HDRS
dlerror.h
DEPENDS
libc.include.dlfcn
libc.src.errno.errno
)

add_entrypoint_object(
dlopen
SRCS
dlopen.cpp
HDRS
dlopen.h
DEPENDS
libc.include.dlfcn
libc.src.errno.errno
)

add_entrypoint_object(
dlsym
SRCS
dlsym.cpp
HDRS
dlsym.h
DEPENDS
libc.include.dlfcn
libc.src.errno.errno
)
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlclose.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of dlclose -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "dlclose.h"

#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97917
LLVM_LIBC_FUNCTION(int, dlclose, (void *)) { return -1; }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlclose.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header of dlclose ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_DLFCN_DLCLOSE_H
#define LLVM_LIBC_SRC_DLFCN_DLCLOSE_H

namespace LIBC_NAMESPACE {

int dlclose(void *);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_DLFCN_DLCLOSE_H
20 changes: 20 additions & 0 deletions libc/src/dlfcn/dlerror.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- Implementation of delerror ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "dlerror.h"

#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97918
LLVM_LIBC_FUNCTION(char *, dlerror, ()) {
return const_cast<char *>("unsupported");
}

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlerror.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header of dlerror ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_DLFCN_DLERROR_H
#define LLVM_LIBC_SRC_DLFCN_DLERROR_H

namespace LIBC_NAMESPACE {

char *dlerror();

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_DLFCN_DLERROR_H
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlopen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of dlopen -----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "dlopen.h"

#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97919
LLVM_LIBC_FUNCTION(void *, dlopen, (const char *, int)) { return nullptr; }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlopen.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header of dlopen -------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_DLFCN_DLOPEN_H
#define LLVM_LIBC_SRC_DLFCN_DLOPEN_H

namespace LIBC_NAMESPACE {

void *dlopen(const char *, int);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_DLFCN_DLOPEN_H
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlsym.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation of dlsym ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "dlsym.h"

#include "src/__support/common.h"

namespace LIBC_NAMESPACE {

// TODO(@izaakschroeder): https://github.com/llvm/llvm-project/issues/97920
LLVM_LIBC_FUNCTION(void *, dlsym, (void *, const char *)) { return nullptr; }

} // namespace LIBC_NAMESPACE
18 changes: 18 additions & 0 deletions libc/src/dlfcn/dlsym.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header of dlsym --------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_DLFCN_DLSYM_H
#define LLVM_LIBC_SRC_DLFCN_DLSYM_H

namespace LIBC_NAMESPACE {

void *dlsym(void *, const char *);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_DLFCN_DLSYM_H
1 change: 1 addition & 0 deletions libc/src/math/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ add_math_entrypoint_object(cos)
add_math_entrypoint_object(cosf)
add_math_entrypoint_object(cosh)
add_math_entrypoint_object(coshf)
add_math_entrypoint_object(cospif)

add_math_entrypoint_object(erf)
add_math_entrypoint_object(erff)
Expand Down
18 changes: 18 additions & 0 deletions libc/src/math/cospif.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header for cospif ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_MATH_COSPIF_H
#define LLVM_LIBC_SRC_MATH_COSPIF_H

namespace LIBC_NAMESPACE {

float cospif(float x);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_MATH_COSPIF_H
17 changes: 17 additions & 0 deletions libc/src/math/generic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,23 @@ add_entrypoint_object(
-O3
)

add_entrypoint_object(
cospif
SRCS
cospif.cpp
HDRS
../cospif.h
DEPENDS
.sincosf_utils
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.fma
libc.src.__support.FPUtil.multiply_add
libc.src.__support.macros.optimization
COMPILE_OPTIONS
-O3
)

add_entrypoint_object(
sin
SRCS
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/cos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ LLVM_LIBC_FUNCTION(double, cos, (double x)) {

DoubleDouble y;
unsigned k;
generic::LargeRangeReduction<NO_FMA> range_reduction_large;
generic::LargeRangeReduction<NO_FMA> range_reduction_large{};

// |x| < 2^32 (with FMA) or |x| < 2^23 (w/o FMA)
if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
Expand Down
96 changes: 96 additions & 0 deletions libc/src/math/generic/cospif.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//===-- Single-precision cospi function -----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/math/cospif.h"
#include "sincosf_utils.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/multiply_add.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(float, cospif, (float x)) {
using FPBits = typename fputil::FPBits<float>;

FPBits xbits(x);
Sign xsign = xbits.sign();
xbits.set_sign(Sign::POS);

uint32_t x_abs = xbits.uintval();
double xd = static_cast<double>(xbits.get_val());

// Range reduction:
// For |x| > 1/32, we perform range reduction as follows:
// Find k and y such that:
// x = (k + y) * 1/32
// k is an integer
// |y| < 0.5
//
// This is done by performing:
// k = round(x * 32)
// y = x * 32 - k
//
// Once k and y are computed, we then deduce the answer by the cosine of sum
// formula:
// cospi(x) = cos((k + y)*pi/32)
// = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
// The values of sin(k*pi/32) and cos(k*pi/32) for k = 0..63 are precomputed
// and stored using a vector of 32 doubles. Sin(y*pi/32) and cos(y*pi/32) are
// computed using degree-7 and degree-6 minimax polynomials generated by
// Sollya respectively.

// The exhautive test passes for smaller values
if (LIBC_UNLIKELY(x_abs < 0x38A2'F984U)) {

#if defined(LIBC_TARGET_CPU_HAS_FMA)
return fputil::multiply_add(xbits.get_val(), -0x1.0p-25f, 1.0f);
#else
return static_cast<float>(fputil::multiply_add(xd, -0x1.0p-25, 1.0));
#endif // LIBC_TARGET_CPU_HAS_FMA
}

// Numbers greater or equal to 2^23 are always integers or NaN
if (LIBC_UNLIKELY(x_abs >= 0x4B00'0000)) {

if (LIBC_UNLIKELY(x_abs < 0x4B80'0000)) {
return (x_abs & 0x1) ? -1.0f : 1.0f;
}

// x is inf or nan.
if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) {
if (x_abs == 0x7f80'0000U) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
}
return x + FPBits::quiet_nan().get_val();
}

return 1.0f;
}

// Combine the results with the sine of sum formula:
// cos(pi * x) = cos((k + y)*pi/32)
// = cos(y*pi/32) * cos(k*pi/32) - sin(y*pi/32) * sin(k*pi/32)
// = (cosm1_y + 1) * cos_k - sin_y * sin_k
// = (cosm1_y * cos_k + cos_k) - sin_y * sin_k
double sin_k, cos_k, sin_y, cosm1_y;

sincospif_eval(xd, sin_k, cos_k, sin_y, cosm1_y);

if (LIBC_UNLIKELY(sin_y == 0 && cos_k == 0)) {
return FPBits::zero(xsign).get_val();
}

return static_cast<float>(fputil::multiply_add(
sin_y, -sin_k, fputil::multiply_add(cosm1_y, cos_k, cos_k)));
}

} // namespace LIBC_NAMESPACE
24 changes: 15 additions & 9 deletions libc/src/math/generic/erff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,6 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
uint32_t x_u = xbits.uintval();
uint32_t x_abs = x_u & 0x7fff'ffffU;

// Exceptional values
if (LIBC_UNLIKELY(x_abs == 0x3f65'9229U)) // |x| = 0x1.cb2452p-1f
return x < 0.0f ? fputil::round_result_slightly_down(-0x1.972ea8p-1f)
: fputil::round_result_slightly_up(0x1.972ea8p-1f);
if (LIBC_UNLIKELY(x_abs == 0x4004'1e6aU)) // |x| = 0x1.083cd4p+1f
return x < 0.0f ? fputil::round_result_slightly_down(-0x1.fe3462p-1f)
: fputil::round_result_slightly_up(0x1.fe3462p-1f);

// if (LIBC_UNLIKELY(x_abs > 0x407a'd444U)) {
if (LIBC_UNLIKELY(x_abs >= 0x4080'0000U)) {
const float ONE[2] = {1.0f, -1.0f};
const float SMALL[2] = {-0x1.0p-25f, 0x1.0p-25f};
Expand All @@ -149,6 +140,21 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) {
return ONE[sign] + SMALL[sign];
}

// Exceptional mask = common 0 bits of 2 exceptional values.
constexpr uint32_t EXCEPT_MASK = 0x809a'6184U;

if (LIBC_UNLIKELY((x_abs & EXCEPT_MASK) == 0)) {
// Exceptional values
if (LIBC_UNLIKELY(x_abs == 0x3f65'9229U)) // |x| = 0x1.cb2452p-1f
return x < 0.0f ? fputil::round_result_slightly_down(-0x1.972ea8p-1f)
: fputil::round_result_slightly_up(0x1.972ea8p-1f);
if (LIBC_UNLIKELY(x_abs == 0x4004'1e6aU)) // |x| = 0x1.083cd4p+1f
return x < 0.0f ? fputil::round_result_slightly_down(-0x1.fe3462p-1f)
: fputil::round_result_slightly_up(0x1.fe3462p-1f);
if (x_abs == 0U)
return x;
}

// Polynomial approximation:
// erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
double xd = static_cast<double>(x);
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/sin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ LLVM_LIBC_FUNCTION(double, sin, (double x)) {

DoubleDouble y;
unsigned k;
generic::LargeRangeReduction<NO_FMA> range_reduction_large;
generic::LargeRangeReduction<NO_FMA> range_reduction_large{};

// |x| < 2^32 (with FMA) or |x| < 2^23 (w/o FMA)
if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/sincos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ LLVM_LIBC_FUNCTION(void, sincos, (double x, double *sin_x, double *cos_x)) {

DoubleDouble y;
unsigned k;
generic::LargeRangeReduction<NO_FMA> range_reduction_large;
generic::LargeRangeReduction<NO_FMA> range_reduction_large{};

// |x| < 2^32 (with FMA) or |x| < 2^23 (w/o FMA)
if (LIBC_LIKELY(x_e < FPBits::EXP_BIAS + FAST_PASS_EXPONENT)) {
Expand Down
6 changes: 3 additions & 3 deletions libc/src/math/generic/sinpif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ LLVM_LIBC_FUNCTION(float, sinpif, (float x)) {
double xd = static_cast<double>(x);

// Range reduction:
// For |x| > pi/32, we perform range reduction as follows:
// For |x| > 1/32, we perform range reduction as follows:
// Find k and y such that:
// x = (k + y) * 1/32
// k is an integer
// |y| < 0.5
// For small range (|x| < 2^45 when FMA instructions are available, 2^22
// otherwise), this is done by performing:
//
// This is done by performing:
// k = round(x * 32)
// y = x * 32 - k
//
Expand Down
2 changes: 1 addition & 1 deletion libc/src/search/hsearch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

namespace LIBC_NAMESPACE {
LLVM_LIBC_FUNCTION(ENTRY *, hsearch, (ENTRY item, ACTION action)) {
ENTRY *result;
ENTRY *result = nullptr;
if (internal::global_hash_table == nullptr) {
// If global_hash_table is null, we create a new hash table with a minimal
// capacity. Such hashtable will be expanded as needed.
Expand Down
1 change: 1 addition & 0 deletions libc/src/sys/statvfs/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ add_header_library(
libc.src.__support.common
libc.src.__support.CPP.optional
libc.include.sys_syscall
libc.include.llvm-libc-types.struct_statvfs
)

add_entrypoint_object(
Expand Down
15 changes: 15 additions & 0 deletions libc/src/unistd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.fork
)

add_entrypoint_object(
fpathconf
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.fpathconf
)

add_entrypoint_object(
execv
ALIAS
Expand Down Expand Up @@ -160,6 +167,14 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.lseek
)

add_entrypoint_object(
pathconf
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.pathconf
)


add_entrypoint_object(
pipe
ALIAS
Expand Down
18 changes: 18 additions & 0 deletions libc/src/unistd/fpathconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//===-- Implementation header for fpathconf ---------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIBC_SRC_UNISTD_FPATHCONF_H
#define LLVM_LIBC_SRC_UNISTD_FPATHCONF_H

namespace LIBC_NAMESPACE {

long fpathconf(int fd, int name);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_UNISTD_FSYNC_H
42 changes: 42 additions & 0 deletions libc/src/unistd/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ add_entrypoint_object(
libc.src.errno.errno
)

add_entrypoint_object(
fpathconf
SRCS
fpathconf.cpp
HDRS
../fpathconf.h
DEPENDS
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
libc.src.unistd.linux.pathconf_utils
)

add_entrypoint_object(
execv
SRCS
Expand Down Expand Up @@ -273,6 +287,34 @@ add_entrypoint_object(
libc.src.errno.errno
)

add_entrypoint_object(
pathconf
SRCS
pathconf.cpp
HDRS
../pathconf.h
DEPENDS
libc.include.unistd
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
libc.src.unistd.linux.pathconf_utils
)

add_object_library(
pathconf_utils
SRCS
pathconf_utils.cpp
HDRS
pathconf_utils.h
DEPENDS
libc.hdr.limits_macros
libc.hdr.unistd_macros
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
libc.src.sys.statvfs.linux.statfs_utils
)

add_entrypoint_object(
pipe
SRCS
Expand Down
24 changes: 24 additions & 0 deletions libc/src/unistd/linux/fpathconf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Linux implementation of fpathconf ---------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/unistd/fpathconf.h"
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
#include "src/__support/common.h"
#include "src/sys/statvfs/linux/statfs_utils.h"
#include "src/unistd/linux/pathconf_utils.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, fpathconf, (int fd, int name)) {
if (cpp::optional<statfs_utils::LinuxStatFs> result =
statfs_utils::linux_fstatfs(fd))
return pathconfig(result.value(), name);
return -1;
}

} // namespace LIBC_NAMESPACE
23 changes: 23 additions & 0 deletions libc/src/unistd/linux/pathconf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===-- Linux implementation of pathconf ----------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "src/unistd/pathconf.h"
#include "src/errno/libc_errno.h"
#include "src/sys/statvfs/linux/statfs_utils.h"
#include "src/unistd/linux/pathconf_utils.h"

namespace LIBC_NAMESPACE {

LLVM_LIBC_FUNCTION(long, pathconf, (const char *path, int name)) {
if (cpp::optional<statfs_utils::LinuxStatFs> result =
statfs_utils::linux_statfs(path))
return pathconfig(result.value(), name);
return -1;
}

} // namespace LIBC_NAMESPACE
Loading