aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/DeclTemplate.h7
-rw-r--r--clang/include/clang/AST/HLSLResource.h5
-rw-r--r--clang/include/clang/AST/TypeBase.h4
-rw-r--r--clang/include/clang/Analysis/Analyses/LifetimeSafety.h24
-rw-r--r--clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h7
-rw-r--r--clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def1
-rw-r--r--clang/include/clang/Basic/BuiltinsX86.td19
-rw-r--r--clang/include/clang/Basic/CMakeLists.txt6
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def2
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.h4
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td3
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/include/clang/Basic/SanitizerSpecialCaseList.h6
-rw-r--r--clang/include/clang/Basic/Sanitizers.def3
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRAttrs.td102
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h13
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRDialect.td1
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIROps.td156
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td22
-rw-r--r--clang/include/clang/CIR/MissingFeatures.h1
-rw-r--r--clang/include/clang/Driver/Options.td21
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h2
-rw-r--r--clang/include/clang/Sema/Overload.h10
23 files changed, 373 insertions, 48 deletions
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index a3c67a6..a4a1bb9 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -3395,9 +3395,10 @@ inline UnsignedOrNone getExpandedPackSize(const NamedDecl *Param) {
return std::nullopt;
}
-/// Internal helper used by Subst* nodes to retrieve the parameter list
-/// for their AssociatedDecl.
-TemplateParameterList *getReplacedTemplateParameterList(const Decl *D);
+/// Internal helper used by Subst* nodes to retrieve a parameter from the
+/// AssociatedDecl, and the template argument substituted into it, if any.
+std::tuple<NamedDecl *, TemplateArgument>
+getReplacedTemplateParameter(Decl *D, unsigned Index);
/// If we have a 'templated' declaration for a template, adjust 'D' to
/// refer to the actual template.
diff --git a/clang/include/clang/AST/HLSLResource.h b/clang/include/clang/AST/HLSLResource.h
index 9cdd81b..7440050 100644
--- a/clang/include/clang/AST/HLSLResource.h
+++ b/clang/include/clang/AST/HLSLResource.h
@@ -69,6 +69,11 @@ struct ResourceBindingAttrs {
assert(hasImplicitOrderID());
return RegBinding->getImplicitBindingOrderID();
}
+
+ void setImplicitOrderID(unsigned Value) const {
+ assert(hasBinding() && !isExplicit() && !hasImplicitOrderID());
+ RegBinding->setImplicitBindingOrderID(Value);
+ }
};
} // namespace hlsl
diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index 6786b2f..625cc77 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -7082,10 +7082,6 @@ public:
class SubstTemplateTypeParmPackType : public SubstPackType {
friend class ASTContext;
- /// A pointer to the set of template arguments that this
- /// parameter pack is instantiated with.
- const TemplateArgument *Arguments;
-
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl,
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
index 512cb76..e54fc26 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h
@@ -29,12 +29,18 @@
namespace clang::lifetimes {
/// Enum to track the confidence level of a potential error.
-enum class Confidence {
+enum class Confidence : uint8_t {
None,
Maybe, // Reported as a potential error (-Wlifetime-safety-strict)
Definite // Reported as a definite error (-Wlifetime-safety-permissive)
};
+enum class LivenessKind : uint8_t {
+ Dead, // Not alive
+ Maybe, // Live on some path but not all paths (may-be-live)
+ Must // Live on all paths (must-be-live)
+};
+
class LifetimeSafetyReporter {
public:
LifetimeSafetyReporter() = default;
@@ -55,6 +61,7 @@ class Fact;
class FactManager;
class LoanPropagationAnalysis;
class ExpiredLoansAnalysis;
+class LiveOriginAnalysis;
struct LifetimeFactory;
/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type.
@@ -89,6 +96,7 @@ inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, OriginID ID) {
// TODO(opt): Consider using a bitset to represent the set of loans.
using LoanSet = llvm::ImmutableSet<LoanID>;
using OriginSet = llvm::ImmutableSet<OriginID>;
+using OriginLoanMap = llvm::ImmutableMap<OriginID, LoanSet>;
/// A `ProgramPoint` identifies a location in the CFG by pointing to a specific
/// `Fact`. identified by a lifetime-related event (`Fact`).
@@ -110,8 +118,16 @@ public:
/// Returns the set of loans an origin holds at a specific program point.
LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const;
- /// Returns the set of loans that have expired at a specific program point.
- std::vector<LoanID> getExpiredLoansAtPoint(ProgramPoint PP) const;
+ /// Returns the set of origins that are live at a specific program point,
+ /// along with the confidence level of their liveness.
+ ///
+ /// An origin is considered live if there are potential future uses of that
+ /// origin after the given program point. The confidence level indicates
+ /// whether the origin is definitely live (Definite) due to being domintated
+ /// by a set of uses or only possibly live (Maybe) only on some but not all
+ /// control flow paths.
+ std::vector<std::pair<OriginID, LivenessKind>>
+ getLiveOriginsAtPoint(ProgramPoint PP) const;
/// Finds the OriginID for a given declaration.
/// Returns a null optional if not found.
@@ -138,7 +154,7 @@ private:
std::unique_ptr<LifetimeFactory> Factory;
std::unique_ptr<FactManager> FactMgr;
std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
- std::unique_ptr<ExpiredLoansAnalysis> ExpiredLoans;
+ std::unique_ptr<LiveOriginAnalysis> LiveOrigins;
};
} // namespace internal
} // namespace clang::lifetimes
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
index 9b53f1d..ea41eb3 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
@@ -139,6 +140,12 @@ public:
FixItList &&Fixes, const Decl *D,
const FixitStrategy &VarTargetTypes) = 0;
+ // Invoked when an array subscript operator[] is used on a
+ // std::unique_ptr<T[]>.
+ virtual void handleUnsafeUniquePtrArrayAccess(const DynTypedNode &Node,
+ bool IsRelatedToDecl,
+ ASTContext &Ctx) = 0;
+
#ifndef NDEBUG
public:
bool areDebugNotesRequested() {
diff --git a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
index 09fa510..fae5f8b 100644
--- a/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
+++ b/clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def
@@ -38,6 +38,7 @@ WARNING_GADGET(PointerArithmetic)
WARNING_GADGET(UnsafeBufferUsageAttr)
WARNING_GADGET(UnsafeBufferUsageCtorAttr)
WARNING_GADGET(DataInvocation)
+WARNING_GADGET(UniquePtrArrayAccess)
WARNING_OPTIONAL_GADGET(UnsafeLibcFunctionCall)
WARNING_OPTIONAL_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)`
FIXABLE_GADGET(ULCArraySubscript) // `DRE[any]` in an Unspecified Lvalue Context
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 4165225..217589d 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -123,13 +123,16 @@ let Attributes = [Const, NoThrow, RequiredVectorWidth<128>] in {
def Op#d128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
}
- def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">;
def pmulhrsw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def pshufb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
def psignb128 : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Vector<16, char>)">;
def psignw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def psignd128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
}
+
+ let Features = "ssse3", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
+ def pmaddubsw128 : X86Builtin<"_Vector<8, short>(_Vector<16, char>, _Vector<16, char>)">;
+ }
}
// AVX
@@ -278,13 +281,14 @@ let Features = "sse2", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] i
def psllw128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, _Vector<8, short>)">;
def pslld128 : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>)">;
def psllq128 : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>)">;
- def pmaddwd128 : X86Builtin<"_Vector<4, int>(_Vector<8, short>, _Vector<8, short>)">;
def pslldqi128_byteshift : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Constant int)">;
def psrldqi128_byteshift : X86Builtin<"_Vector<16, char>(_Vector<16, char>, _Constant int)">;
}
let Features = "sse2",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
+ def pmaddwd128 : X86Builtin<"_Vector<4, int>(_Vector<8, short>, _Vector<8, short>)">;
+
def pmuludq128 : X86Builtin<"_Vector<2, long long int>(_Vector<4, int>, _Vector<4, int>)">;
def psllwi128 : X86Builtin<"_Vector<8, short>(_Vector<8, short>, int)">;
@@ -581,8 +585,6 @@ let Features = "avx2", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] i
def phsubw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
def phsubd256 : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>)">;
def phsubsw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
- def pmaddubsw256 : X86Builtin<"_Vector<16, short>(_Vector<32, char>, _Vector<32, char>)">;
- def pmaddwd256 : X86Builtin<"_Vector<8, int>(_Vector<16, short>, _Vector<16, short>)">;
def pmovmskb256 : X86Builtin<"int(_Vector<32, char>)">;
def pmulhrsw256 : X86Builtin<"_Vector<16, short>(_Vector<16, short>, _Vector<16, short>)">;
def psadbw256 : X86Builtin<"_Vector<4, long long int>(_Vector<32, char>, _Vector<32, char>)">;
@@ -619,6 +621,9 @@ let Features = "avx2", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWi
def pblendvb256 : X86Builtin<"_Vector<32, char>(_Vector<32, char>, _Vector<32, char>, _Vector<32, char>)">;
+ def pmaddubsw256 : X86Builtin<"_Vector<16, short>(_Vector<32, char>, _Vector<32, char>)">;
+ def pmaddwd256 : X86Builtin<"_Vector<8, int>(_Vector<16, short>, _Vector<16, short>)">;
+
def pmuldq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
def pmuludq256 : X86Builtin<"_Vector<4, long long int>(_Vector<8, int>, _Vector<8, int>)">;
@@ -1378,10 +1383,6 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>
def subps512 : X86Builtin<"_Vector<16, float>(_Vector<16, float>, _Vector<16, float>, _Constant int)">;
}
-let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512>] in {
- def pmaddubsw512 : X86Builtin<"_Vector<32, short>(_Vector<64, char>, _Vector<64, char>)">;
- def pmaddwd512 : X86Builtin<"_Vector<16, int>(_Vector<32, short>, _Vector<32, short>)">;
-}
let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
def addss_round_mask : X86Builtin<"_Vector<4, float>(_Vector<4, float>, _Vector<4, float>, _Vector<4, float>, unsigned char, _Constant int)">;
@@ -1999,6 +2000,8 @@ let Features = "avx512bw", Attributes = [NoThrow, Const, RequiredVectorWidth<512
}
let Features = "avx512bw", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
+ def pmaddubsw512 : X86Builtin<"_Vector<32, short>(_Vector<64, char>, _Vector<64, char>)">;
+ def pmaddwd512 : X86Builtin<"_Vector<16, int>(_Vector<32, short>, _Vector<32, short>)">;
def psllv32hi : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Vector<32, short>)">;
def pshufhw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Constant int)">;
def pshuflw512 : X86Builtin<"_Vector<32, short>(_Vector<32, short>, _Constant int)">;
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 8173600..cfd165e 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -159,6 +159,9 @@ clang_tablegen(arm_mve_builtin_aliases.inc -gen-arm-mve-builtin-aliases
clang_tablegen(arm_sve_builtins.inc -gen-arm-sve-builtins
SOURCE arm_sve.td
TARGET ClangARMSveBuiltins)
+clang_tablegen(arm_sve_builtins.json -gen-arm-sve-builtins-json
+ SOURCE arm_sve.td
+ TARGET ClangARMSveBuiltinsJSON)
clang_tablegen(arm_sve_builtin_cg.inc -gen-arm-sve-builtin-codegen
SOURCE arm_sve.td
TARGET ClangARMSveBuiltinCG)
@@ -174,6 +177,9 @@ clang_tablegen(arm_sve_streaming_attrs.inc -gen-arm-sve-streaming-attrs
clang_tablegen(arm_sme_builtins.inc -gen-arm-sme-builtins
SOURCE arm_sme.td
TARGET ClangARMSmeBuiltins)
+clang_tablegen(arm_sme_builtins.json -gen-arm-sme-builtins-json
+ SOURCE arm_sme.td
+ TARGET ClangARMSmeBuiltinsJSON)
clang_tablegen(arm_sme_builtin_cg.inc -gen-arm-sme-builtin-codegen
SOURCE arm_sme.td
TARGET ClangARMSmeBuiltinCG)
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 872f73e..d924cb4 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -306,6 +306,8 @@ CODEGENOPT(SanitizeBinaryMetadataCovered, 1, 0, Benign) ///< Emit PCs for covere
CODEGENOPT(SanitizeBinaryMetadataAtomics, 1, 0, Benign) ///< Emit PCs for atomic operations.
CODEGENOPT(SanitizeBinaryMetadataUAR, 1, 0, Benign) ///< Emit PCs for start of functions
///< that are subject for use-after-return checking.
+CODEGENOPT(SanitizeAllocTokenFastABI, 1, 0, Benign) ///< Use the AllocToken fast ABI.
+CODEGENOPT(SanitizeAllocTokenExtended, 1, 0, Benign) ///< Extend coverage to custom allocation functions.
CODEGENOPT(SanitizeStats , 1, 0, Benign) ///< Collect statistics for sanitizers.
ENUM_CODEGENOPT(SanitizeDebugTrapReasons, SanitizeDebugTrapReasonKind, 2, SanitizeDebugTrapReasonKind::Detailed, Benign) ///< Control how "trap reasons" are emitted in debug info
CODEGENOPT(SimplifyLibCalls , 1, 1, Benign) ///< Set when -fbuiltin is enabled.
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 5d5cf25..cae06c3 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -447,6 +447,10 @@ public:
std::optional<double> AllowRuntimeCheckSkipHotCutoff;
+ /// Maximum number of allocation tokens (0 = no max), nullopt if none set (use
+ /// pass default).
+ std::optional<uint64_t> AllocTokenMax;
+
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 0c994e0..4b27a42 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1750,7 +1750,8 @@ def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;
// Warnings and fixes to support the "safe buffers" programming model.
def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">;
def UnsafeBufferUsageInLibcCall : DiagGroup<"unsafe-buffer-usage-in-libc-call">;
-def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall]>;
+def UnsafeBufferUsageInUniquePtrArrayAccess : DiagGroup<"unsafe-buffer-usage-in-unique-ptr-array-access">;
+def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall, UnsafeBufferUsageInUniquePtrArrayAccess]>;
// Warnings and notes InstallAPI verification.
def InstallAPIViolation : DiagGroup<"installapi-violation">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b157cbb..5be63c0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13295,6 +13295,8 @@ def note_safe_buffer_usage_suggestions_disabled : Note<
def warn_unsafe_buffer_usage_in_container : Warning<
"the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information">,
InGroup<UnsafeBufferUsageInContainer>, DefaultIgnore;
+def warn_unsafe_buffer_usage_unique_ptr_array_access : Warning<"direct access using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds checking">,
+ InGroup<UnsafeBufferUsageInUniquePtrArrayAccess>, DefaultIgnore;
#ifndef NDEBUG
// Not a user-facing diagnostic. Useful for debugging false negatives in
// -fsafe-buffer-usage-suggestions (i.e. lack of -Wunsafe-buffer-usage fixits).
diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
index cf74859..a05da4c 100644
--- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h
+++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -57,12 +57,10 @@ protected:
void createSanitizerSections();
struct SanitizerSection {
- SanitizerSection(SanitizerMask SM, SectionEntries &E, unsigned idx)
- : Mask(SM), Entries(E), FileIdx(idx) {};
+ SanitizerSection(SanitizerMask SM, const Section &S) : Mask(SM), S(S) {};
SanitizerMask Mask;
- SectionEntries &Entries;
- unsigned FileIdx;
+ const Section &S;
};
std::vector<SanitizerSection> SanitizerSections;
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index 1d0e97c..da85431 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -195,6 +195,9 @@ SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds)
// Scudo hardened allocator
SANITIZER("scudo", Scudo)
+// AllocToken
+SANITIZER("alloc-token", AllocToken)
+
// Magic group, containing all sanitizers. For example, "-fno-sanitize=all"
// can be used to disable all the sanitizers.
SANITIZER_GROUP("all", All, ~SanitizerMask())
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 7714750..bb62223 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
@@ -602,6 +602,63 @@ def CIR_VTableAttr : CIR_Attr<"VTable", "vtable", [TypedAttrInterface]> {
}
//===----------------------------------------------------------------------===//
+// DynamicCastInfoAttr
+//===----------------------------------------------------------------------===//
+
+def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> {
+ let summary = "ABI specific information about a dynamic cast";
+ let description = [{
+ Provide ABI specific information about a dynamic cast operation.
+
+ The `src_rtti` and the `dest_rtti` parameters give the RTTI of the source
+ record type and the destination record type, respectively.
+
+ The `runtime_func` parameter gives the `__dynamic_cast` function which is
+ provided by the runtime. The `bad_cast_func` parameter gives the
+ `__cxa_bad_cast` function which is also provided by the runtime.
+
+ The `offset_hint` parameter gives the hint value that should be passed to
+ the `__dynamic_cast` runtime function.
+ }];
+
+ let parameters = (ins
+ CIR_GlobalViewAttr:$src_rtti,
+ CIR_GlobalViewAttr:$dest_rtti,
+ "mlir::FlatSymbolRefAttr":$runtime_func,
+ "mlir::FlatSymbolRefAttr":$bad_cast_func,
+ CIR_IntAttr:$offset_hint
+ );
+
+ let builders = [
+ AttrBuilderWithInferredContext<(ins
+ "GlobalViewAttr":$src_rtti,
+ "GlobalViewAttr":$dest_rtti,
+ "mlir::FlatSymbolRefAttr":$runtime_func,
+ "mlir::FlatSymbolRefAttr":$bad_cast_func,
+ "IntAttr":$offset_hint), [{
+ return $_get(src_rtti.getContext(), src_rtti, dest_rtti, runtime_func,
+ bad_cast_func, offset_hint);
+ }]>,
+ ];
+
+ let genVerifyDecl = 1;
+ let assemblyFormat = [{
+ `<`
+ struct(qualified($src_rtti),
+ qualified($dest_rtti),
+ $runtime_func,
+ $bad_cast_func,
+ qualified($offset_hint))
+ `>`
+ }];
+
+ let extraClassDeclaration = [{
+ /// Get attribute alias name for this attribute.
+ std::string getAlias() const;
+ }];
+}
+
+//===----------------------------------------------------------------------===//
// TargetAddressSpaceAttr
//===----------------------------------------------------------------------===//
@@ -713,6 +770,51 @@ def CIR_VisibilityAttr : CIR_EnumAttr<CIR_VisibilityKind, "visibility"> {
}
//===----------------------------------------------------------------------===//
+// GloblCtorAttr
+//===----------------------------------------------------------------------===//
+
+class CIR_GlobalCtorDtor<string name, string attrMnemonic>
+ : CIR_Attr<"Global" # name, "global_" # attrMnemonic> {
+ let parameters = (ins "mlir::StringAttr":$name, "int":$priority);
+
+ let skipDefaultBuilders = 1;
+ let builders = [
+ AttrBuilder<(ins
+ "llvm::StringRef":$name,
+ CArg<"int", "65535">:$priority), [{
+ return $_get($_ctxt, mlir::StringAttr::get($_ctxt, name), priority);
+ }]>,
+ AttrBuilderWithInferredContext<(ins
+ "mlir::StringAttr":$name,
+ CArg<"int", "65535">:$priority), [{
+ return $_get(name.getContext(), name, priority);
+ }]>
+ ];
+
+ let assemblyFormat = [{
+ `<` $name `,` $priority `>`
+ }];
+
+ let extraClassDeclaration = [{
+ bool isDefaultPriority() const {
+ return getPriority() == getDefaultPriority();
+ };
+
+ static int getDefaultPriority() {
+ return 65535;
+ }
+ }];
+}
+
+def CIR_GlobalCtorAttr : CIR_GlobalCtorDtor<"Ctor", "ctor"> {
+ let summary = "Marks a function as a global constructor";
+ let description = [{
+ Marks the function as a global constructor in the module's constructor list.
+ It will be executed before main() is called.
+ }];
+}
+
+//===----------------------------------------------------------------------===//
// BitfieldInfoAttr
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
index 417a226..5c6ce7a 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDataLayout.h
@@ -14,6 +14,7 @@
#include "mlir/Dialect/DLTI/DLTI.h"
#include "mlir/IR/BuiltinOps.h"
+#include "clang/CIR/Dialect/IR/CIRTypes.h"
namespace cir {
@@ -81,6 +82,18 @@ public:
}
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const;
+
+ llvm::TypeSize getPointerTypeSizeInBits(mlir::Type ty) const {
+ assert(mlir::isa<cir::PointerType>(ty) &&
+ "This should only be called with a pointer type");
+ return layout.getTypeSizeInBits(ty);
+ }
+
+ mlir::Type getIntPtrType(mlir::Type ty) const {
+ assert(mlir::isa<cir::PointerType>(ty) && "Expected pointer type");
+ return cir::IntType::get(ty.getContext(), getPointerTypeSizeInBits(ty),
+ false);
+ }
};
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
index 15d5fa0..feb08d60 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td
@@ -42,6 +42,7 @@ def CIR_Dialect : Dialect {
static llvm::StringRef getNoThrowAttrName() { return "nothrow"; }
static llvm::StringRef getSideEffectAttrName() { return "side_effect"; }
static llvm::StringRef getModuleLevelAsmAttrName() { return "cir.module_asm"; }
+ static llvm::StringRef getGlobalCtorsAttrName() { return "cir.global_ctors"; }
void registerAttributes();
void registerTypes();
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d4ffcf3..27fe0cc 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -232,6 +232,100 @@ def CIR_CastOp : CIR_Op<"cast", [
}];
}
+//===----------------------------------------------------------------------===//
+// DynamicCastOp
+//===----------------------------------------------------------------------===//
+
+def CIR_DynamicCastKind : CIR_I32EnumAttr<
+ "DynamicCastKind", "dynamic cast kind", [
+ I32EnumAttrCase<"Ptr", 0, "ptr">,
+ I32EnumAttrCase<"Ref", 1, "ref">
+]>;
+
+def CIR_DynamicCastOp : CIR_Op<"dyn_cast"> {
+ let summary = "Perform dynamic cast on record pointers";
+ let description = [{
+ The `cir.dyn_cast` operation models part of the semantics of the
+ `dynamic_cast` operator in C++. It can be used to perform 3 kinds of casts
+ on record pointers:
+
+ - Down-cast, which casts a base class pointer to a derived class pointer;
+ - Side-cast, which casts a class pointer to a sibling class pointer;
+ - Cast-to-complete, which casts a class pointer to a void pointer.
+
+ The input of the operation must be a record pointer. The result of the
+ operation is either a record pointer or a void pointer.
+
+ The parameter `kind` specifies the semantics of this operation. If its value
+ is `ptr`, then the operation models dynamic casts on pointers. Otherwise, if
+ its value is `ref`, the operation models dynamic casts on references.
+ Specifically:
+
+ - When the input pointer is a null pointer value:
+ - If `kind` is `ref`, the operation will invoke undefined behavior. A
+ sanitizer check will be emitted if sanitizer is on.
+ - Otherwise, the operation will return a null pointer value as its result.
+ - When the runtime type check fails:
+ - If `kind` is `ref`, the operation will throw a `bad_cast` exception.
+ - Otherwise, the operation will return a null pointer value as its result.
+
+ The `info` argument gives detailed information about the requested dynamic
+ cast operation. It is an optional `#cir.dyn_cast_info` attribute that is
+ only present when the operation models a down-cast or a side-cast.
+
+ The `relative_layout` argument specifies whether the Itanium C++ ABI vtable
+ uses relative layout. It is only meaningful when the operation models a
+ cast-to-complete operation.
+
+ Examples:
+
+ ```mlir
+ %0 = cir.dyn_cast ptr %p : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived>
+ %1 = cir.dyn_cast ptr relative_layout %p : !cir.ptr<!rec_Base>
+ -> !cir.ptr<!rec_Derived>
+ %2 = cir.dyn_cast ref %r : !cir.ptr<!rec_Base> -> !cir.ptr<!rec_Derived>
+ #cir.dyn_cast_info<
+ srcRtti = #cir.global_view<@_ZTI4Base> : !cir.ptr<!u8i>,
+ destRtti = #cir.global_view<@_ZTI7Derived> : !cir.ptr<!u8i>,
+ runtimeFunc = @__dynamic_cast,
+ badCastFunc = @__cxa_bad_cast,
+ offsetHint = #cir.int<0> : !s64i
+ >
+ ```
+ }];
+
+ let arguments = (ins
+ CIR_DynamicCastKind:$kind,
+ CIR_PtrToRecordType:$src,
+ OptionalAttr<CIR_DynamicCastInfoAttr>:$info,
+ UnitAttr:$relative_layout
+ );
+
+ let results = (outs
+ CIR_PtrToAnyOf<[CIR_VoidType, CIR_RecordType]>:$result
+ );
+
+ let assemblyFormat = [{
+ $kind (`relative_layout` $relative_layout^)? $src
+ `:` qualified(type($src)) `->` qualified(type($result))
+ (qualified($info)^)? attr-dict
+ }];
+
+ let extraClassDeclaration = [{
+ /// Determine whether this operation models reference casting in C++.
+ bool isRefCast() {
+ return getKind() == ::cir::DynamicCastKind::Ref;
+ }
+
+ /// Determine whether this operation represents a dynamic cast to a void
+ /// pointer.
+ bool isCastToVoid() {
+ return getType().isVoidPtr();
+ }
+ }];
+
+ let hasLLVMLowering = false;
+}
//===----------------------------------------------------------------------===//
// PtrStrideOp
@@ -278,22 +372,22 @@ def CIR_PtrStrideOp : CIR_Op<"ptr_stride", [
def CIR_ConstantOp : CIR_Op<"const", [
ConstantLike, Pure, AllTypesMatch<["value", "res"]>
]> {
- let summary = "Defines a CIR constant";
+ let summary = "Create a CIR constant from a literal attribute";
let description = [{
The `cir.const` operation turns a literal into an SSA value. The data is
attached to the operation as an attribute.
```mlir
- %0 = cir.const 42 : i32
- %1 = cir.const 4.2 : f32
- %2 = cir.const nullptr : !cir.ptr<i32>
+ %0 = cir.const #cir.int<4> : !u32i
+ %1 = cir.const #cir.fp<1.500000e+00> : !cir.float
+ %2 = cir.const #cir.ptr<null> : !cir.ptr<!void>
```
}];
let arguments = (ins TypedAttrInterface:$value);
let results = (outs CIR_AnyType:$res);
- let assemblyFormat = "attr-dict $value";
+ let assemblyFormat = "$value attr-dict";
let hasVerifier = 1;
@@ -3277,9 +3371,9 @@ def CIR_ComplexCreateOp : CIR_Op<"complex.create", [Pure, SameTypeOperands]> {
def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
let summary = "Extract the real part of a complex value";
let description = [{
- `cir.complex.real` operation takes an operand of `!cir.complex`, `!cir.int`
- or `!cir.float`. If the operand is `!cir.complex`, the real part of it will
- be returned, otherwise the value returned unmodified.
+ `cir.complex.real` operation takes an operand of `!cir.complex`, `cir.int`,
+ `!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the real
+ part of it will be returned, otherwise the value returned unmodified.
Example:
@@ -3289,8 +3383,8 @@ def CIR_ComplexRealOp : CIR_Op<"complex.real", [Pure]> {
```
}];
- let results = (outs CIR_AnyIntOrFloatType:$result);
- let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
+ let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
+ let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
let assemblyFormat = [{
$operand `:` qualified(type($operand)) `->` qualified(type($result))
@@ -3309,8 +3403,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
let summary = "Extract the imaginary part of a complex value";
let description = [{
`cir.complex.imag` operation takes an operand of `!cir.complex`, `!cir.int`
- or `!cir.float`. If the operand is `!cir.complex`, the imag part of it will
- be returned, otherwise a zero value will be returned.
+ `!cir.bool` or `!cir.float`. If the operand is `!cir.complex`, the imag
+ part of it will be returned, otherwise a zero value will be returned.
Example:
@@ -3320,8 +3414,8 @@ def CIR_ComplexImagOp : CIR_Op<"complex.imag", [Pure]> {
```
}];
- let results = (outs CIR_AnyIntOrFloatType:$result);
- let arguments = (ins CIR_AnyComplexOrIntOrFloatType:$operand);
+ let results = (outs CIR_AnyIntOrBoolOrFloatType:$result);
+ let arguments = (ins CIR_AnyComplexOrIntOrBoolOrFloatType:$operand);
let assemblyFormat = [{
$operand `:` qualified(type($operand)) `->` qualified(type($result))
@@ -4169,6 +4263,40 @@ def CIR_ThrowOp : CIR_Op<"throw"> {
}
//===----------------------------------------------------------------------===//
+// AllocExceptionOp
+//===----------------------------------------------------------------------===//
+
+def CIR_AllocExceptionOp : CIR_Op<"alloc.exception"> {
+ let summary = "Allocates an exception according to Itanium ABI";
+ let description = [{
+ Implements a slightly higher level __cxa_allocate_exception:
+
+ `void *__cxa_allocate_exception(size_t thrown_size);`
+
+ If the operation fails, the program terminates rather than throw.
+
+ Example:
+
+ ```mlir
+ // if (b == 0) {
+ // ...
+ // throw "...";
+ cir.if %10 {
+ %11 = cir.alloc_exception 8 -> !cir.ptr<!void>
+ ... // store exception content into %11
+ cir.throw %11 : !cir.ptr<!cir.ptr<!u8i>>, ...
+ ```
+ }];
+
+ let arguments = (ins I64Attr:$size);
+ let results = (outs Res<CIR_PointerType, "", [MemAlloc<DefaultResource>]>:$addr);
+
+ let assemblyFormat = [{
+ $size `->` qualified(type($addr)) attr-dict
+ }];
+}
+
+//===----------------------------------------------------------------------===//
// Atomic operations
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index da03a29..b2c146c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -159,19 +159,31 @@ def CIR_AnyIntOrFloatType : AnyTypeOf<[CIR_AnyFloatType, CIR_AnyIntType],
let cppFunctionName = "isAnyIntegerOrFloatingPointType";
}
+def CIR_AnyIntOrBoolOrFloatType
+ : AnyTypeOf<[CIR_AnyBoolType, CIR_AnyFloatType, CIR_AnyIntType],
+ "integer, boolean or floating point type"> {
+ let cppFunctionName = "isAnyIntegerOrBooleanOrFloatingPointType";
+}
+
//===----------------------------------------------------------------------===//
// Complex Type predicates
//===----------------------------------------------------------------------===//
def CIR_AnyComplexType : CIR_TypeBase<"::cir::ComplexType", "complex type">;
-def CIR_AnyComplexOrIntOrFloatType : AnyTypeOf<[
- CIR_AnyComplexType, CIR_AnyFloatType, CIR_AnyIntType
-], "complex, integer or floating point type"> {
- let cppFunctionName = "isComplexOrIntegerOrFloatingPointType";
+def CIR_AnyComplexOrIntOrBoolOrFloatType
+ : AnyTypeOf<[CIR_AnyComplexType, CIR_AnyIntOrBoolOrFloatType],
+ "complex, integer or floating point type"> {
+ let cppFunctionName = "isComplexOrIntegerOrBoolOrFloatingPointType";
}
//===----------------------------------------------------------------------===//
+// Record Type predicates
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyRecordType : CIR_TypeBase<"::cir::RecordType", "record type">;
+
+//===----------------------------------------------------------------------===//
// Array Type predicates
//===----------------------------------------------------------------------===//
@@ -228,6 +240,8 @@ def CIR_PtrToIntOrFloatType : CIR_PtrToType<CIR_AnyIntOrFloatType>;
def CIR_PtrToComplexType : CIR_PtrToType<CIR_AnyComplexType>;
+def CIR_PtrToRecordType : CIR_PtrToType<CIR_AnyRecordType>;
+
def CIR_PtrToArray : CIR_PtrToType<CIR_AnyArrayType>;
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index f795800..3b7b130 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -39,7 +39,6 @@ struct MissingFeatures {
static bool opGlobalUsedOrCompilerUsed() { return false; }
static bool opGlobalAnnotations() { return false; }
static bool opGlobalDtorLowering() { return false; }
- static bool opGlobalCtorAttr() { return false; }
static bool opGlobalCtorPriority() { return false; }
static bool opGlobalCtorList() { return false; }
static bool setDSOLocal() { return false; }
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 60c4ad4..ec38231 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2731,8 +2731,25 @@ def fsanitize_skip_hot_cutoff_EQ
"(0.0 [default] = skip none; 1.0 = skip all). "
"Argument format: <sanitizer1>=<value1>,<sanitizer2>=<value2>,...">;
+defm sanitize_alloc_token_fast_abi : BoolOption<"f", "sanitize-alloc-token-fast-abi",
+ CodeGenOpts<"SanitizeAllocTokenFastABI">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Use the AllocToken fast ABI">,
+ NegFlag<SetFalse, [], [ClangOption], "Use the default AllocToken ABI">>,
+ Group<f_clang_Group>;
+defm sanitize_alloc_token_extended : BoolOption<"f", "sanitize-alloc-token-extended",
+ CodeGenOpts<"SanitizeAllocTokenExtended">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption], "Enable">,
+ NegFlag<SetFalse, [], [ClangOption], "Disable">,
+ BothFlags<[], [ClangOption], " extended coverage to custom allocation functions">>,
+ Group<f_clang_Group>;
+
} // end -f[no-]sanitize* flags
+def falloc_token_max_EQ : Joined<["-"], "falloc-token-max=">,
+ Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
+ MetaVarName<"<N>">,
+ HelpText<"Limit to maximum N allocation tokens (0 = no max)">;
+
def fallow_runtime_check_skip_hot_cutoff_EQ
: Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
Group<f_clang_Group>,
@@ -4715,6 +4732,10 @@ def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 4">;
def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 5">;
+def gdwarf_6
+ : Flag<["-"], "gdwarf-6">,
+ Group<g_Group>,
+ HelpText<"Generate source-level debug information with dwarf version 6">;
}
def gdwarf64 : Flag<["-"], "gdwarf64">, Group<g_Group>,
Visibility<[ClangOption, CC1Option, CC1AsOption]>,
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 2b72268..eea7897 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -75,6 +75,8 @@ class SanitizerArgs {
llvm::AsanDetectStackUseAfterReturnMode::Invalid;
std::string MemtagMode;
+ bool AllocTokenFastABI = false;
+ bool AllocTokenExtended = false;
public:
/// Parses the sanitizer arguments from an argument list.
diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h
index d34a414..59bbd0f 100644
--- a/clang/include/clang/Sema/Overload.h
+++ b/clang/include/clang/Sema/Overload.h
@@ -1202,12 +1202,12 @@ class Sema;
/// Would use of this function result in a rewrite using a different
/// operator?
- bool isRewrittenOperator(const FunctionDecl *FD) {
+ bool isRewrittenOperator(const FunctionDecl *FD) const {
return OriginalOperator &&
FD->getDeclName().getCXXOverloadedOperator() != OriginalOperator;
}
- bool isAcceptableCandidate(const FunctionDecl *FD) {
+ bool isAcceptableCandidate(const FunctionDecl *FD) const {
if (!OriginalOperator)
return true;
@@ -1234,7 +1234,7 @@ class Sema;
}
/// Determines whether this operator could be implemented by a function
/// with reversed parameter order.
- bool isReversible() {
+ bool isReversible() const {
return AllowRewrittenCandidates && OriginalOperator &&
(getRewrittenOverloadedOperator(OriginalOperator) != OO_None ||
allowsReversed(OriginalOperator));
@@ -1242,13 +1242,13 @@ class Sema;
/// Determine whether reversing parameter order is allowed for operator
/// Op.
- bool allowsReversed(OverloadedOperatorKind Op);
+ bool allowsReversed(OverloadedOperatorKind Op) const;
/// Determine whether we should add a rewritten candidate for \p FD with
/// reversed parameter order.
/// \param OriginalArgs are the original non reversed arguments.
bool shouldAddReversed(Sema &S, ArrayRef<Expr *> OriginalArgs,
- FunctionDecl *FD);
+ FunctionDecl *FD) const;
};
private: