108 changes: 84 additions & 24 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1690,7 +1690,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {

/// Whether we have a stored size expression.
LLVM_PREFERRED_TYPE(bool)
unsigned HasStoredSizeExpr : 1;
unsigned HasExternalSize : 1;

LLVM_PREFERRED_TYPE(unsigned)
unsigned SizeWidth : 5;
};

class BuiltinTypeBitfields {
Expand Down Expand Up @@ -3338,35 +3341,93 @@ class ArrayType : public Type, public llvm::FoldingSetNode {
/// Represents the canonical version of C arrays with a specified constant size.
/// For example, the canonical type for 'int A[4 + 4*100]' is a
/// ConstantArrayType where the element type is 'int' and the size is 404.
class ConstantArrayType final
: public ArrayType,
private llvm::TrailingObjects<ConstantArrayType, const Expr *> {
class ConstantArrayType final : public ArrayType {
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;

llvm::APInt Size; // Allows us to unique the type.
struct ExternalSize {
ExternalSize(const llvm::APInt &Sz, const Expr *SE)
: Size(Sz), SizeExpr(SE) {}
llvm::APInt Size; // Allows us to unique the type.
const Expr *SizeExpr;
};

ConstantArrayType(QualType et, QualType can, const llvm::APInt &size,
const Expr *sz, ArraySizeModifier sm, unsigned tq)
: ArrayType(ConstantArray, et, can, sm, tq, sz), Size(size) {
ConstantArrayTypeBits.HasStoredSizeExpr = sz != nullptr;
if (ConstantArrayTypeBits.HasStoredSizeExpr) {
assert(!can.isNull() && "canonical constant array should not have size");
*getTrailingObjects<const Expr*>() = sz;
}
union {
uint64_t Size;
ExternalSize *SizePtr;
};

ConstantArrayType(QualType Et, QualType Can, uint64_t Width, uint64_t Sz,
ArraySizeModifier SM, unsigned TQ)
: ArrayType(ConstantArray, Et, Can, SM, TQ, nullptr), Size(Sz) {
ConstantArrayTypeBits.HasExternalSize = false;
ConstantArrayTypeBits.SizeWidth = Width / 8;
// The in-structure size stores the size in bytes rather than bits so we
// drop the three least significant bits since they're always zero anyways.
assert(Width < 0xFF && "Type width in bits must be less than 8 bits");
}

unsigned numTrailingObjects(OverloadToken<const Expr*>) const {
return ConstantArrayTypeBits.HasStoredSizeExpr;
ConstantArrayType(QualType Et, QualType Can, ExternalSize *SzPtr,
ArraySizeModifier SM, unsigned TQ)
: ArrayType(ConstantArray, Et, Can, SM, TQ, SzPtr->SizeExpr),
SizePtr(SzPtr) {
ConstantArrayTypeBits.HasExternalSize = true;
ConstantArrayTypeBits.SizeWidth = 0;

assert((SzPtr->SizeExpr == nullptr || !Can.isNull()) &&
"canonical constant array should not have size expression");
}

static ConstantArrayType *Create(const ASTContext &Ctx, QualType ET,
QualType Can, const llvm::APInt &Sz,
const Expr *SzExpr, ArraySizeModifier SzMod,
unsigned Qual);

public:
const llvm::APInt &getSize() const { return Size; }
/// Return the constant array size as an APInt.
llvm::APInt getSize() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size
: llvm::APInt(ConstantArrayTypeBits.SizeWidth * 8, Size);
}

/// Return the bit width of the size type.
unsigned getSizeBitWidth() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size.getBitWidth()
: static_cast<unsigned>(ConstantArrayTypeBits.SizeWidth * 8);
}

/// Return true if the size is zero.
bool isZeroSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.isZero()
: 0 == Size;
}

/// Return the size zero-extended as a uint64_t.
uint64_t getZExtSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getZExtValue()
: Size;
}

/// Return the size sign-extended as a uint64_t.
int64_t getSExtSize() const {
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->Size.getSExtValue()
: static_cast<int64_t>(Size);
}

/// Return the size zero-extended to uint64_t or UINT64_MAX if the value is
/// larger than UINT64_MAX.
uint64_t getLimitedSize() const {
return ConstantArrayTypeBits.HasExternalSize
? SizePtr->Size.getLimitedValue()
: Size;
}

/// Return a pointer to the size expression.
const Expr *getSizeExpr() const {
return ConstantArrayTypeBits.HasStoredSizeExpr
? *getTrailingObjects<const Expr *>()
: nullptr;
return ConstantArrayTypeBits.HasExternalSize ? SizePtr->SizeExpr : nullptr;
}

bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }

Expand All @@ -3383,14 +3444,13 @@ class ConstantArrayType final
static unsigned getMaxSizeBits(const ASTContext &Context);

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) {
Profile(ID, Ctx, getElementType(), getSize(), getSizeExpr(),
Profile(ID, Ctx, getElementType(), getZExtSize(), getSizeExpr(),
getSizeModifier(), getIndexTypeCVRQualifiers());
}

static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx,
QualType ET, const llvm::APInt &ArraySize,
const Expr *SizeExpr, ArraySizeModifier SizeMod,
unsigned TypeQuals);
QualType ET, uint64_t ArraySize, const Expr *SizeExpr,
ArraySizeModifier SizeMod, unsigned TypeQuals);

static bool classof(const Type *T) {
return T->getTypeClass() == ConstantArray;
Expand Down
8 changes: 7 additions & 1 deletion clang/include/clang/Analysis/PathDiagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,9 @@ class PathDiagnostic : public llvm::FoldingSetNode {
PathDiagnosticLocation UniqueingLoc;
const Decl *UniqueingDecl;

/// The top-level entry point from which this issue was discovered.
const Decl *AnalysisEntryPoint = nullptr;

/// Lines executed in the path.
std::unique_ptr<FilesToLineNumsMap> ExecutedLines;

Expand All @@ -788,7 +791,7 @@ class PathDiagnostic : public llvm::FoldingSetNode {
PathDiagnostic(StringRef CheckerName, const Decl *DeclWithIssue,
StringRef bugtype, StringRef verboseDesc, StringRef shortDesc,
StringRef category, PathDiagnosticLocation LocationToUnique,
const Decl *DeclToUnique,
const Decl *DeclToUnique, const Decl *AnalysisEntryPoint,
std::unique_ptr<FilesToLineNumsMap> ExecutedLines);
~PathDiagnostic();

Expand Down Expand Up @@ -852,6 +855,9 @@ class PathDiagnostic : public llvm::FoldingSetNode {
return *ExecutedLines;
}

/// Get the top-level entry point from which this issue was discovered.
const Decl *getAnalysisEntryPoint() const { return AnalysisEntryPoint; }

/// Return the semantic context where an issue occurred. If the
/// issue occurs along a path, this represents the "central" area
/// where the bug manifests.
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -3011,6 +3011,13 @@ def PreserveNone : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86> {
let Documentation = [PreserveNoneDocs];
}

def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
let Spellings = [CXX11<"riscv", "vector_cc">,
C23<"riscv", "vector_cc">,
Clang<"riscv_vector_cc">];
let Documentation = [RISCVVectorCCDocs];
}

def Target : InheritableAttr {
let Spellings = [GCC<"target">];
let Args = [StringArgument<"featuresStr">];
Expand Down Expand Up @@ -3088,6 +3095,20 @@ def TargetClones : InheritableAttr {
StringRef getFeatureStr(unsigned Index) const {
return *(featuresStrs_begin() + Index);
}
bool isDefaultVersion(unsigned Index) const {
return getFeatureStr(Index) == "default";
}
void getFeatures(llvm::SmallVectorImpl<StringRef> &Out,
unsigned Index) const {
if (isDefaultVersion(Index)) return;
StringRef Features = getFeatureStr(Index);
SmallVector<StringRef, 8> AttrFeatures;
Features.split(AttrFeatures, "+");
for (auto &Feature : AttrFeatures) {
Feature = Feature.trim();
Out.push_back(Feature);
}
}
// Given an index into the 'featuresStrs' sequence, compute a unique
// ID to be used with function name mangling for the associated variant.
// This mapping is necessary due to a requirement that the mangling ID
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -5494,6 +5494,17 @@ for clang builtin functions.
}];
}

def RISCVVectorCCDocs : Documentation {
let Category = DocCatCallingConvs;
let Heading = "riscv::vector_cc, riscv_vector_cc, clang::riscv_vector_cc";
let Content = [{
The ``riscv_vector_cc`` attribute can be applied to a function. It preserves 15
registers namely, v1-v7 and v24-v31 as callee-saved. Callers thus don't need
to save these registers before function calls, and callees only need to save
them if they use them.
}];
}

def PreferredNameDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
Expand Down Expand Up @@ -6069,6 +6080,9 @@ def AlwaysDestroyDocs : Documentation {
The ``always_destroy`` attribute specifies that a variable with static or thread
storage duration should have its exit-time destructor run. This attribute is the
default unless clang was invoked with -fno-c++-static-destructors.

If a variable is explicitly declared with this attribute, Clang will silence
otherwise applicable ``-Wexit-time-destructors`` warnings.
}];
}

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ def Clz : Builtin, BitShort_Int_Long_LongLongTemplate {

def Clzg : Builtin {
let Spellings = ["__builtin_clzg"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
let Prototype = "int(...)";
}

Expand All @@ -690,7 +690,7 @@ def Ctz : Builtin, BitShort_Int_Long_LongLongTemplate {

def Ctzg : Builtin {
let Spellings = ["__builtin_ctzg"];
let Attributes = [NoThrow, Const, CustomTypeChecking];
let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
let Prototype = "int(...)";
}

Expand Down
11 changes: 4 additions & 7 deletions clang/include/clang/Basic/BuiltinsAMDGPU.def
Original file line number Diff line number Diff line change
Expand Up @@ -432,13 +432,10 @@ TARGET_BUILTIN(__builtin_amdgcn_s_wakeup_barrier, "vi", "n", "gfx12-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_barrier_leave, "b", "n", "gfx12-insts")
TARGET_BUILTIN(__builtin_amdgcn_s_get_barrier_state, "Uii", "n", "gfx12-insts")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v8f16, "V8hV8h*1", "nc", "gfx12-insts,wavefrontsize32")

TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_v4f16, "V4hV4h*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_v2i32, "V2iV2i*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v8i16, "V8sV8s*1", "nc", "gfx12-insts,wavefrontsize32")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b64_i32, "ii*1", "nc", "gfx12-insts,wavefrontsize64")
TARGET_BUILTIN(__builtin_amdgcn_global_load_tr_b128_v4i16, "V4sV4s*1", "nc", "gfx12-insts,wavefrontsize64")

//===----------------------------------------------------------------------===//
// WMMA builtins.
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ let CategoryName = "Command line" in {
def err_cannot_write_file : Error<"cannot write file '%0': %1">;
def err_no_install_name : Error<"no install name specified: add -install_name <path>">;
def err_no_output_file: Error<"no output file specified">;
def err_no_such_header_file : Error<"no such %select{public|private|project}1 header file: '%0'">;
def warn_no_such_excluded_header_file : Warning<"no such excluded %select{public|private}0 header file: '%1'">, InGroup<InstallAPIViolation>;
def warn_glob_did_not_match: Warning<"glob '%0' did not match any header file">, InGroup<InstallAPIViolation>;
def err_no_such_umbrella_header_file : Error<"%select{public|private|project}1 umbrella header file not found in input: '%0'">;
} // end of command line category.

let CategoryName = "Verification" in {
Expand All @@ -26,6 +30,7 @@ def warn_library_hidden_symbol : Warning<"declaration has external linkage, but
def warn_header_hidden_symbol : Warning<"symbol exported in dynamic library, but marked hidden in declaration '%0'">, InGroup<InstallAPIViolation>;
def err_header_hidden_symbol : Error<"symbol exported in dynamic library, but marked hidden in declaration '%0'">;
def err_header_symbol_missing : Error<"no declaration found for exported symbol '%0' in dynamic library">;
def warn_header_symbol_missing : Warning<"no declaration was found for exported symbol '%0' in dynamic library">, InGroup<InstallAPIViolation>;
def warn_header_availability_mismatch : Warning<"declaration '%0' is marked %select{available|unavailable}1,"
" but symbol is %select{not |}2exported in dynamic library">, InGroup<InstallAPIViolation>;
def err_header_availability_mismatch : Error<"declaration '%0' is marked %select{available|unavailable}1,"
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def err_expected_semi_after_namespace_name : Error<
"expected ';' after namespace name">;
def err_unexpected_namespace_attributes_alias : Error<
"attributes cannot be specified on namespace alias">;
def err_unexpected_qualified_namespace_alias : Error<
"namespace alias must be a single identifier">;
def err_unexpected_nested_namespace_attribute : Error<
"attributes cannot be specified on a nested namespace definition">;
def err_inline_namespace_alias : Error<"namespace alias cannot be inline">;
Expand Down
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -6464,9 +6464,6 @@ def ext_c99_flexible_array_member : Extension<
def err_flexible_array_virtual_base : Error<
"flexible array member %0 not allowed in "
"%select{struct|interface|union|class|enum}1 which has a virtual base class">;
def err_flexible_array_empty_aggregate : Error<
"flexible array member %0 not allowed in otherwise empty "
"%select{struct|interface|union|class|enum}1">;
def err_flexible_array_has_nontrivial_dtor : Error<
"flexible array member %0 of type %1 with non-trivial destruction">;
def ext_flexible_array_in_struct : Extension<
Expand All @@ -6481,8 +6478,6 @@ def ext_flexible_array_empty_aggregate_ms : Extension<
"flexible array member %0 in otherwise empty "
"%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
InGroup<MicrosoftFlexibleArray>;
def err_flexible_array_union : Error<
"flexible array member %0 in a union is not allowed">;
def ext_flexible_array_union_ms : Extension<
"flexible array member %0 in a union is a Microsoft extension">,
InGroup<MicrosoftFlexibleArray>;
Expand Down
5 changes: 3 additions & 2 deletions clang/include/clang/Basic/LangStandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ enum class Language : uint8_t {
/// Assembly: we accept this only so that we can preprocess it.
Asm,

/// LLVM IR: we accept this so that we can run the optimizer on it,
/// and compile it to assembly or object code.
/// LLVM IR & CIR: we accept these so that we can run the optimizer on them,
/// and compile them to assembly or object code (or LLVM for CIR).
CIR,
LLVM_IR,

///@{ Languages that the frontend can parse and compile.
Expand Down
43 changes: 22 additions & 21 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,29 +273,30 @@ namespace clang {

/// CallingConv - Specifies the calling convention that a function uses.
enum CallingConv {
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
CC_Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
CC_SpirFunction, // default for OpenCL functions on SPIR target
CC_OpenCLKernel, // inferred for OpenCL kernels
CC_Swift, // __attribute__((swiftcall))
CC_C, // __attribute__((cdecl))
CC_X86StdCall, // __attribute__((stdcall))
CC_X86FastCall, // __attribute__((fastcall))
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
CC_Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
CC_SpirFunction, // default for OpenCL functions on SPIR target
CC_OpenCLKernel, // inferred for OpenCL kernels
CC_Swift, // __attribute__((swiftcall))
CC_SwiftAsync, // __attribute__((swiftasynccall))
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_PreserveMost, // __attribute__((preserve_most))
CC_PreserveAll, // __attribute__((preserve_all))
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
CC_M68kRTD, // __attribute__((m68k_rtd))
CC_PreserveNone, // __attribute__((preserve_none))
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
CC_M68kRTD, // __attribute__((m68k_rtd))
CC_PreserveNone, // __attribute__((preserve_none))
CC_RISCVVectorCall, // __attribute__((riscv_vector_cc))
};

/// Checks whether the given calling convention supports variadic
Expand Down
3 changes: 1 addition & 2 deletions clang/include/clang/Basic/SyncScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ class AtomicScopeGenericModel : public AtomicScopeModel {
}

bool isValid(unsigned S) const override {
return S >= static_cast<unsigned>(System) &&
S <= static_cast<unsigned>(Last);
return S <= static_cast<unsigned>(Last);
}

ArrayRef<unsigned> getRuntimeValues() const override {
Expand Down
11 changes: 5 additions & 6 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4105,12 +4105,8 @@ defm strict_return : BoolFOption<"strict-return",
" of a non-void function as unreachable">,
PosFlag<SetTrue>>;

let Group = f_Group in {
let Visibility = [ClangOption,CC1Option] in {
def fptrauth_intrinsics : Flag<["-"], "fptrauth-intrinsics">,
HelpText<"Enable pointer authentication intrinsics">;
}
def fno_ptrauth_intrinsics : Flag<["-"], "fno-ptrauth-intrinsics">;
let Flags = [TargetSpecific] in {
defm ptrauth_intrinsics : OptInCC1FFlag<"ptrauth-intrinsics", "Enable pointer authentication intrinsics">;
}

def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>,
Expand Down Expand Up @@ -6688,6 +6684,9 @@ def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">,
def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
HelpText<"Emit verbose output about the analyzer's progress">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerDisplayProgress">>;
def analyzer_note_analysis_entry_points : Flag<["-"], "analyzer-note-analysis-entry-points">,
HelpText<"Add a note for each bug report to denote their analysis entry points">,
MarshallingInfoFlag<AnalyzerOpts<"AnalyzerNoteAnalysisEntryPoints">>;
def analyze_function : Separate<["-"], "analyze-function">,
HelpText<"Run analysis on specific function (for C++ include parameters in name)">,
MarshallingInfoString<AnalyzerOpts<"AnalyzeSpecificFunction">>;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Types.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ TYPE("ir", LLVM_BC, INVALID, "bc", phases
TYPE("lto-ir", LTO_IR, INVALID, "s", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("lto-bc", LTO_BC, INVALID, "o", phases::Compile, phases::Backend, phases::Assemble, phases::Link)

TYPE("cir", CIR, INVALID, "cir", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
// Misc.
TYPE("ast", AST, INVALID, "ast", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("ifs", IFS, INVALID, "ifs", phases::IfsMerge)
Expand Down
17 changes: 17 additions & 0 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,21 @@ struct FormatStyle {
/// \version 17
ShortCaseStatementsAlignmentStyle AlignConsecutiveShortCaseStatements;

/// Style of aligning consecutive TableGen DAGArg operator colons.
/// If enabled, align the colon inside DAGArg which have line break inside.
/// This works only when TableGenBreakInsideDAGArg is BreakElements or
/// BreakAll and the DAGArg is not excepted by
/// TableGenBreakingDAGArgOperators's effect.
/// \code
/// let dagarg = (ins
/// a :$src1,
/// aa :$src2,
/// aaa:$src3
/// )
/// \endcode
/// \version 19
AlignConsecutiveStyle AlignConsecutiveTableGenBreakingDAGArgColons;

/// Style of aligning consecutive TableGen cond operator colons.
/// Align the colons of cases inside !cond operators.
/// \code
Expand Down Expand Up @@ -4879,6 +4894,8 @@ struct FormatStyle {
AlignConsecutiveMacros == R.AlignConsecutiveMacros &&
AlignConsecutiveShortCaseStatements ==
R.AlignConsecutiveShortCaseStatements &&
AlignConsecutiveTableGenBreakingDAGArgColons ==
R.AlignConsecutiveTableGenBreakingDAGArgColons &&
AlignConsecutiveTableGenCondOperatorColons ==
R.AlignConsecutiveTableGenCondOperatorColons &&
AlignConsecutiveTableGenDefinitionColons ==
Expand Down
13 changes: 12 additions & 1 deletion clang/include/clang/InstallAPI/DylibVerifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ enum class VerificationMode {
/// lifetime of InstallAPI.
/// As declarations are collected during AST traversal, they are
/// compared as symbols against what is available in the binary dylib.
class DylibVerifier {
class DylibVerifier : llvm::MachO::RecordVisitor {
private:
struct SymbolContext;

Expand Down Expand Up @@ -72,6 +72,9 @@ class DylibVerifier {
Result verify(ObjCIVarRecord *R, const FrontendAttrs *FA,
const StringRef SuperClass);

// Scan through dylib slices and report any remaining missing exports.
Result verifyRemainingSymbols();

/// Initialize target for verification.
void setTarget(const Target &T);

Expand Down Expand Up @@ -128,6 +131,14 @@ class DylibVerifier {
/// Find matching dylib slice for target triple that is being parsed.
void assignSlice(const Target &T);

/// Shared implementation for verifying exported symbols in dylib.
void visitSymbolInDylib(const Record &R, SymbolContext &SymCtx);

void visitGlobal(const GlobalRecord &R) override;
void visitObjCInterface(const ObjCInterfaceRecord &R) override;
void visitObjCCategory(const ObjCCategoryRecord &R) override;
void visitObjCIVar(const ObjCIVarRecord &R, const StringRef Super);

/// Gather annotations for symbol for error reporting.
std::string getAnnotatedName(const Record *R, SymbolContext &SymCtx,
bool ValidSourceLoc = true);
Expand Down
66 changes: 61 additions & 5 deletions clang/include/clang/InstallAPI/HeaderFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
#ifndef LLVM_CLANG_INSTALLAPI_HEADERFILE_H
#define LLVM_CLANG_INSTALLAPI_HEADERFILE_H

#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangStandard.h"
#include "clang/InstallAPI/MachO.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
Expand All @@ -22,15 +24,15 @@

namespace clang::installapi {
enum class HeaderType {
/// Unset or unknown type.
Unknown,
/// Represents declarations accessible to all clients.
Public,
/// Represents declarations accessible to a disclosed set of clients.
Private,
/// Represents declarations only accessible as implementation details to the
/// input library.
Project,
/// Unset or unknown type.
Unknown,
};

inline StringRef getName(const HeaderType T) {
Expand All @@ -56,6 +58,12 @@ class HeaderFile {
std::string IncludeName;
/// Supported language mode for header.
std::optional<clang::Language> Language;
/// Exclude header file from processing.
bool Excluded{false};
/// Add header file to processing.
bool Extra{false};
/// Specify that header file is the umbrella header for library.
bool Umbrella{false};

public:
HeaderFile() = delete;
Expand All @@ -71,17 +79,52 @@ class HeaderFile {
StringRef getIncludeName() const { return IncludeName; }
StringRef getPath() const { return FullPath; }

void setExtra(bool V = true) { Extra = V; }
void setExcluded(bool V = true) { Excluded = V; }
void setUmbrellaHeader(bool V = true) { Umbrella = V; }
bool isExtra() const { return Extra; }
bool isExcluded() const { return Excluded; }
bool isUmbrellaHeader() const { return Umbrella; }

bool useIncludeName() const {
return Type != HeaderType::Project && !IncludeName.empty();
}

bool operator==(const HeaderFile &Other) const {
return std::tie(Type, FullPath, IncludeName, Language) ==
std::tie(Other.Type, Other.FullPath, Other.IncludeName,
Other.Language);
return std::tie(Type, FullPath, IncludeName, Language, Excluded, Extra,
Umbrella) == std::tie(Other.Type, Other.FullPath,
Other.IncludeName, Other.Language,
Other.Excluded, Other.Extra,
Other.Umbrella);
}
};

/// Glob that represents a pattern of header files to retreive.
class HeaderGlob {
private:
std::string GlobString;
llvm::Regex Rule;
HeaderType Type;
bool FoundMatch{false};

public:
HeaderGlob(StringRef GlobString, llvm::Regex &&, HeaderType Type);

/// Create a header glob from string for the header access level.
static llvm::Expected<std::unique_ptr<HeaderGlob>>
create(StringRef GlobString, HeaderType Type);

/// Query if provided header matches glob.
bool match(const HeaderFile &Header);

/// Query if a header was matched in the glob, used primarily for error
/// reporting.
bool didMatch() { return FoundMatch; }

/// Provide back input glob string.
StringRef str() { return GlobString; }
};

/// Assemble expected way header will be included by clients.
/// As in what maps inside the brackets of `#include <IncludeName.h>`
/// For example,
Expand All @@ -93,6 +136,19 @@ class HeaderFile {
std::optional<std::string> createIncludeHeaderName(const StringRef FullPath);
using HeaderSeq = std::vector<HeaderFile>;

/// Determine if Path is a header file.
/// It does not touch the file system.
///
/// \param Path File path to file.
bool isHeaderFile(StringRef Path);

/// Given input directory, collect all header files.
///
/// \param FM FileManager for finding input files.
/// \param Directory Path to directory file.
llvm::Expected<PathSeq> enumerateFiles(clang::FileManager &FM,
StringRef Directory);

} // namespace clang::installapi

#endif // LLVM_CLANG_INSTALLAPI_HEADERFILE_H
1 change: 1 addition & 0 deletions clang/include/clang/InstallAPI/MachO.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ using SymbolSet = llvm::MachO::SymbolSet;
using SimpleSymbol = llvm::MachO::SimpleSymbol;
using FileType = llvm::MachO::FileType;
using PackedVersion = llvm::MachO::PackedVersion;
using PathSeq = llvm::MachO::PathSeq;
using Target = llvm::MachO::Target;
using TargetList = llvm::MachO::TargetList;

Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
namespace llvm {
namespace orc {
class LLJIT;
class LLJITBuilder;
class ThreadSafeContext;
} // namespace orc
} // namespace llvm
Expand Down Expand Up @@ -127,6 +128,13 @@ class Interpreter {
// custom runtime.
virtual std::unique_ptr<RuntimeInterfaceBuilder> FindRuntimeInterface();

// Lazily construct thev ORCv2 JITBuilder. This called when the internal
// IncrementalExecutor is created. The default implementation populates an
// in-process JIT with debugging support. Override this to configure the JIT
// engine used for execution.
virtual llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
CreateJITBuilder(CompilerInstance &CI);

public:
virtual ~Interpreter();

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Interpreter/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class QualType;
X(bool, Bool) \
X(char, Char_S) \
X(signed char, SChar) \
X(unsigned char, Char_U) \
X(unsigned char, UChar) \
X(short, Short) \
X(unsigned short, UShort) \
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2234,7 +2234,8 @@ class Sema final {
bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
CallExpr *TheCall);
void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D);
void checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
const llvm::StringMap<bool> &FeatureMap);
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID, CallExpr *TheCall);
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
Expand Down
12 changes: 6 additions & 6 deletions clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,11 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">,

let ParentPackage = Cplusplus in {

def ArrayDeleteChecker : Checker<"ArrayDelete">,
HelpText<"Reports destructions of arrays of polymorphic objects that are "
"destructed as their base class.">,
Documentation<HasDocumentation>;

def InnerPointerChecker : Checker<"InnerPointer">,
HelpText<"Check for inner pointers of C++ containers used after "
"re/deallocation">,
Expand Down Expand Up @@ -777,11 +782,6 @@ def ContainerModeling : Checker<"ContainerModeling">,
Documentation<NotDocumented>,
Hidden;

def CXXArrayDeleteChecker : Checker<"ArrayDelete">,
HelpText<"Reports destructions of arrays of polymorphic objects that are "
"destructed as their base class.">,
Documentation<HasDocumentation>;

def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
HelpText<"Reports destructions of polymorphic objects with a non-virtual "
"destructor in their base class">,
Expand Down Expand Up @@ -908,7 +908,7 @@ def PaddingChecker : Checker<"Padding">,
"24",
Released>
]>,
Documentation<NotDocumented>;
Documentation<HasDocumentation>;

} // end: "padding"

Expand Down
9 changes: 5 additions & 4 deletions clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzerNoteAnalysisEntryPoints : 1;

unsigned eagerlyAssumeBinOpBifurcation : 1;

Expand Down Expand Up @@ -291,10 +292,10 @@ class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
ShowConfigOptionsList(false),
ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
AnalyzerDisplayProgress(false), eagerlyAssumeBinOpBifurcation(false),
TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
AnalyzerWerror(false) {}
AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {}

/// Interprets an option's string value as a boolean. The "true" string is
/// interpreted as true and the "false" string is interpreted as false.
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,9 @@ class BugReporter {
private:
BugReporterData& D;

/// The top-level entry point for the issue to be reported.
const Decl *AnalysisEntryPoint = nullptr;

/// Generate and flush the diagnostics for the given bug report.
void FlushReport(BugReportEquivClass& EQ);

Expand Down Expand Up @@ -623,6 +626,14 @@ class BugReporter {

Preprocessor &getPreprocessor() { return D.getPreprocessor(); }

/// Get the top-level entry point for the issue to be reported.
const Decl *getAnalysisEntryPoint() const { return AnalysisEntryPoint; }

void setAnalysisEntryPoint(const Decl *EntryPoint) {
assert(EntryPoint);
AnalysisEntryPoint = EntryPoint;
}

/// Add the given report to the set of reports tracked by BugReporter.
///
/// The reports are usually generated by the checkers. Further, they are
Expand Down Expand Up @@ -713,6 +724,7 @@ class BugReporterContext {
virtual ~BugReporterContext() = default;

PathSensitiveBugReporter& getBugReporter() { return BR; }
const PathSensitiveBugReporter &getBugReporter() const { return BR; }

ProgramStateManager& getStateManager() const {
return BR.getStateManager();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ class CallDescription {
/// - We also accept calls where the number of arguments or parameters is
/// greater than the specified value.
/// For the exact heuristics, see CheckerContext::isCLibraryFunction().
/// Note that functions whose declaration context is not a TU (e.g.
/// methods, functions in namespaces) are not accepted as C library
/// functions.
/// FIXME: If I understand it correctly, this discards calls where C++ code
/// refers a C library function through the namespace `std::` via headers
/// like <cstdlib>.
/// (This mode only matches functions that are declared either directly
/// within a TU or in the namespace `std`.)
CLibrary,

/// Matches "simple" functions that are not methods. (Static methods are
Expand Down
72 changes: 72 additions & 0 deletions clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace ento {

enum CallEventKind {
CE_Function,
CE_CXXStaticOperator,
CE_CXXMember,
CE_CXXMemberOperator,
CE_CXXDestructor,
Expand Down Expand Up @@ -709,6 +710,77 @@ class CXXInstanceCall : public AnyFunctionCall {
}
};

/// Represents a static C++ operator call.
///
/// "A" in this example.
/// However, "B" and "C" are represented by SimpleFunctionCall.
/// \code
/// struct S {
/// int pad;
/// static void operator()(int x, int y);
/// };
/// S s{10};
/// void (*fptr)(int, int) = &S::operator();
///
/// s(1, 2); // A
/// S::operator()(1, 2); // B
/// fptr(1, 2); // C
/// \endcode
class CXXStaticOperatorCall : public SimpleFunctionCall {
friend class CallEventManager;

protected:
CXXStaticOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
const LocationContext *LCtx,
CFGBlock::ConstCFGElementRef ElemRef)
: SimpleFunctionCall(CE, St, LCtx, ElemRef) {}
CXXStaticOperatorCall(const CXXStaticOperatorCall &Other) = default;

void cloneTo(void *Dest) const override {
new (Dest) CXXStaticOperatorCall(*this);
}

public:
const CXXOperatorCallExpr *getOriginExpr() const override {
return cast<CXXOperatorCallExpr>(SimpleFunctionCall::getOriginExpr());
}

unsigned getNumArgs() const override {
// Ignore the object parameter that is not used for static member functions.
assert(getOriginExpr()->getNumArgs() > 0);
return getOriginExpr()->getNumArgs() - 1;
}

const Expr *getArgExpr(unsigned Index) const override {
// Ignore the object parameter that is not used for static member functions.
return getOriginExpr()->getArg(Index + 1);
}

std::optional<unsigned>
getAdjustedParameterIndex(unsigned ASTArgumentIndex) const override {
// Ignore the object parameter that is not used for static member functions.
if (ASTArgumentIndex == 0)
return std::nullopt;
return ASTArgumentIndex - 1;
}

unsigned getASTArgumentIndex(unsigned CallArgumentIndex) const override {
// Account for the object parameter for the static member function.
return CallArgumentIndex + 1;
}

OverloadedOperatorKind getOverloadedOperator() const {
return getOriginExpr()->getOperator();
}

Kind getKind() const override { return CE_CXXStaticOperator; }
StringRef getKindAsString() const override { return "CXXStaticOperatorCall"; }

static bool classof(const CallEvent *CA) {
return CA->getKind() == CE_CXXStaticOperator;
}
};

/// Represents a non-static C++ member function call.
///
/// Example: \c obj.fun()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "ProgramState_Fwd.h"
#include "SVals.h"

#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/OperatorKinds.h"
Expand Down Expand Up @@ -113,8 +112,7 @@ class OperatorKind {
OperatorKind operationKindFromOverloadedOperator(OverloadedOperatorKind OOK,
bool IsBinary);

std::optional<DefinedSVal> getPointeeDefVal(SVal PtrSVal,
ProgramStateRef State);
std::optional<SVal> getPointeeVal(SVal PtrSVal, ProgramStateRef State);

} // namespace ento

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ class ExprEngine {

/// Returns true if there is still simulation state on the worklist.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) {
assert(L->inTopFrame());
BR.setAnalysisEntryPoint(L->getDecl());
return Engine.ExecuteWorkList(L, Steps, nullptr);
}

Expand Down
Loading