aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/HLSLResource.h5
-rw-r--r--clang/include/clang/Analysis/Analyses/LifetimeSafety.h24
-rw-r--r--clang/include/clang/Basic/CMakeLists.txt6
-rw-r--r--clang/include/clang/Basic/SanitizerSpecialCaseList.h6
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRAttrs.td57
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIROps.td94
-rw-r--r--clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td8
7 files changed, 192 insertions, 8 deletions
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/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/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/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/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
index 7714750..43832b7 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
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 66c4c04..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
diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
index a1ebd6c..b2c146c 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td
@@ -178,6 +178,12 @@ def CIR_AnyComplexOrIntOrBoolOrFloatType
}
//===----------------------------------------------------------------------===//
+// Record Type predicates
+//===----------------------------------------------------------------------===//
+
+def CIR_AnyRecordType : CIR_TypeBase<"::cir::RecordType", "record type">;
+
+//===----------------------------------------------------------------------===//
// Array Type predicates
//===----------------------------------------------------------------------===//
@@ -234,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>;
//===----------------------------------------------------------------------===//