diff options
Diffstat (limited to 'clang/include')
30 files changed, 345 insertions, 102 deletions
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b929585..be038d9 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -6953,7 +6953,7 @@ clang_getCursorUnaryOperatorKind(CXCursor cursor); * @} */ -CINDEX_DEPRECATED +/* CINDEX_DEPRECATED - disabled to silence MSVC deprecation warnings */ typedef void *CXRemapping; CINDEX_DEPRECATED CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *); diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 66ec339..17cbfb2 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -277,6 +277,11 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::ContextualFoldingSet<ArrayParameterType, ASTContext &> ArrayParameterTypes; + /// Store the unique Type corresponding to each Kind. + mutable std::array<Type *, + llvm::to_underlying(PredefinedSugarType::Kind::Last) + 1> + PredefinedSugarTypes{}; + /// The set of nested name specifiers. /// /// This set is managed by the NestedNameSpecifier class. @@ -1192,6 +1197,8 @@ public: bool isInSameModule(const Module *M1, const Module *M2) const; TranslationUnitDecl *getTranslationUnitDecl() const { + assert(TUDecl->getMostRecentDecl() == TUDecl && + "The active TU is not current one!"); return TUDecl->getMostRecentDecl(); } void addTranslationUnitDecl() { @@ -1567,6 +1574,8 @@ public: /// and bit count. QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const; + QualType getPredefinedSugarType(PredefinedSugarType::Kind KD) const; + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; @@ -1999,11 +2008,13 @@ public: /// <stddef.h>. /// /// The sizeof operator requires this (C99 6.5.3.4p4). - CanQualType getSizeType() const; + QualType getSizeType() const; + + CanQualType getCanonicalSizeType() const; /// Return the unique signed counterpart of /// the integer type corresponding to size_t. - CanQualType getSignedSizeType() const; + QualType getSignedSizeType() const; /// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in /// <stdint.h>. diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h index 3560766..a284f2c 100644 --- a/clang/include/clang/AST/FormatString.h +++ b/clang/include/clang/AST/FormatString.h @@ -489,7 +489,8 @@ public: /// For a TypedefType QT, if it is a named integer type such as size_t, /// assign the appropriate value to LM and return true. - static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM); + static bool namedTypeToLengthModifier(ASTContext &Ctx, QualType QT, + LengthModifier &LM); }; } // end analyze_format_string namespace diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 519a811..62991d9 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1208,6 +1208,8 @@ DEF_TRAVERSE_TYPE(BitIntType, {}) DEF_TRAVERSE_TYPE(DependentBitIntType, { TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) +DEF_TRAVERSE_TYPE(PredefinedSugarType, {}) + #undef DEF_TRAVERSE_TYPE // ----------------- TypeLoc traversal ----------------- @@ -1524,6 +1526,8 @@ DEF_TRAVERSE_TYPELOC(DependentBitIntType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); }) +DEF_TRAVERSE_TYPELOC(PredefinedSugarType, {}) + #undef DEF_TRAVERSE_TYPELOC // ----------------- Decl traversal ----------------- diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 21b9710..764e9d50 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2258,6 +2258,30 @@ protected: unsigned NumExpansions; }; + enum class PredefinedSugarKind { + /// The "size_t" type. + SizeT, + + /// The signed integer type corresponding to "size_t". + SignedSizeT, + + /// The "ptrdiff_t" type. + PtrdiffT, + + // Indicates how many items the enum has. + Last = PtrdiffT + }; + + class PresefinedSugarTypeBitfields { + friend class PredefinedSugarType; + + LLVM_PREFERRED_TYPE(TypeBitfields) + unsigned : NumTypeBits; + + LLVM_PREFERRED_TYPE(PredefinedSugarKind) + unsigned Kind : 8; + }; + class CountAttributedTypeBitfields { friend class CountAttributedType; @@ -2297,6 +2321,7 @@ protected: DependentTemplateSpecializationTypeBits; PackExpansionTypeBitfields PackExpansionTypeBits; CountAttributedTypeBitfields CountAttributedTypeBits; + PresefinedSugarTypeBitfields PredefinedSugarTypeBits; }; private: @@ -8038,6 +8063,37 @@ public: } }; +class PredefinedSugarType final : public Type { +public: + friend class ASTContext; + using Kind = PredefinedSugarKind; + +private: + PredefinedSugarType(Kind KD, const IdentifierInfo *IdentName, + QualType CanonicalType) + : Type(PredefinedSugar, CanonicalType, TypeDependence::None), + Name(IdentName) { + PredefinedSugarTypeBits.Kind = llvm::to_underlying(KD); + } + + static StringRef getName(Kind KD); + + const IdentifierInfo *Name; + +public: + bool isSugared() const { return true; } + + QualType desugar() const { return getCanonicalTypeInternal(); } + + Kind getKind() const { return Kind(PredefinedSugarTypeBits.Kind); } + + const IdentifierInfo *getIdentifier() const { return Name; } + + static bool classof(const Type *T) { + return T->getTypeClass() == PredefinedSugar; + } +}; + /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index cf06e27..be0bc89 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -2783,6 +2783,16 @@ public: } }; +struct PredefinedSugarTypeLocInfo {}; // Nothing. + +class PredefinedSugarTypeLoc final + : public ConcreteTypeLoc<UnqualTypeLoc, PredefinedSugarTypeLoc, + PredefinedSugarType, PredefinedSugarTypeLocInfo> { +public: + void initializeLocal(ASTContext &Context, SourceLocation loc) {} + SourceRange getLocalSourceRange() const { return {}; } +}; + } // namespace clang #endif // LLVM_CLANG_AST_TYPELOC_H diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index a615764..3114d11 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -1028,3 +1028,12 @@ let Class = DependentBitIntType in { return ctx.getDependentBitIntType(isUnsigned, numBitsExpr); }]>; } + +let Class = PredefinedSugarType in { + def : Property<"kind", UInt32> { + let Read = [{ static_cast<uint32_t>(node->getKind()) }]; + } + def : Creator<[{ + return ctx.getPredefinedSugarType(static_cast<PredefinedSugarType::Kind>(kind)); + }]>; +} diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h index 9998702..beeb0aa 100644 --- a/clang/include/clang/Analysis/Analyses/LifetimeSafety.h +++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety.h @@ -17,14 +17,96 @@ //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H #define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H -#include "clang/AST/DeclBase.h" #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" -namespace clang { +#include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/StringMap.h" +#include <memory> -void runLifetimeSafetyAnalysis(const DeclContext &DC, const CFG &Cfg, - AnalysisDeclContext &AC); +namespace clang::lifetimes { -} // namespace clang +/// The main entry point for the analysis. +void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC); + +namespace internal { +// Forward declarations of internal types. +class Fact; +class FactManager; +class LoanPropagationAnalysis; +struct LifetimeFactory; + +/// A generic, type-safe wrapper for an ID, distinguished by its `Tag` type. +/// Used for giving ID to loans and origins. +template <typename Tag> struct ID { + uint32_t Value = 0; + + bool operator==(const ID<Tag> &Other) const { return Value == Other.Value; } + bool operator!=(const ID<Tag> &Other) const { return !(*this == Other); } + bool operator<(const ID<Tag> &Other) const { return Value < Other.Value; } + ID<Tag> operator++(int) { + ID<Tag> Tmp = *this; + ++Value; + return Tmp; + } + void Profile(llvm::FoldingSetNodeID &IDBuilder) const { + IDBuilder.AddInteger(Value); + } +}; + +using LoanID = ID<struct LoanTag>; +using OriginID = ID<struct OriginTag>; + +// Using LLVM's immutable collections is efficient for dataflow analysis +// as it avoids deep copies during state transitions. +// TODO(opt): Consider using a bitset to represent the set of loans. +using LoanSet = llvm::ImmutableSet<LoanID>; +using OriginSet = llvm::ImmutableSet<OriginID>; + +/// A `ProgramPoint` identifies a location in the CFG by pointing to a specific +/// `Fact`. identified by a lifetime-related event (`Fact`). +/// +/// A `ProgramPoint` has "after" semantics: it represents the location +/// immediately after its corresponding `Fact`. +using ProgramPoint = const Fact *; + +/// Running the lifetime safety analysis and querying its results. It +/// encapsulates the various dataflow analyses. +class LifetimeSafetyAnalysis { +public: + LifetimeSafetyAnalysis(AnalysisDeclContext &AC); + ~LifetimeSafetyAnalysis(); + + void run(); + + /// Returns the set of loans an origin holds at a specific program point. + LoanSet getLoansAtPoint(OriginID OID, ProgramPoint PP) const; + + /// Finds the OriginID for a given declaration. + /// Returns a null optional if not found. + std::optional<OriginID> getOriginIDForDecl(const ValueDecl *D) const; + + /// Finds the LoanID's for the loan created with the specific variable as + /// their Path. + std::vector<LoanID> getLoanIDForVar(const VarDecl *VD) const; + + /// Retrieves program points that were specially marked in the source code + /// for testing. + /// + /// The analysis recognizes special function calls of the form + /// `void("__lifetime_test_point_<name>")` as test points. This method returns + /// a map from the annotation string (<name>) to the corresponding + /// `ProgramPoint`. This allows test harnesses to query the analysis state at + /// user-defined locations in the code. + /// \note This is intended for testing only. + llvm::StringMap<ProgramPoint> getTestPoints() const; + +private: + AnalysisDeclContext &AC; + std::unique_ptr<LifetimeFactory> Factory; + std::unique_ptr<FactManager> FactMgr; + std::unique_ptr<LoanPropagationAnalysis> LoanPropagation; +}; +} // namespace internal +} // namespace clang::lifetimes #endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index a916af7..8785435 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -684,6 +684,8 @@ TARGET_BUILTIN(__builtin_amdgcn_cvt_f16_fp8, "hiIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_f16_bf8, "hiIi", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f16_fp8, "V2hs", "nc", "gfx1250-insts") TARGET_BUILTIN(__builtin_amdgcn_cvt_pk_f16_bf8, "V2hs", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_sat_pk4_i4_i8, "UsUi", "nc", "gfx1250-insts") +TARGET_BUILTIN(__builtin_amdgcn_sat_pk4_u4_u8, "UsUi", "nc", "gfx1250-insts") // GFX1250 WMMA builtins TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x4_f32, "V8fIbV2fIbV2fIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") @@ -703,6 +705,7 @@ TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_fp8_fp8, "V8hV16iV16iIsV8hIbI TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_fp8_bf8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_bf8_fp8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f16_16x16x128_bf8_bf8, "V8hV16iV16iIsV8hIbIb", "nc", "gfx1250-insts,wavefrontsize32") +TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_f8f6f4, "V8fIiV16iIiV16iIsV8f", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_fp8_fp8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_fp8_bf8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") TARGET_BUILTIN(__builtin_amdgcn_wmma_f32_16x16x128_bf8_fp8, "V8fV16iV16iIsV8fIbIb", "nc", "gfx1250-insts,wavefrontsize32") diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index c7a6276..cee5bed 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -895,7 +895,10 @@ public: /// \param FormatString A fixed diagnostic format string that will be hashed /// and mapped to a unique DiagID. template <unsigned N> - // TODO: Deprecate this once all uses are removed from Clang. + // FIXME: this API should almost never be used; custom diagnostics do not + // have an associated diagnostic group and thus cannot be controlled by users + // like other diagnostics. The number of times this API is used in Clang + // should only ever be reduced, not increased. // [[deprecated("Use a CustomDiagDesc instead of a Level")]] unsigned getCustomDiagID(Level L, const char (&FormatString)[N]) { return Diags->getCustomDiagID((DiagnosticIDs::Level)L, diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 34b6c0d..759ba04 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -116,6 +116,8 @@ def err_drv_cuda_host_arch : Error< "unsupported architecture '%0' for host compilation">; def err_drv_mix_cuda_hip : Error< "mixed CUDA and HIP compilation is not supported">; +def err_drv_mix_offload : Error< + "mixed %0 and %1 offloading compilation is not supported">; def err_drv_bad_target_id : Error< "invalid target ID '%0'; format is a processor name followed by an optional " "colon-delimited list of features followed by an enable/disable sign (e.g., " diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 2b095f0..f07a003 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -283,7 +283,10 @@ public: // writing, nearly all callers of this function were invalid. unsigned getCustomDiagID(CustomDiagDesc Diag); - // TODO: Deprecate this once all uses are removed from LLVM + // FIXME: this API should almost never be used; custom diagnostics do not + // have an associated diagnostic group and thus cannot be controlled by users + // like other diagnostics. The number of times this API is used in Clang + // should only ever be reduced, not increased. // [[deprecated("Use a CustomDiagDesc instead of a Level")]] unsigned getCustomDiagID(Level Level, StringRef Message) { return getCustomDiagID([&]() -> CustomDiagDesc { diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 723f5d4..c7fe6e1d 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -694,6 +694,9 @@ def err_pragma_push_pop_macro_malformed : Error< def warn_pragma_pop_macro_no_push : Warning< "pragma pop_macro could not pop '%0', no matching push_macro">, InGroup<IgnoredPragmas>; +def warn_pargma_push_pop_macro_empty_string : Warning< + "'#pragma %select{push_macro|pop_macro}0' expected a non-empty string">, + InGroup<IgnoredPragmas>; def warn_pragma_message : Warning<"%0">, InGroup<PoundPragmaMessage>, DefaultWarnNoWerror; def err_pragma_message : Error<"%0">; diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 6ac8d49..08d98a7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -491,6 +491,8 @@ LANGOPT(CheckConstexprFunctionBodies, 1, 1, Benign, LANGOPT(BoundsSafety, 1, 0, NotCompatible, "Bounds safety extension for C") +LANGOPT(EnableLifetimeSafety, 1, 0, NotCompatible, "Experimental lifetime safety analysis for C++") + LANGOPT(PreserveVec3Type, 1, 0, NotCompatible, "Preserve 3-component vector type") #undef LANGOPT diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 567b8a5..971ce54 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -117,3 +117,4 @@ def PipeType : TypeNode<Type>; def AtomicType : TypeNode<Type>; def BitIntType : TypeNode<Type>; def DependentBitIntType : TypeNode<Type>, AlwaysDependent; +def PredefinedSugarType : TypeNode<Type>, NeverCanonical; diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index d19cd83..694e369 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1739,7 +1739,8 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> { %2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type> %3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type> -> !cir.ptr<!u16i> - %4 = cir.set_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) -> !s32i + %4 = cir.set_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>, %1 : !s32i) + -> !s32i ``` }]; @@ -1747,12 +1748,15 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> { Arg<CIR_PointerType, "the address to store the value", [MemWrite]>:$addr, CIR_AnyType:$src, BitfieldInfoAttr:$bitfield_info, + DefaultValuedOptionalAttr<I64Attr, "0">:$alignment, UnitAttr:$is_volatile ); let results = (outs CIR_IntType:$result); - let assemblyFormat = [{ `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,` + let assemblyFormat = [{ + (`align` `(` $alignment^ `)`)? + `(`$bitfield_info`,` $addr`:`qualified(type($addr))`,` $src`:`type($src) `)` attr-dict `->` type($result) }]; let builders = [ @@ -1764,14 +1768,15 @@ def CIR_SetBitfieldOp : CIR_Op<"set_bitfield"> { "unsigned":$size, "unsigned":$offset, "bool":$is_signed, - "bool":$is_volatile + "bool":$is_volatile, + CArg<"unsigned", "0">:$alignment ), [{ BitfieldInfoAttr info = BitfieldInfoAttr::get($_builder.getContext(), name, storage_type, size, offset, is_signed); - build($_builder, $_state, type, addr, src, info, is_volatile); + build($_builder, $_state, type, addr, src, info, alignment, is_volatile); }]> ]; } @@ -1823,20 +1828,23 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> { %2 = cir.load %0 : !cir.ptr<!cir.ptr<!record_type>>, !cir.ptr<!record_type> %3 = cir.get_member %2[1] {name = "e"} : !cir.ptr<!record_type> -> !cir.ptr<!u16i> - %4 = cir.get_bitfield(#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i + %4 = cir.get_bitfield align(4) (#bfi_e, %3 : !cir.ptr<!u16i>) -> !s32i ``` }]; let arguments = (ins Arg<CIR_PointerType, "the address to load from", [MemRead]>:$addr, BitfieldInfoAttr:$bitfield_info, + DefaultValuedOptionalAttr<I64Attr, "0">:$alignment, UnitAttr:$is_volatile ); let results = (outs CIR_IntType:$result); - let assemblyFormat = [{ `(`$bitfield_info `,` $addr attr-dict `:` - qualified(type($addr)) `)` `->` type($result) }]; + let assemblyFormat = [{ + (`align` `(` $alignment^ `)`)? + `(`$bitfield_info `,` $addr attr-dict `:` + qualified(type($addr)) `)` `->` type($result) }]; let builders = [ OpBuilder<(ins "mlir::Type":$type, @@ -1846,14 +1854,15 @@ def CIR_GetBitfieldOp : CIR_Op<"get_bitfield"> { "unsigned":$size, "unsigned":$offset, "bool":$is_signed, - "bool":$is_volatile + "bool":$is_volatile, + CArg<"unsigned", "0">:$alignment ), [{ BitfieldInfoAttr info = BitfieldInfoAttr::get($_builder.getContext(), name, storage_type, size, offset, is_signed); - build($_builder, $_state, type, addr, info, is_volatile); + build($_builder, $_state, type, addr, info, alignment, is_volatile); }]> ]; } @@ -2995,6 +3004,27 @@ def CIR_AssumeOp : CIR_Op<"assume"> { }]; } +def CIR_AssumeSepStorageOp : CIR_Op<"assume_separate_storage", [ + SameTypeOperands +]> { + let summary = + "Tell the optimizer that two pointers point to different allocations"; + let description = [{ + The `cir.assume_separate_storage` operation takes two pointers as arguments, + and the operation tells the optimizer that these two pointers point to + different allocations. + + This operation corresponds to the `__builtin_assume_separate_storage` + builtin function. + }]; + + let arguments = (ins CIR_VoidPtrType:$ptr1, CIR_VoidPtrType:$ptr2); + + let assemblyFormat = [{ + $ptr1 `,` $ptr2 `:` qualified(type($ptr1)) attr-dict + }]; +} + //===----------------------------------------------------------------------===// // Branch Probability Operations //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 182e4b6..37e0a4c 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -252,7 +252,6 @@ struct MissingFeatures { static bool writebacks() { return false; } static bool appleKext() { return false; } static bool dtorCleanups() { return false; } - static bool completeDtors() { return false; } static bool vtableInitialization() { return false; } static bool msvcBuiltins() { return false; } diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index d9e328f..78a4c57 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -355,6 +355,9 @@ public: phases::ID getFinalPhase(const llvm::opt::DerivedArgList &DAL, llvm::opt::Arg **FinalPhaseArg = nullptr) const; + llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> + executeProgram(llvm::ArrayRef<llvm::StringRef> Args) const; + private: /// Certain options suppress the 'no input files' warning. LLVM_PREFERRED_TYPE(bool) @@ -367,10 +370,6 @@ private: /// stored in it, and will clean them up when torn down. mutable llvm::StringMap<std::unique_ptr<ToolChain>> ToolChains; - /// The associated offloading architectures with each toolchain. - llvm::DenseMap<const ToolChain *, llvm::SmallVector<llvm::StringRef>> - OffloadArchs; - private: /// TranslateInputArgs - Create a new derived argument list from the input /// arguments, after applying the standard argument translations. @@ -537,8 +536,7 @@ public: /// empty string. llvm::SmallVector<StringRef> getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, - Action::OffloadKind Kind, const ToolChain *TC, - bool SpecificToolchain = true) const; + Action::OffloadKind Kind, const ToolChain &TC) const; /// Check that the file referenced by Value exists. If it doesn't, /// issue a diagnostic and return false. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 6c22f06..55e90b7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1156,7 +1156,7 @@ def offload_arch_EQ : CommaJoined<["--"], "offload-arch=">, "If 'native' is used the compiler will detect locally installed architectures. " "For HIP offloading, the device architecture can be followed by target ID features " "delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once.">; -def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, +def no_offload_arch_EQ : CommaJoined<["--"], "no-offload-arch=">, Visibility<[ClangOption, FlangOption]>, HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; @@ -1624,7 +1624,7 @@ defm auto_import : BoolFOption<"auto-import", // In the future this option will be supported by other offloading // languages and accept other values such as CPU/GPU architectures, // offload kinds and target aliases. -def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>, +def offload_EQ : CommaJoined<["--"], "offload=">, Flags<[NoXarchOption]>, Alias<offload_targets_EQ>, HelpText<"Specify comma-separated list of offloading target triples (CUDA and HIP only)">; // C++ Coroutines @@ -1904,6 +1904,14 @@ defm bounds_safety : BoolFOption< BothFlags<[], [CC1Option], " experimental bounds safety extension for C">>; +defm lifetime_safety : BoolFOption< + "experimental-lifetime-safety", + LangOpts<"EnableLifetimeSafety">, DefaultFalse, + PosFlag<SetTrue, [], [CC1Option], "Enable">, + NegFlag<SetFalse, [], [CC1Option], "Disable">, + BothFlags<[], [CC1Option], + " experimental lifetime safety for C++">>; + defm addrsig : BoolFOption<"addrsig", CodeGenOpts<"Addrsig">, DefaultFalse, PosFlag<SetTrue, [], [ClangOption, CC1Option], "Emit">, @@ -3257,13 +3265,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf", "Perform ODR checks for decls in the global module fragment.">>, Group<f_Group>; -def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, - HelpText<"Generate the reduced BMI">, - MarshallingInfoFlag<FrontendOpts<"GenReducedBMI">>; +defm modules_reduced_bmi : BoolOption<"f", "modules-reduced-bmi", + FrontendOpts<"GenReducedBMI">, DefaultFalse, + NegFlag<SetFalse>, + PosFlag<SetTrue, [], [ClangOption, CC1Option], + "Generate the reduced BMI">>; def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">, - Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<modules_reduced_bmi>; + Group<f_Group>, Visibility<[ClangOption, CC1Option]>, Alias<fmodules_reduced_bmi>; def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">, Visibility<[ClangOption, CC1Option, CLOption]>, @@ -7129,6 +7138,8 @@ def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group HelpText<"Specify where to find the compiled intrinsic modules">, DocBrief<[{This option specifies the location of pre-compiled intrinsic modules, if they are not in the default location expected by the compiler.}]>; +def fintrinsic_modules_path_EQ : Joined<["-"], "fintrinsic-modules-path=">, + Group<f_Group>, Alias<fintrinsic_modules_path>; defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">; defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">; diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index b8899e7..d9f7fa2 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -202,10 +202,6 @@ protected: ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args); - /// Executes the given \p Executable and returns the stdout. - llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> - executeToolChainProgram(StringRef Executable) const; - void setTripleEnvironment(llvm::Triple::EnvironmentType Env); virtual Tool *buildAssembler() const; diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 78dff116..83d2962 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -175,31 +175,42 @@ public: llvm::Expected<llvm::orc::ExecutorAddr> getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const; - const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const { - return ValuePrintingInfo; - } - - Expr *SynthesizeExpr(Expr *E); + std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr); + PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU, + std::unique_ptr<llvm::Module> M = {}, + IncrementalAction *Action = nullptr); private: size_t getEffectivePTUSize() const; void markUserCodeStart(); llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E); - llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD); - - CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const; - std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr); - PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU, - std::unique_ptr<llvm::Module> M = {}, - IncrementalAction *Action = nullptr); // A cache for the compiled destructors used to for de-allocation of managed // clang::Values. - llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors; + mutable llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors; - llvm::SmallVector<Expr *, 4> ValuePrintingInfo; + std::array<Expr *, 4> ValuePrintingInfo = {0}; std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder; + + /// @} + /// @name Value and pretty printing support + /// @{ + + std::string ValueDataToString(const Value &V) const; + std::string ValueTypeToString(const Value &V) const; + + llvm::Expected<Expr *> convertExprToValue(Expr *E); + + // When we deallocate clang::Value we need to run the destructor of the type. + // This function forces emission of the needed dtor. + llvm::Expected<llvm::orc::ExecutorAddr> + CompileDtorCall(CXXRecordDecl *CXXRD) const; + + /// @} + /// @name Code generation + /// @{ + CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const; }; } // namespace clang diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h index a93c084..b91301e 100644 --- a/clang/include/clang/Interpreter/Value.h +++ b/clang/include/clang/Interpreter/Value.h @@ -35,6 +35,7 @@ #include "llvm/Config/llvm-config.h" // for LLVM_BUILD_LLVM_DYLIB, LLVM_BUILD_SHARED_LIBS #include "llvm/Support/Compiler.h" +#include <cassert> #include <cstdint> // NOTE: Since the REPL itself could also include this runtime, extreme caution @@ -97,6 +98,7 @@ class REPL_EXTERNAL_VISIBILITY Value { REPL_BUILTIN_TYPES #undef X void *m_Ptr; + unsigned char m_RawBits[sizeof(long double) * 8]; // widest type }; public: @@ -111,7 +113,7 @@ public: }; Value() = default; - Value(Interpreter *In, void *Ty); + Value(const Interpreter *In, void *Ty); Value(const Value &RHS); Value(Value &&RHS) noexcept; Value &operator=(const Value &RHS); @@ -124,9 +126,7 @@ public: void dump() const; void clear(); - ASTContext &getASTContext(); const ASTContext &getASTContext() const; - Interpreter &getInterpreter(); const Interpreter &getInterpreter() const; QualType getType() const; @@ -140,6 +140,7 @@ public: void *getPtr() const; void setPtr(void *Ptr) { Data.m_Ptr = Ptr; } + void setRawBits(void *Ptr, unsigned NBits = sizeof(Storage)); #define X(type, name) \ void set##name(type Val) { Data.m_##name = Val; } \ @@ -193,7 +194,7 @@ protected: } }; - Interpreter *Interp = nullptr; + const Interpreter *Interp = nullptr; void *OpaqueType = nullptr; Storage Data; Kind ValueKind = K_Unspecified; @@ -205,6 +206,5 @@ template <> inline void *Value::as() const { return Data.m_Ptr; return (void *)as<uintptr_t>(); } - } // namespace clang #endif diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index a70335b..d34a414 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -1491,8 +1491,6 @@ class Sema; OverloadingResult BestViableFunctionImpl(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best); - void PerfectViableFunction(Sema &S, SourceLocation Loc, - OverloadCandidateSet::iterator &Best); }; bool isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b331acb..73eb730 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -834,6 +834,13 @@ enum class CCEKind { ///< message. }; +/// Enums for the diagnostics of target, target_version and target_clones. +namespace DiagAttrParams { +enum DiagType { Unsupported, Duplicate, Unknown }; +enum Specifier { None, CPU, Tune }; +enum AttrName { Target, TargetClones, TargetVersion }; +} // end namespace DiagAttrParams + void inferNoReturnAttr(Sema &S, const Decl *D); /// Sema - This implements semantic analysis and AST building for C. @@ -4922,13 +4929,6 @@ public: // handled later in the process, once we know how many exist. bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); - /// Check Target Version attrs - bool checkTargetVersionAttr(SourceLocation Loc, Decl *D, StringRef Str); - bool checkTargetClonesAttrString( - SourceLocation LiteralLoc, StringRef Str, const StringLiteral *Literal, - Decl *D, bool &HasDefault, bool &HasCommas, bool &HasNotDefault, - SmallVectorImpl<SmallString<64>> &StringsBuffer); - ErrorAttr *mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI, StringRef NewUserDiagnostic); FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, diff --git a/clang/include/clang/Sema/SemaARM.h b/clang/include/clang/Sema/SemaARM.h index 788a7ab..e77d65f 100644 --- a/clang/include/clang/Sema/SemaARM.h +++ b/clang/include/clang/Sema/SemaARM.h @@ -91,6 +91,11 @@ public: /// Return true if the given vector types are lax-compatible SVE vector types, /// false otherwise. bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType); + + bool checkTargetVersionAttr(const StringRef Str, const SourceLocation Loc); + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index 8d2e1c6..844cc3c 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -55,6 +55,11 @@ public: bool DeclareAndesVectorBuiltins = false; std::unique_ptr<sema::RISCVIntrinsicManager> IntrinsicManager; + + bool checkTargetVersionAttr(const StringRef Param, const SourceLocation Loc); + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; std::unique_ptr<sema::RISCVIntrinsicManager> diff --git a/clang/include/clang/Sema/SemaX86.h b/clang/include/clang/Sema/SemaX86.h index b5a23f1..20783e3 100644 --- a/clang/include/clang/Sema/SemaX86.h +++ b/clang/include/clang/Sema/SemaX86.h @@ -37,6 +37,10 @@ public: void handleAnyInterruptAttr(Decl *D, const ParsedAttr &AL); void handleForceAlignArgPointerAttr(Decl *D, const ParsedAttr &AL); + + bool checkTargetClonesAttr(SmallVectorImpl<StringRef> &Params, + SmallVectorImpl<SourceLocation> &Locs, + SmallVectorImpl<SmallString<64>> &NewParams); }; } // namespace clang diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def index b8cde2e..613eb6a 100644 --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -69,5 +69,6 @@ TYPE_BIT_CODE(CountAttributed, COUNT_ATTRIBUTED, 57) TYPE_BIT_CODE(ArrayParameter, ARRAY_PARAMETER, 58) TYPE_BIT_CODE(HLSLAttributedResource, HLSLRESOURCE_ATTRIBUTED, 59) TYPE_BIT_CODE(HLSLInlineSpirv, HLSL_INLINE_SPIRV, 60) +TYPE_BIT_CODE(PredefinedSugar, PREDEFINED_SUGAR, 61) #undef TYPE_BIT_CODE diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index 43dbfb1..da3efd7 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -38,29 +38,29 @@ // function clang_registerCheckers. For example: // // extern "C" -// void clang_registerCheckers (CheckerRegistry ®istry) { -// registry.addChecker<MainCallChecker>("example.MainCallChecker", -// "Disallows calls to functions called main"); +// void clang_registerCheckers(CheckerRegistry &Registry) { +// Registry.addChecker<MainCallChecker>( +// "example.MainCallChecker", +// "Disallows calls to functions called main"); // } // -// The first method argument is the full name of the checker, including its -// enclosing package. By convention, the registered name of a checker is the -// name of the associated class (the template argument). -// The second method argument is a short human-readable description of the -// checker. +// The first argument of this templated method is the full name of the checker +// (including its package), while the second argument is a short description +// that is printed by `-analyzer-checker-help`. // -// The clang_registerCheckers function may add any number of checkers to the -// registry. If any checkers require additional initialization, use the three- -// argument form of CheckerRegistry::addChecker. +// A plugin may register several separate checkers by calling `addChecker()` +// multiple times. If a checker requires custom registration functions (e.g. +// checker option handling) use the non-templated overload of `addChecker` that +// takes two callback functions as the first two parameters. // // To load a checker plugin, specify the full path to the dynamic library as // the argument to the -load option in the cc1 frontend. You can then enable // your custom checker using the -analyzer-checker: // -// clang -cc1 -load </path/to/plugin.dylib> -analyze -// -analyzer-checker=<example.MainCallChecker> +// clang -cc1 -load /path/to/plugin.dylib -analyze +// -analyzer-checker=example.MainCallChecker // -// For a complete working example, see examples/analyzer-plugin. +// For complete examples, see clang/lib/Analysis/plugins/SampleAnalyzer #ifndef CLANG_ANALYZER_API_VERSION_STRING // FIXME: The Clang version string is not particularly granular; @@ -108,30 +108,25 @@ private: mgr.template registerChecker<T>(); } - template <typename T> static bool returnTrue(const CheckerManager &mgr) { - return true; - } + static bool returnTrue(const CheckerManager &) { return true; } public: - /// Adds a checker to the registry. Use this non-templated overload when your - /// checker requires custom initialization. - void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, - StringRef FullName, StringRef Desc, StringRef DocsUri, - bool IsHidden); - - /// Adds a checker to the registry. Use this templated overload when your - /// checker does not require any custom initialization. - /// This function isn't really needed and probably causes more headaches than - /// the tiny convenience that it provides, but external plugins might use it, - /// and there isn't a strong incentive to remove it. + /// Adds a checker to the registry. + /// Use this for a checker defined in a plugin if it requires custom + /// registration functions (e.g. for handling checker options). + /// NOTE: As of now `DocsUri` is never queried from the checker registry. + void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction Sfn, + StringRef FullName, StringRef Desc, + StringRef DocsUri = "NoDocsUri", bool IsHidden = false); + + /// Adds a checker to the registry. + /// Use this for a checker defined in a plugin if it doesn't require custom + /// registration functions. template <class T> - void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, - bool IsHidden = false) { - // Avoid MSVC's Compiler Error C2276: - // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx + void addChecker(StringRef FullName, StringRef Desc, + StringRef DocsUri = "NoDocsUri", bool IsHidden = false) { addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>, - &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri, - IsHidden); + &CheckerRegistry::returnTrue, FullName, Desc, DocsUri, IsHidden); } /// Makes the checker with the full name \p fullName depend on the checker diff --git a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h index fba90d8..bf06061 100644 --- a/clang/include/clang/Tooling/Inclusions/IncludeStyle.h +++ b/clang/include/clang/Tooling/Inclusions/IncludeStyle.h @@ -126,8 +126,8 @@ struct IncludeStyle { /// * ``""`` means "arbitrary suffix" /// * ``"$"`` means "no suffix" /// - /// For example, if configured to ``"(_test)?$"``, then a header a.h would be seen - /// as the "main" include in both a.cc and a_test.cc. + /// For example, if configured to ``"(_test)?$"``, then a header a.h would be + /// seen as the "main" include in both a.cc and a_test.cc. /// \version 3.9 std::string IncludeIsMainRegex; |