81#include "llvm/ADT/APFloat.h"
82#include "llvm/ADT/APInt.h"
83#include "llvm/ADT/APSInt.h"
84#include "llvm/ADT/ArrayRef.h"
85#include "llvm/ADT/DenseMap.h"
86#include "llvm/ADT/FoldingSet.h"
87#include "llvm/ADT/STLExtras.h"
88#include "llvm/ADT/STLForwardCompat.h"
89#include "llvm/ADT/SmallBitVector.h"
90#include "llvm/ADT/SmallPtrSet.h"
91#include "llvm/ADT/SmallString.h"
92#include "llvm/ADT/SmallVector.h"
93#include "llvm/ADT/StringExtras.h"
94#include "llvm/ADT/StringRef.h"
95#include "llvm/ADT/StringSet.h"
96#include "llvm/ADT/StringSwitch.h"
97#include "llvm/Support/AtomicOrdering.h"
98#include "llvm/Support/Compiler.h"
99#include "llvm/Support/ConvertUTF.h"
100#include "llvm/Support/ErrorHandling.h"
101#include "llvm/Support/Format.h"
102#include "llvm/Support/Locale.h"
103#include "llvm/Support/MathExtras.h"
104#include "llvm/Support/SaveAndRestore.h"
105#include "llvm/Support/raw_ostream.h"
106#include "llvm/TargetParser/RISCVTargetParser.h"
107#include "llvm/TargetParser/Triple.h"
120using namespace clang;
124 unsigned ByteNo)
const {
135 unsigned ArgCount =
Call->getNumArgs();
136 if (ArgCount >= MinArgCount)
139 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
140 << 0 << MinArgCount << ArgCount
141 << 0 <<
Call->getSourceRange();
145 unsigned ArgCount =
Call->getNumArgs();
146 if (ArgCount <= MaxArgCount)
148 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
149 << 0 << MaxArgCount << ArgCount
150 << 0 <<
Call->getSourceRange();
154 unsigned MaxArgCount) {
160 unsigned ArgCount =
Call->getNumArgs();
161 if (ArgCount == DesiredArgCount)
166 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
170 Call->getArg(ArgCount - 1)->getEndLoc());
172 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
173 << 0 << DesiredArgCount << ArgCount
178 bool HasError =
false;
180 for (
const Expr *Arg :
Call->arguments()) {
181 if (Arg->isValueDependent())
184 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
185 int DiagMsgKind = -1;
187 if (!ArgString.has_value())
189 else if (ArgString->find(
'$') != std::string::npos)
192 if (DiagMsgKind >= 0) {
193 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
194 << DiagMsgKind << Arg->getSourceRange();
203 if (
Value->isTypeDependent())
210 if (Result.isInvalid())
212 Value = Result.get();
234 if (!Literal || !Literal->isOrdinary()) {
247 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
255 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
256 if (!Literal || !Literal->isWide()) {
257 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
258 << Arg->getSourceRange();
295 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
326 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
328 auto IsValidIntegerType = [](
QualType Ty) {
329 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
336 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
346 if (!IsValidIntegerType(AlignOp->
getType())) {
357 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
358 llvm::APSInt MaxValue(
359 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
360 if (AlignValue < 1) {
361 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
364 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
369 if (!AlignValue.isPowerOf2()) {
370 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
373 if (AlignValue == 1) {
374 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
375 << IsBooleanAlignBuiltin;
403 std::pair<unsigned, const char *> Builtins[] = {
404 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
405 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
406 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
409 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
416 auto ValidCkdIntType = [](
QualType QT) {
419 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
420 return (BT->getKind() >= BuiltinType::Short &&
421 BT->getKind() <= BuiltinType::Int128) || (
422 BT->getKind() >= BuiltinType::UShort &&
423 BT->getKind() <= BuiltinType::UInt128) ||
424 BT->getKind() == BuiltinType::UChar ||
425 BT->getKind() == BuiltinType::SChar;
430 for (
unsigned I = 0; I < 2; ++I) {
436 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
455 !PtrTy->getPointeeType()->isIntegerType() ||
456 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
457 PtrTy->getPointeeType().isConstQualified()) {
459 diag::err_overflow_builtin_must_be_ptr_int)
467 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
468 for (
unsigned I = 0; I < 3; ++I) {
469 const auto Arg = TheCall->
getArg(I);
472 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
474 return S.
Diag(Arg->getBeginLoc(),
475 diag::err_overflow_builtin_bit_int_max_size)
484struct BuiltinDumpStructGenerator {
488 SmallVector<Expr *, 32> Actions;
489 DiagnosticErrorTrap ErrorTracker;
490 PrintingPolicy Policy;
492 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
493 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
494 Policy(S.Context.getPrintingPolicy()) {
498 Expr *makeOpaqueValueExpr(Expr *Inner) {
502 Actions.push_back(OVE);
506 Expr *getStringLiteral(llvm::StringRef Str) {
509 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
512 bool callPrintFunction(llvm::StringRef Format,
513 llvm::ArrayRef<Expr *> Exprs = {}) {
514 SmallVector<Expr *, 8> Args;
516 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
518 Args.push_back(getStringLiteral(Format));
519 llvm::append_range(Args, Exprs);
522 Sema::CodeSynthesisContext Ctx;
535 Actions.push_back(RealCall.
get());
541 Expr *getIndentString(
unsigned Depth) {
545 llvm::SmallString<32>
Indent;
547 return getStringLiteral(
Indent);
551 return getStringLiteral(
T.getAsString(Policy));
554 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
555 llvm::raw_svector_ostream
OS(Str);
559 if (
auto *BT =
T->
getAs<BuiltinType>()) {
560 switch (BT->getKind()) {
561 case BuiltinType::Bool:
564 case BuiltinType::Char_U:
565 case BuiltinType::UChar:
568 case BuiltinType::Char_S:
569 case BuiltinType::SChar:
577 analyze_printf::PrintfSpecifier
Specifier;
580 if (
Specifier.getConversionSpecifier().getKind() ==
581 analyze_printf::PrintfConversionSpecifier::sArg) {
587 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
607 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
608 Expr *IndentLit = getIndentString(Depth);
610 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
611 : callPrintFunction(
"%s", {TypeLit}))
614 return dumpRecordValue(RD, E, IndentLit, Depth);
618 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
627 Expr *RecordArg = makeOpaqueValueExpr(E);
630 if (callPrintFunction(
" {\n"))
634 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
635 for (
const auto &Base : CXXRD->bases()) {
643 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
649 Expr *FieldIndentArg = getIndentString(Depth + 1);
652 for (
auto *D : RD->
decls()) {
653 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
654 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
655 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
658 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
659 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
661 getStringLiteral(FD->getName())};
663 if (FD->isBitField()) {
667 FD->getBitWidthValue());
675 CXXScopeSpec(), Loc, IFD,
678 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
680 DeclarationNameInfo(FD->getDeclName(), Loc));
681 if (
Field.isInvalid())
684 auto *InnerRD = FD->getType()->getAsRecordDecl();
685 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
686 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
688 if (callPrintFunction(Format, Args) ||
689 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
693 if (appendFormatSpecifier(FD->getType(), Format)) {
695 Args.push_back(
Field.get());
705 Args.push_back(FieldAddr.
get());
708 if (callPrintFunction(Format, Args))
713 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
714 : callPrintFunction(
"}\n");
717 Expr *buildWrapper() {
720 TheCall->
setType(Wrapper->getType());
741 diag::err_expected_struct_pointer_argument)
750 diag::err_incomplete_type))
759 switch (BT ? BT->getKind() : BuiltinType::Void) {
760 case BuiltinType::Dependent:
761 case BuiltinType::Overload:
762 case BuiltinType::BoundMember:
763 case BuiltinType::PseudoObject:
764 case BuiltinType::UnknownAny:
765 case BuiltinType::BuiltinFn:
771 diag::err_expected_callable_argument)
777 BuiltinDumpStructGenerator Generator(S, TheCall);
783 Expr *PtrArg = PtrArgResult.
get();
787 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
790 return Generator.buildWrapper();
802 if (
Call->getStmtClass() != Stmt::CallExprClass) {
803 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
804 <<
Call->getSourceRange();
809 if (CE->getCallee()->getType()->isBlockPointerType()) {
810 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
811 <<
Call->getSourceRange();
815 const Decl *TargetDecl = CE->getCalleeDecl();
816 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
817 if (FD->getBuiltinID()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
819 <<
Call->getSourceRange();
824 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
825 <<
Call->getSourceRange();
833 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
847 BuiltinCall->
setType(CE->getType());
851 BuiltinCall->
setArg(1, ChainResult.
get());
858class ScanfDiagnosticFormatHandler
862 using ComputeSizeFunction =
863 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
867 using DiagnoseFunction =
868 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
870 ComputeSizeFunction ComputeSizeArgument;
871 DiagnoseFunction Diagnose;
874 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
875 DiagnoseFunction Diagnose)
876 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
878 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
879 const char *StartSpecifier,
880 unsigned specifierLen)
override {
884 unsigned NulByte = 0;
896 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
898 analyze_format_string::OptionalAmount::HowSpecified::Constant)
903 std::optional<llvm::APSInt> DestSizeAPS =
908 unsigned DestSize = DestSizeAPS->getZExtValue();
910 if (DestSize < SourceSize)
917class EstimateSizeFormatHandler
922 bool IsKernelCompatible =
true;
925 EstimateSizeFormatHandler(StringRef Format)
926 :
Size(std::
min(Format.find(0), Format.size()) +
929 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
930 const char *,
unsigned SpecifierLen,
931 const TargetInfo &)
override {
933 const size_t FieldWidth = computeFieldWidth(FS);
934 const size_t Precision = computePrecision(FS);
941 Size += std::max(FieldWidth, (
size_t)1);
953 Size += std::max(FieldWidth, Precision);
969 Size += std::max(FieldWidth, 1 +
970 (Precision ? 1 + Precision
980 (Precision ? 1 + Precision : 0) +
990 (Precision ? 1 + Precision : 0) +
1005 IsKernelCompatible =
false;
1006 Size += std::max(FieldWidth, 2 + Precision);
1053 Size += (Precision ? 0 : 1);
1060 assert(SpecifierLen <= Size &&
"no underflow");
1061 Size -= SpecifierLen;
1065 size_t getSizeLowerBound()
const {
return Size; }
1066 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1069 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1070 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1071 size_t FieldWidth = 0;
1077 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1079 size_t Precision = 0;
1126 StringRef &FormatStrRef,
size_t &StrLen,
1128 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1129 Format && (Format->isOrdinary() || Format->isUTF8())) {
1130 FormatStrRef = Format->getString();
1132 Context.getAsConstantArrayType(Format->getType());
1133 assert(
T &&
"String literal not of constant array type!");
1134 size_t TypeSize =
T->getZExtSize();
1136 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1142void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1148 bool UseDABAttr =
false;
1149 const FunctionDecl *UseDecl = FD;
1151 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1153 UseDecl = DABAttr->getFunction();
1154 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1166 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1173 unsigned DABIndices = DABAttr->argIndices_size();
1174 unsigned NewIndex = Index < DABIndices
1175 ? DABAttr->argIndices_begin()[Index]
1178 return std::nullopt;
1182 auto ComputeExplicitObjectSizeArgument =
1183 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1184 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1186 return std::nullopt;
1187 unsigned NewIndex = *IndexOptional;
1189 Expr *SizeArg = TheCall->
getArg(NewIndex);
1191 return std::nullopt;
1197 auto ComputeSizeArgument =
1198 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1204 if (Index < FD->getNumParams()) {
1205 if (
const auto *POS =
1207 BOSType = POS->getType();
1210 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1212 return std::nullopt;
1213 unsigned NewIndex = *IndexOptional;
1216 return std::nullopt;
1218 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1221 return std::nullopt;
1224 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1227 auto ComputeStrLenArgument =
1228 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1229 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1231 return std::nullopt;
1232 unsigned NewIndex = *IndexOptional;
1234 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1237 return std::nullopt;
1239 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1242 std::optional<llvm::APSInt> SourceSize;
1243 std::optional<llvm::APSInt> DestinationSize;
1244 unsigned DiagID = 0;
1245 bool IsChkVariant =
false;
1247 auto GetFunctionName = [&]() {
1248 std::string FunctionNameStr =
1250 llvm::StringRef FunctionName = FunctionNameStr;
1255 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1256 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1258 FunctionName.consume_front(
"__builtin_");
1260 return FunctionName.str();
1263 switch (BuiltinID) {
1266 case Builtin::BI__builtin_strcat:
1267 case Builtin::BIstrcat:
1268 case Builtin::BI__builtin_stpcpy:
1269 case Builtin::BIstpcpy:
1270 case Builtin::BI__builtin_strcpy:
1271 case Builtin::BIstrcpy: {
1272 DiagID = diag::warn_fortify_strlen_overflow;
1273 SourceSize = ComputeStrLenArgument(1);
1274 DestinationSize = ComputeSizeArgument(0);
1278 case Builtin::BI__builtin___strcat_chk:
1279 case Builtin::BI__builtin___stpcpy_chk:
1280 case Builtin::BI__builtin___strcpy_chk: {
1281 DiagID = diag::warn_fortify_strlen_overflow;
1282 SourceSize = ComputeStrLenArgument(1);
1283 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1284 IsChkVariant =
true;
1288 case Builtin::BIscanf:
1289 case Builtin::BIfscanf:
1290 case Builtin::BIsscanf: {
1291 unsigned FormatIndex = 1;
1292 unsigned DataIndex = 2;
1293 if (BuiltinID == Builtin::BIscanf) {
1298 const auto *FormatExpr =
1301 StringRef FormatStrRef;
1306 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1307 unsigned SourceSize) {
1308 DiagID = diag::warn_fortify_scanf_overflow;
1309 unsigned Index = ArgIndex + DataIndex;
1310 std::string FunctionName = GetFunctionName();
1312 PDiag(DiagID) << FunctionName << (Index + 1)
1313 << DestSize << SourceSize);
1316 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1317 return ComputeSizeArgument(Index + DataIndex);
1319 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1320 const char *FormatBytes = FormatStrRef.data();
1331 case Builtin::BIsprintf:
1332 case Builtin::BI__builtin___sprintf_chk: {
1333 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1336 StringRef FormatStrRef;
1339 EstimateSizeFormatHandler H(FormatStrRef);
1340 const char *FormatBytes = FormatStrRef.data();
1342 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1343 Context.getTargetInfo(),
false)) {
1344 DiagID = H.isKernelCompatible()
1345 ? diag::warn_format_overflow
1346 : diag::warn_format_overflow_non_kprintf;
1347 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1348 .extOrTrunc(SizeTypeWidth);
1349 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1350 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1351 IsChkVariant =
true;
1353 DestinationSize = ComputeSizeArgument(0);
1360 case Builtin::BI__builtin___memcpy_chk:
1361 case Builtin::BI__builtin___memmove_chk:
1362 case Builtin::BI__builtin___memset_chk:
1363 case Builtin::BI__builtin___strlcat_chk:
1364 case Builtin::BI__builtin___strlcpy_chk:
1365 case Builtin::BI__builtin___strncat_chk:
1366 case Builtin::BI__builtin___strncpy_chk:
1367 case Builtin::BI__builtin___stpncpy_chk:
1368 case Builtin::BI__builtin___memccpy_chk:
1369 case Builtin::BI__builtin___mempcpy_chk: {
1370 DiagID = diag::warn_builtin_chk_overflow;
1371 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1373 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1374 IsChkVariant =
true;
1378 case Builtin::BI__builtin___snprintf_chk:
1379 case Builtin::BI__builtin___vsnprintf_chk: {
1380 DiagID = diag::warn_builtin_chk_overflow;
1381 SourceSize = ComputeExplicitObjectSizeArgument(1);
1382 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1383 IsChkVariant =
true;
1387 case Builtin::BIstrncat:
1388 case Builtin::BI__builtin_strncat:
1389 case Builtin::BIstrncpy:
1390 case Builtin::BI__builtin_strncpy:
1391 case Builtin::BIstpncpy:
1392 case Builtin::BI__builtin_stpncpy: {
1398 DiagID = diag::warn_fortify_source_size_mismatch;
1399 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1400 DestinationSize = ComputeSizeArgument(0);
1404 case Builtin::BImemcpy:
1405 case Builtin::BI__builtin_memcpy:
1406 case Builtin::BImemmove:
1407 case Builtin::BI__builtin_memmove:
1408 case Builtin::BImemset:
1409 case Builtin::BI__builtin_memset:
1410 case Builtin::BImempcpy:
1411 case Builtin::BI__builtin_mempcpy: {
1412 DiagID = diag::warn_fortify_source_overflow;
1413 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1414 DestinationSize = ComputeSizeArgument(0);
1417 case Builtin::BIsnprintf:
1418 case Builtin::BI__builtin_snprintf:
1419 case Builtin::BIvsnprintf:
1420 case Builtin::BI__builtin_vsnprintf: {
1421 DiagID = diag::warn_fortify_source_size_mismatch;
1422 SourceSize = ComputeExplicitObjectSizeArgument(1);
1424 StringRef FormatStrRef;
1428 EstimateSizeFormatHandler H(FormatStrRef);
1429 const char *FormatBytes = FormatStrRef.data();
1431 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1432 Context.getTargetInfo(),
false)) {
1433 llvm::APSInt FormatSize =
1434 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1435 .extOrTrunc(SizeTypeWidth);
1436 if (FormatSize > *SourceSize && *SourceSize != 0) {
1437 unsigned TruncationDiagID =
1438 H.isKernelCompatible() ? diag::warn_format_truncation
1439 : diag::warn_format_truncation_non_kprintf;
1440 SmallString<16> SpecifiedSizeStr;
1441 SmallString<16> FormatSizeStr;
1442 SourceSize->toString(SpecifiedSizeStr, 10);
1443 FormatSize.toString(FormatSizeStr, 10);
1445 PDiag(TruncationDiagID)
1446 << GetFunctionName() << SpecifiedSizeStr
1451 DestinationSize = ComputeSizeArgument(0);
1455 if (!SourceSize || !DestinationSize ||
1456 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1459 std::string FunctionName = GetFunctionName();
1461 SmallString<16> DestinationStr;
1462 SmallString<16> SourceStr;
1463 DestinationSize->toString(DestinationStr, 10);
1464 SourceSize->toString(SourceStr, 10);
1467 << FunctionName << DestinationStr << SourceStr);
1482 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1485 << DRE->getDecl()->getIdentifier();
1497 "__builtin_alloca has invalid address space");
1510 if (Arg->isTypeDependent() || Arg->isValueDependent())
1513 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1515 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1523enum PointerAuthOpKind {
1538 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1569 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1572 llvm::raw_svector_ostream Str(
Value);
1581 Result = KeyValue->getZExtValue();
1600 bool IsAddrDiscArg =
false;
1605 IsAddrDiscArg =
true;
1614 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1615 <<
Result->getExtValue();
1617 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1623 IntVal =
Result->getZExtValue();
1627static std::pair<const ValueDecl *, CharUnits>
1634 const auto *BaseDecl =
1639 return {BaseDecl, Result.Val.getLValueOffset()};
1643 bool RequireConstant =
false) {
1651 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1652 return OpKind != PAO_BlendInteger;
1654 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1655 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1656 OpKind == PAO_SignGeneric;
1665 }
else if (AllowsInteger(OpKind) &&
1672 <<
unsigned(OpKind == PAO_Discriminator ? 1
1673 : OpKind == PAO_BlendPointer ? 2
1674 : OpKind == PAO_BlendInteger ? 3
1676 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1686 if (!RequireConstant) {
1688 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1691 ? diag::warn_ptrauth_sign_null_pointer
1692 : diag::warn_ptrauth_auth_null_pointer)
1702 if (OpKind == PAO_Sign) {
1720 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1725 assert(OpKind == PAO_Discriminator);
1731 if (
Call->getBuiltinCallee() ==
1732 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1747 assert(
Pointer->getType()->isPointerType());
1759 assert(
Integer->getType()->isIntegerType());
1765 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1778 Call->setType(
Call->getArgs()[0]->getType());
1809 PointerAuthOpKind OpKind,
1810 bool RequireConstant) {
1821 Call->setType(
Call->getArgs()[0]->getType());
1837 Call->setType(
Call->getArgs()[0]->getType());
1846 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1849 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1850 if (!Literal || Literal->getCharByteWidth() != 1) {
1866 Call->setArg(0, FirstValue.
get());
1872 if (!FirstArgRecord) {
1873 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1874 << 0 << FirstArgType;
1879 diag::err_get_vtable_pointer_requires_complete_type)) {
1884 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1885 << 1 << FirstArgRecord;
1889 Call->setType(ReturnType);
1914 auto DiagSelect = [&]() -> std::optional<unsigned> {
1921 return std::optional<unsigned>{};
1936 diag::err_incomplete_type))
1940 "Unhandled non-object pointer case");
1968 if (PT->getPointeeType()->isFunctionType()) {
1970 diag::err_builtin_is_within_lifetime_invalid_arg)
1976 if (PT->getPointeeType()->isVariableArrayType()) {
1978 << 1 <<
"__builtin_is_within_lifetime";
1983 diag::err_builtin_is_within_lifetime_invalid_arg)
1997 diag::err_builtin_trivially_relocate_invalid_arg_type)
2004 diag::err_incomplete_type))
2008 T->isIncompleteArrayType()) {
2010 diag::err_builtin_trivially_relocate_invalid_arg_type)
2011 << (
T.isConstQualified() ? 1 : 2);
2020 diag::err_builtin_trivially_relocate_invalid_arg_type)
2027 if (Size.isInvalid())
2031 if (Size.isInvalid())
2033 SizeExpr = Size.get();
2034 TheCall->
setArg(2, SizeExpr);
2044 llvm::Triple::ObjectFormatType CurObjFormat =
2046 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2059 llvm::Triple::ArchType CurArch =
2061 if (llvm::is_contained(SupportedArchs, CurArch))
2071bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2078 case llvm::Triple::arm:
2079 case llvm::Triple::armeb:
2080 case llvm::Triple::thumb:
2081 case llvm::Triple::thumbeb:
2083 case llvm::Triple::aarch64:
2084 case llvm::Triple::aarch64_32:
2085 case llvm::Triple::aarch64_be:
2087 case llvm::Triple::bpfeb:
2088 case llvm::Triple::bpfel:
2090 case llvm::Triple::dxil:
2092 case llvm::Triple::hexagon:
2094 case llvm::Triple::mips:
2095 case llvm::Triple::mipsel:
2096 case llvm::Triple::mips64:
2097 case llvm::Triple::mips64el:
2099 case llvm::Triple::spirv:
2100 case llvm::Triple::spirv32:
2101 case llvm::Triple::spirv64:
2102 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2105 case llvm::Triple::systemz:
2107 case llvm::Triple::x86:
2108 case llvm::Triple::x86_64:
2110 case llvm::Triple::ppc:
2111 case llvm::Triple::ppcle:
2112 case llvm::Triple::ppc64:
2113 case llvm::Triple::ppc64le:
2115 case llvm::Triple::amdgcn:
2117 case llvm::Triple::riscv32:
2118 case llvm::Triple::riscv64:
2120 case llvm::Triple::loongarch32:
2121 case llvm::Triple::loongarch64:
2124 case llvm::Triple::wasm32:
2125 case llvm::Triple::wasm64:
2127 case llvm::Triple::nvptx:
2128 case llvm::Triple::nvptx64:
2142 EltTy = VecTy->getElementType();
2144 switch (ArgTyRestr) {
2148 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2149 << ArgOrdinal << 2 << 1 << 1
2155 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2156 << ArgOrdinal << 5 << 0
2162 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2163 << ArgOrdinal << 5 << 1
2169 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2183 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2184 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2185 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2186 "Expecting __builtin_cpu_...");
2188 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2190 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2191 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2192 (!IsCPUSupports && TInfo->supportsCpuIs()));
2194 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2201 ? diag::err_builtin_aix_os_unsupported
2202 : diag::err_builtin_target_unsupported)
2208 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2246 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2247 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8) {
2249 << ArgTy << BT->getNumBits();
2293 TheCall->
setArg(0, Arg0);
2310 TheCall->
setArg(1, Arg1);
2316 << 2 << 1 << 4 << 0 << Arg1Ty;
2325 unsigned Pos,
bool AllowConst,
2329 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2334 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2335 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2336 << Pos <<
"scalar pointer";
2345 diag::err_typecheck_convert_incompatible)
2354 bool TypeDependent =
false;
2355 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2383 Builtin::BI__builtin_masked_load))
2397 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2420 Builtin::BI__builtin_masked_store))
2428 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2438 diag::err_vec_builtin_incompatible_vector)
2467 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2480 << MaskTy << IdxTy);
2489 diag::err_vec_masked_load_store_ptr)
2518 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2534 << MaskTy << IdxTy);
2540 << MaskTy << ValTy);
2546 diag::err_vec_builtin_incompatible_vector)
2560 if (Args.size() == 0) {
2562 diag::err_typecheck_call_too_few_args_at_least)
2568 QualType FuncT = Args[0]->getType();
2571 if (Args.size() < 2) {
2573 diag::err_typecheck_call_too_few_args_at_least)
2579 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2580 QualType ObjectT = Args[1]->getType();
2582 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2631 tok::periodstar, ObjectArg.
get(), Args[0]);
2635 if (MPT->isMemberDataPointer())
2638 auto *MemCall =
new (S.
Context)
2661Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2666 unsigned ICEArguments = 0;
2668 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2673 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2675 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2680 if (ArgNo < TheCall->getNumArgs() &&
2683 ICEArguments &= ~(1 << ArgNo);
2687 switch (BuiltinID) {
2688 case Builtin::BI__builtin_cpu_supports:
2689 case Builtin::BI__builtin_cpu_is:
2691 Context.getAuxTargetInfo(), BuiltinID))
2694 case Builtin::BI__builtin_cpu_init:
2695 if (!
Context.getTargetInfo().supportsCpuInit()) {
2701 case Builtin::BI__builtin___CFStringMakeConstantString:
2705 *
this, BuiltinID, TheCall,
2706 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2709 "Wrong # arguments to builtin CFStringMakeConstantString");
2710 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2713 case Builtin::BI__builtin_ms_va_start:
2714 case Builtin::BI__builtin_stdarg_start:
2715 case Builtin::BI__builtin_va_start:
2716 case Builtin::BI__builtin_c23_va_start:
2717 if (BuiltinVAStart(BuiltinID, TheCall))
2720 case Builtin::BI__va_start: {
2721 switch (
Context.getTargetInfo().getTriple().getArch()) {
2722 case llvm::Triple::aarch64:
2723 case llvm::Triple::arm:
2724 case llvm::Triple::thumb:
2725 if (BuiltinVAStartARMMicrosoft(TheCall))
2729 if (BuiltinVAStart(BuiltinID, TheCall))
2737 case Builtin::BI_interlockedbittestandset_acq:
2738 case Builtin::BI_interlockedbittestandset_rel:
2739 case Builtin::BI_interlockedbittestandset_nf:
2740 case Builtin::BI_interlockedbittestandreset_acq:
2741 case Builtin::BI_interlockedbittestandreset_rel:
2742 case Builtin::BI_interlockedbittestandreset_nf:
2745 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2750 case Builtin::BI_bittest64:
2751 case Builtin::BI_bittestandcomplement64:
2752 case Builtin::BI_bittestandreset64:
2753 case Builtin::BI_bittestandset64:
2754 case Builtin::BI_interlockedbittestandreset64:
2755 case Builtin::BI_interlockedbittestandset64:
2758 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2759 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2764 case Builtin::BI_interlockedbittestandreset64_acq:
2765 case Builtin::BI_interlockedbittestandreset64_rel:
2766 case Builtin::BI_interlockedbittestandreset64_nf:
2767 case Builtin::BI_interlockedbittestandset64_acq:
2768 case Builtin::BI_interlockedbittestandset64_rel:
2769 case Builtin::BI_interlockedbittestandset64_nf:
2774 case Builtin::BI__builtin_set_flt_rounds:
2777 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2778 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2779 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2780 llvm::Triple::ppc64le}))
2784 case Builtin::BI__builtin_isgreater:
2785 case Builtin::BI__builtin_isgreaterequal:
2786 case Builtin::BI__builtin_isless:
2787 case Builtin::BI__builtin_islessequal:
2788 case Builtin::BI__builtin_islessgreater:
2789 case Builtin::BI__builtin_isunordered:
2790 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2793 case Builtin::BI__builtin_fpclassify:
2794 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2797 case Builtin::BI__builtin_isfpclass:
2798 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2801 case Builtin::BI__builtin_isfinite:
2802 case Builtin::BI__builtin_isinf:
2803 case Builtin::BI__builtin_isinf_sign:
2804 case Builtin::BI__builtin_isnan:
2805 case Builtin::BI__builtin_issignaling:
2806 case Builtin::BI__builtin_isnormal:
2807 case Builtin::BI__builtin_issubnormal:
2808 case Builtin::BI__builtin_iszero:
2809 case Builtin::BI__builtin_signbit:
2810 case Builtin::BI__builtin_signbitf:
2811 case Builtin::BI__builtin_signbitl:
2812 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2815 case Builtin::BI__builtin_shufflevector:
2819 case Builtin::BI__builtin_masked_load:
2820 case Builtin::BI__builtin_masked_expand_load:
2822 case Builtin::BI__builtin_masked_store:
2823 case Builtin::BI__builtin_masked_compress_store:
2825 case Builtin::BI__builtin_masked_gather:
2827 case Builtin::BI__builtin_masked_scatter:
2829 case Builtin::BI__builtin_invoke:
2831 case Builtin::BI__builtin_prefetch:
2832 if (BuiltinPrefetch(TheCall))
2835 case Builtin::BI__builtin_alloca_with_align:
2836 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2837 if (BuiltinAllocaWithAlign(TheCall))
2840 case Builtin::BI__builtin_alloca:
2841 case Builtin::BI__builtin_alloca_uninitialized:
2848 case Builtin::BI__builtin_infer_alloc_token:
2852 case Builtin::BI__arithmetic_fence:
2853 if (BuiltinArithmeticFence(TheCall))
2856 case Builtin::BI__assume:
2857 case Builtin::BI__builtin_assume:
2858 if (BuiltinAssume(TheCall))
2861 case Builtin::BI__builtin_assume_aligned:
2862 if (BuiltinAssumeAligned(TheCall))
2865 case Builtin::BI__builtin_dynamic_object_size:
2866 case Builtin::BI__builtin_object_size:
2870 case Builtin::BI__builtin_longjmp:
2871 if (BuiltinLongjmp(TheCall))
2874 case Builtin::BI__builtin_setjmp:
2875 if (BuiltinSetjmp(TheCall))
2878 case Builtin::BI__builtin_classify_type:
2883 case Builtin::BI__builtin_complex:
2884 if (BuiltinComplex(TheCall))
2887 case Builtin::BI__builtin_constant_p: {
2896 case Builtin::BI__builtin_launder:
2898 case Builtin::BI__builtin_is_within_lifetime:
2900 case Builtin::BI__builtin_trivially_relocate:
2903 case Builtin::BI__sync_fetch_and_add:
2904 case Builtin::BI__sync_fetch_and_add_1:
2905 case Builtin::BI__sync_fetch_and_add_2:
2906 case Builtin::BI__sync_fetch_and_add_4:
2907 case Builtin::BI__sync_fetch_and_add_8:
2908 case Builtin::BI__sync_fetch_and_add_16:
2909 case Builtin::BI__sync_fetch_and_sub:
2910 case Builtin::BI__sync_fetch_and_sub_1:
2911 case Builtin::BI__sync_fetch_and_sub_2:
2912 case Builtin::BI__sync_fetch_and_sub_4:
2913 case Builtin::BI__sync_fetch_and_sub_8:
2914 case Builtin::BI__sync_fetch_and_sub_16:
2915 case Builtin::BI__sync_fetch_and_or:
2916 case Builtin::BI__sync_fetch_and_or_1:
2917 case Builtin::BI__sync_fetch_and_or_2:
2918 case Builtin::BI__sync_fetch_and_or_4:
2919 case Builtin::BI__sync_fetch_and_or_8:
2920 case Builtin::BI__sync_fetch_and_or_16:
2921 case Builtin::BI__sync_fetch_and_and:
2922 case Builtin::BI__sync_fetch_and_and_1:
2923 case Builtin::BI__sync_fetch_and_and_2:
2924 case Builtin::BI__sync_fetch_and_and_4:
2925 case Builtin::BI__sync_fetch_and_and_8:
2926 case Builtin::BI__sync_fetch_and_and_16:
2927 case Builtin::BI__sync_fetch_and_xor:
2928 case Builtin::BI__sync_fetch_and_xor_1:
2929 case Builtin::BI__sync_fetch_and_xor_2:
2930 case Builtin::BI__sync_fetch_and_xor_4:
2931 case Builtin::BI__sync_fetch_and_xor_8:
2932 case Builtin::BI__sync_fetch_and_xor_16:
2933 case Builtin::BI__sync_fetch_and_nand:
2934 case Builtin::BI__sync_fetch_and_nand_1:
2935 case Builtin::BI__sync_fetch_and_nand_2:
2936 case Builtin::BI__sync_fetch_and_nand_4:
2937 case Builtin::BI__sync_fetch_and_nand_8:
2938 case Builtin::BI__sync_fetch_and_nand_16:
2939 case Builtin::BI__sync_add_and_fetch:
2940 case Builtin::BI__sync_add_and_fetch_1:
2941 case Builtin::BI__sync_add_and_fetch_2:
2942 case Builtin::BI__sync_add_and_fetch_4:
2943 case Builtin::BI__sync_add_and_fetch_8:
2944 case Builtin::BI__sync_add_and_fetch_16:
2945 case Builtin::BI__sync_sub_and_fetch:
2946 case Builtin::BI__sync_sub_and_fetch_1:
2947 case Builtin::BI__sync_sub_and_fetch_2:
2948 case Builtin::BI__sync_sub_and_fetch_4:
2949 case Builtin::BI__sync_sub_and_fetch_8:
2950 case Builtin::BI__sync_sub_and_fetch_16:
2951 case Builtin::BI__sync_and_and_fetch:
2952 case Builtin::BI__sync_and_and_fetch_1:
2953 case Builtin::BI__sync_and_and_fetch_2:
2954 case Builtin::BI__sync_and_and_fetch_4:
2955 case Builtin::BI__sync_and_and_fetch_8:
2956 case Builtin::BI__sync_and_and_fetch_16:
2957 case Builtin::BI__sync_or_and_fetch:
2958 case Builtin::BI__sync_or_and_fetch_1:
2959 case Builtin::BI__sync_or_and_fetch_2:
2960 case Builtin::BI__sync_or_and_fetch_4:
2961 case Builtin::BI__sync_or_and_fetch_8:
2962 case Builtin::BI__sync_or_and_fetch_16:
2963 case Builtin::BI__sync_xor_and_fetch:
2964 case Builtin::BI__sync_xor_and_fetch_1:
2965 case Builtin::BI__sync_xor_and_fetch_2:
2966 case Builtin::BI__sync_xor_and_fetch_4:
2967 case Builtin::BI__sync_xor_and_fetch_8:
2968 case Builtin::BI__sync_xor_and_fetch_16:
2969 case Builtin::BI__sync_nand_and_fetch:
2970 case Builtin::BI__sync_nand_and_fetch_1:
2971 case Builtin::BI__sync_nand_and_fetch_2:
2972 case Builtin::BI__sync_nand_and_fetch_4:
2973 case Builtin::BI__sync_nand_and_fetch_8:
2974 case Builtin::BI__sync_nand_and_fetch_16:
2975 case Builtin::BI__sync_val_compare_and_swap:
2976 case Builtin::BI__sync_val_compare_and_swap_1:
2977 case Builtin::BI__sync_val_compare_and_swap_2:
2978 case Builtin::BI__sync_val_compare_and_swap_4:
2979 case Builtin::BI__sync_val_compare_and_swap_8:
2980 case Builtin::BI__sync_val_compare_and_swap_16:
2981 case Builtin::BI__sync_bool_compare_and_swap:
2982 case Builtin::BI__sync_bool_compare_and_swap_1:
2983 case Builtin::BI__sync_bool_compare_and_swap_2:
2984 case Builtin::BI__sync_bool_compare_and_swap_4:
2985 case Builtin::BI__sync_bool_compare_and_swap_8:
2986 case Builtin::BI__sync_bool_compare_and_swap_16:
2987 case Builtin::BI__sync_lock_test_and_set:
2988 case Builtin::BI__sync_lock_test_and_set_1:
2989 case Builtin::BI__sync_lock_test_and_set_2:
2990 case Builtin::BI__sync_lock_test_and_set_4:
2991 case Builtin::BI__sync_lock_test_and_set_8:
2992 case Builtin::BI__sync_lock_test_and_set_16:
2993 case Builtin::BI__sync_lock_release:
2994 case Builtin::BI__sync_lock_release_1:
2995 case Builtin::BI__sync_lock_release_2:
2996 case Builtin::BI__sync_lock_release_4:
2997 case Builtin::BI__sync_lock_release_8:
2998 case Builtin::BI__sync_lock_release_16:
2999 case Builtin::BI__sync_swap:
3000 case Builtin::BI__sync_swap_1:
3001 case Builtin::BI__sync_swap_2:
3002 case Builtin::BI__sync_swap_4:
3003 case Builtin::BI__sync_swap_8:
3004 case Builtin::BI__sync_swap_16:
3005 return BuiltinAtomicOverloaded(TheCallResult);
3006 case Builtin::BI__sync_synchronize:
3010 case Builtin::BI__builtin_nontemporal_load:
3011 case Builtin::BI__builtin_nontemporal_store:
3012 return BuiltinNontemporalOverloaded(TheCallResult);
3013 case Builtin::BI__builtin_memcpy_inline: {
3014 clang::Expr *SizeOp = TheCall->
getArg(2);
3026 case Builtin::BI__builtin_memset_inline: {
3027 clang::Expr *SizeOp = TheCall->
getArg(2);
3037#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3038 case Builtin::BI##ID: \
3039 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3040#include "clang/Basic/Builtins.inc"
3041 case Builtin::BI__annotation:
3045 case Builtin::BI__builtin_annotation:
3049 case Builtin::BI__builtin_addressof:
3053 case Builtin::BI__builtin_function_start:
3057 case Builtin::BI__builtin_is_aligned:
3058 case Builtin::BI__builtin_align_up:
3059 case Builtin::BI__builtin_align_down:
3063 case Builtin::BI__builtin_add_overflow:
3064 case Builtin::BI__builtin_sub_overflow:
3065 case Builtin::BI__builtin_mul_overflow:
3069 case Builtin::BI__builtin_operator_new:
3070 case Builtin::BI__builtin_operator_delete: {
3071 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3073 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3076 case Builtin::BI__builtin_dump_struct:
3078 case Builtin::BI__builtin_expect_with_probability: {
3083 const Expr *ProbArg = TheCall->
getArg(2);
3084 SmallVector<PartialDiagnosticAt, 8> Notes;
3085 Expr::EvalResult Eval;
3089 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3096 bool LoseInfo =
false;
3097 Probability.convert(llvm::APFloat::IEEEdouble(),
3098 llvm::RoundingMode::Dynamic, &LoseInfo);
3099 if (!(Probability >= llvm::APFloat(0.0) &&
3100 Probability <= llvm::APFloat(1.0))) {
3107 case Builtin::BI__builtin_preserve_access_index:
3111 case Builtin::BI__builtin_call_with_static_chain:
3115 case Builtin::BI__exception_code:
3116 case Builtin::BI_exception_code:
3118 diag::err_seh___except_block))
3121 case Builtin::BI__exception_info:
3122 case Builtin::BI_exception_info:
3124 diag::err_seh___except_filter))
3127 case Builtin::BI__GetExceptionInfo:
3139 case Builtin::BIaddressof:
3140 case Builtin::BI__addressof:
3141 case Builtin::BIforward:
3142 case Builtin::BIforward_like:
3143 case Builtin::BImove:
3144 case Builtin::BImove_if_noexcept:
3145 case Builtin::BIas_const: {
3153 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3154 BuiltinID == Builtin::BI__addressof;
3156 (ReturnsPointer ?
Result->isAnyPointerType()
3157 :
Result->isReferenceType()) &&
3160 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3166 case Builtin::BI__builtin_ptrauth_strip:
3168 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3170 case Builtin::BI__builtin_ptrauth_sign_constant:
3173 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3176 case Builtin::BI__builtin_ptrauth_auth:
3179 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3181 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3183 case Builtin::BI__builtin_ptrauth_string_discriminator:
3186 case Builtin::BI__builtin_get_vtable_pointer:
3190 case Builtin::BIread_pipe:
3191 case Builtin::BIwrite_pipe:
3194 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3197 case Builtin::BIreserve_read_pipe:
3198 case Builtin::BIreserve_write_pipe:
3199 case Builtin::BIwork_group_reserve_read_pipe:
3200 case Builtin::BIwork_group_reserve_write_pipe:
3201 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3204 case Builtin::BIsub_group_reserve_read_pipe:
3205 case Builtin::BIsub_group_reserve_write_pipe:
3206 if (
OpenCL().checkSubgroupExt(TheCall) ||
3207 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3210 case Builtin::BIcommit_read_pipe:
3211 case Builtin::BIcommit_write_pipe:
3212 case Builtin::BIwork_group_commit_read_pipe:
3213 case Builtin::BIwork_group_commit_write_pipe:
3214 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3217 case Builtin::BIsub_group_commit_read_pipe:
3218 case Builtin::BIsub_group_commit_write_pipe:
3219 if (
OpenCL().checkSubgroupExt(TheCall) ||
3220 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3223 case Builtin::BIget_pipe_num_packets:
3224 case Builtin::BIget_pipe_max_packets:
3225 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3228 case Builtin::BIto_global:
3229 case Builtin::BIto_local:
3230 case Builtin::BIto_private:
3231 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3235 case Builtin::BIenqueue_kernel:
3236 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3239 case Builtin::BIget_kernel_work_group_size:
3240 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3241 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3244 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3245 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3246 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3249 case Builtin::BI__builtin_os_log_format:
3250 Cleanup.setExprNeedsCleanups(
true);
3252 case Builtin::BI__builtin_os_log_format_buffer_size:
3253 if (BuiltinOSLogFormat(TheCall))
3256 case Builtin::BI__builtin_frame_address:
3257 case Builtin::BI__builtin_return_address: {
3266 Result.Val.getInt() != 0)
3268 << ((BuiltinID == Builtin::BI__builtin_return_address)
3269 ?
"__builtin_return_address"
3270 :
"__builtin_frame_address")
3275 case Builtin::BI__builtin_nondeterministic_value: {
3276 if (BuiltinNonDeterministicValue(TheCall))
3283 case Builtin::BI__builtin_elementwise_abs:
3291 case Builtin::BI__builtin_elementwise_acos:
3292 case Builtin::BI__builtin_elementwise_asin:
3293 case Builtin::BI__builtin_elementwise_atan:
3294 case Builtin::BI__builtin_elementwise_ceil:
3295 case Builtin::BI__builtin_elementwise_cos:
3296 case Builtin::BI__builtin_elementwise_cosh:
3297 case Builtin::BI__builtin_elementwise_exp:
3298 case Builtin::BI__builtin_elementwise_exp2:
3299 case Builtin::BI__builtin_elementwise_exp10:
3300 case Builtin::BI__builtin_elementwise_floor:
3301 case Builtin::BI__builtin_elementwise_log:
3302 case Builtin::BI__builtin_elementwise_log2:
3303 case Builtin::BI__builtin_elementwise_log10:
3304 case Builtin::BI__builtin_elementwise_roundeven:
3305 case Builtin::BI__builtin_elementwise_round:
3306 case Builtin::BI__builtin_elementwise_rint:
3307 case Builtin::BI__builtin_elementwise_nearbyint:
3308 case Builtin::BI__builtin_elementwise_sin:
3309 case Builtin::BI__builtin_elementwise_sinh:
3310 case Builtin::BI__builtin_elementwise_sqrt:
3311 case Builtin::BI__builtin_elementwise_tan:
3312 case Builtin::BI__builtin_elementwise_tanh:
3313 case Builtin::BI__builtin_elementwise_trunc:
3314 case Builtin::BI__builtin_elementwise_canonicalize:
3319 case Builtin::BI__builtin_elementwise_fma:
3324 case Builtin::BI__builtin_elementwise_ldexp: {
3346 const auto *Vec0 = TyA->
getAs<VectorType>();
3347 const auto *Vec1 = TyExp->
getAs<VectorType>();
3348 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3350 if (Arg0Length != Arg1Length) {
3352 diag::err_typecheck_vector_lengths_not_equal)
3366 case Builtin::BI__builtin_elementwise_minnum:
3367 case Builtin::BI__builtin_elementwise_maxnum:
3368 case Builtin::BI__builtin_elementwise_minimum:
3369 case Builtin::BI__builtin_elementwise_maximum:
3370 case Builtin::BI__builtin_elementwise_minimumnum:
3371 case Builtin::BI__builtin_elementwise_maximumnum:
3372 case Builtin::BI__builtin_elementwise_atan2:
3373 case Builtin::BI__builtin_elementwise_fmod:
3374 case Builtin::BI__builtin_elementwise_pow:
3375 if (BuiltinElementwiseMath(TheCall,
3381 case Builtin::BI__builtin_elementwise_add_sat:
3382 case Builtin::BI__builtin_elementwise_sub_sat:
3383 if (BuiltinElementwiseMath(TheCall,
3387 case Builtin::BI__builtin_elementwise_fshl:
3388 case Builtin::BI__builtin_elementwise_fshr:
3393 case Builtin::BI__builtin_elementwise_min:
3394 case Builtin::BI__builtin_elementwise_max:
3395 if (BuiltinElementwiseMath(TheCall))
3398 case Builtin::BI__builtin_elementwise_popcount:
3399 case Builtin::BI__builtin_elementwise_bitreverse:
3404 case Builtin::BI__builtin_elementwise_copysign: {
3413 QualType MagnitudeTy = Magnitude.
get()->
getType();
3426 diag::err_typecheck_call_different_arg_types)
3427 << MagnitudeTy << SignTy;
3435 case Builtin::BI__builtin_elementwise_clzg:
3436 case Builtin::BI__builtin_elementwise_ctzg:
3444 }
else if (BuiltinElementwiseMath(
3448 case Builtin::BI__builtin_reduce_max:
3449 case Builtin::BI__builtin_reduce_min: {
3450 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3453 const Expr *Arg = TheCall->
getArg(0);
3458 ElTy = TyA->getElementType();
3462 if (ElTy.isNull()) {
3472 case Builtin::BI__builtin_reduce_maximum:
3473 case Builtin::BI__builtin_reduce_minimum: {
3474 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3477 const Expr *Arg = TheCall->
getArg(0);
3482 ElTy = TyA->getElementType();
3486 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3499 case Builtin::BI__builtin_reduce_add:
3500 case Builtin::BI__builtin_reduce_mul:
3501 case Builtin::BI__builtin_reduce_xor:
3502 case Builtin::BI__builtin_reduce_or:
3503 case Builtin::BI__builtin_reduce_and: {
3504 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3507 const Expr *Arg = TheCall->
getArg(0);
3512 ElTy = TyA->getElementType();
3516 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3527 case Builtin::BI__builtin_matrix_transpose:
3528 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3530 case Builtin::BI__builtin_matrix_column_major_load:
3531 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3533 case Builtin::BI__builtin_matrix_column_major_store:
3534 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3536 case Builtin::BI__builtin_verbose_trap:
3541 case Builtin::BI__builtin_get_device_side_mangled_name: {
3542 auto Check = [](CallExpr *TheCall) {
3548 auto *D = DRE->getDecl();
3551 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3552 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3554 if (!Check(TheCall)) {
3556 diag::err_hip_invalid_args_builtin_mangled_name);
3561 case Builtin::BI__builtin_bswapg:
3565 case Builtin::BI__builtin_popcountg:
3569 case Builtin::BI__builtin_clzg:
3570 case Builtin::BI__builtin_ctzg:
3575 case Builtin::BI__builtin_allow_runtime_check: {
3576 Expr *Arg = TheCall->
getArg(0);
3585 case Builtin::BI__builtin_counted_by_ref:
3586 if (BuiltinCountedByRef(TheCall))
3596 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3597 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3598 assert(
Context.getAuxTargetInfo() &&
3599 "Aux Target Builtin, but not an aux target?");
3601 if (CheckTSBuiltinFunctionCall(
3603 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3606 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3612 return TheCallResult;
3627 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3631 diag::err_argument_not_contiguous_bit_field)
3638 bool IsVariadic =
false;
3641 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3642 IsVariadic = BD->isVariadic();
3643 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3644 IsVariadic = OMD->isVariadic();
3651 bool HasImplicitThisParam,
bool IsVariadic,
3655 else if (IsVariadic)
3665 if (HasImplicitThisParam) {
3697 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3698 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3699 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3700 Expr = ILE->getInit(0);
3710 const Expr *ArgExpr,
3714 S.
PDiag(diag::warn_null_arg)
3720 if (
auto nullability =
type->getNullability())
3731 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3737 llvm::SmallBitVector NonNullArgs;
3743 for (
const auto *Arg : Args)
3750 unsigned IdxAST = Idx.getASTIndex();
3751 if (IdxAST >= Args.size())
3753 if (NonNullArgs.empty())
3754 NonNullArgs.resize(Args.size());
3755 NonNullArgs.set(IdxAST);
3764 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3769 unsigned ParamIndex = 0;
3771 I != E; ++I, ++ParamIndex) {
3774 if (NonNullArgs.empty())
3775 NonNullArgs.resize(Args.size());
3777 NonNullArgs.set(ParamIndex);
3784 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3789 type = blockType->getPointeeType();
3803 if (NonNullArgs.empty())
3804 NonNullArgs.resize(Args.size());
3806 NonNullArgs.set(Index);
3815 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3816 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3817 if (NonNullArgs[ArgIndex])
3823 StringRef ParamName,
QualType ArgTy,
3846 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3847 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3851 if (ArgAlign < ParamAlign)
3852 Diag(Loc, diag::warn_param_mismatched_alignment)
3854 << ParamName << (FDecl !=
nullptr) << FDecl;
3858 const Expr *ThisArg,
3860 if (!FD || Args.empty())
3862 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3863 if (Idx == LifetimeCaptureByAttr::Global ||
3864 Idx == LifetimeCaptureByAttr::Unknown)
3866 if (IsMemberFunction && Idx == 0)
3868 return Args[Idx - IsMemberFunction];
3870 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3875 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3876 for (
int CapturingParamIdx :
Attr->params()) {
3879 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3882 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3890 I + IsMemberFunction);
3892 if (IsMemberFunction) {
3900 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3913 llvm::SmallBitVector CheckedVarArgs;
3915 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3917 CheckedVarArgs.resize(Args.size());
3918 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3923 CheckedVarArgs.resize(Args.size());
3924 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3931 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3935 : isa_and_nonnull<FunctionDecl>(FDecl)
3937 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3941 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3943 if (
const Expr *Arg = Args[ArgIdx]) {
3944 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3951 if (FDecl || Proto) {
3956 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3957 CheckArgumentWithTypeTag(I, Args, Loc);
3963 if (!Proto && FDecl) {
3965 if (isa_and_nonnull<FunctionProtoType>(FT))
3971 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3973 bool IsScalableArg =
false;
3974 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3976 if (
const Expr *Arg = Args[ArgIdx]) {
3980 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3988 IsScalableArg =
true;
3990 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3999 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4000 llvm::StringMap<bool> CallerFeatureMap;
4001 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4002 if (!CallerFeatureMap.contains(
"sme"))
4003 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4004 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4005 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4014 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4016 (IsScalableArg || IsScalableRet)) {
4017 bool IsCalleeStreaming =
4019 bool IsCalleeStreamingCompatible =
4023 if (!IsCalleeStreamingCompatible &&
4027 unsigned VL = LO.VScaleMin * 128;
4028 unsigned SVL = LO.VScaleStreamingMin * 128;
4029 bool IsVLMismatch = VL && SVL && VL != SVL;
4031 auto EmitDiag = [&](
bool IsArg) {
4035 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4036 << IsArg << IsCalleeStreaming << SVL << VL;
4039 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4040 << IsArg << SVL << VL;
4042 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4059 bool CallerHasZAState =
false;
4060 bool CallerHasZT0State =
false;
4062 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4064 CallerHasZAState =
true;
4066 CallerHasZT0State =
true;
4070 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4072 CallerHasZT0State |=
4074 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4080 Diag(Loc, diag::err_sme_za_call_no_za_state);
4083 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4087 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4088 Diag(Loc, diag::note_sme_use_preserves_za);
4093 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4094 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4095 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4096 if (!Arg->isValueDependent()) {
4098 if (Arg->EvaluateAsInt(Align,
Context)) {
4099 const llvm::APSInt &I = Align.
Val.
getInt();
4100 if (!I.isPowerOf2())
4101 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4102 << Arg->getSourceRange();
4105 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4131 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4132 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4134 checkCall(FDecl, Proto,
nullptr, Args,
true,
4143 IsMemberOperatorCall;
4149 Expr *ImplicitThis =
nullptr;
4154 ImplicitThis = Args[0];
4157 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4168 ThisType =
Context.getPointerType(ThisType);
4174 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4192 CheckAbsoluteValueFunction(TheCall, FDecl);
4193 CheckMaxUnsignedZero(TheCall, FDecl);
4194 CheckInfNaNFunction(TheCall, FDecl);
4205 case Builtin::BIstrlcpy:
4206 case Builtin::BIstrlcat:
4207 CheckStrlcpycatArguments(TheCall, FnInfo);
4209 case Builtin::BIstrncat:
4210 CheckStrncatArguments(TheCall, FnInfo);
4212 case Builtin::BIfree:
4213 CheckFreeArguments(TheCall);
4216 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4225 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4226 Ty =
V->getType().getNonReferenceType();
4227 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4228 Ty = F->getType().getNonReferenceType();
4265 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4268 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4270 case AtomicExpr::AO__c11_atomic_init:
4271 case AtomicExpr::AO__opencl_atomic_init:
4272 llvm_unreachable(
"There is no ordering argument for an init");
4274 case AtomicExpr::AO__c11_atomic_load:
4275 case AtomicExpr::AO__opencl_atomic_load:
4276 case AtomicExpr::AO__hip_atomic_load:
4277 case AtomicExpr::AO__atomic_load_n:
4278 case AtomicExpr::AO__atomic_load:
4279 case AtomicExpr::AO__scoped_atomic_load_n:
4280 case AtomicExpr::AO__scoped_atomic_load:
4281 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4282 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4284 case AtomicExpr::AO__c11_atomic_store:
4285 case AtomicExpr::AO__opencl_atomic_store:
4286 case AtomicExpr::AO__hip_atomic_store:
4287 case AtomicExpr::AO__atomic_store:
4288 case AtomicExpr::AO__atomic_store_n:
4289 case AtomicExpr::AO__scoped_atomic_store:
4290 case AtomicExpr::AO__scoped_atomic_store_n:
4291 case AtomicExpr::AO__atomic_clear:
4292 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4293 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4294 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4353 const unsigned NumForm = ClearByte + 1;
4354 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4355 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4363 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4364 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4365 "need to update code for modified forms");
4366 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4367 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4368 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4369 "need to update code for modified C11 atomics");
4370 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4371 Op <= AtomicExpr::AO__opencl_atomic_store;
4372 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4373 Op <= AtomicExpr::AO__hip_atomic_store;
4374 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4375 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4376 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4377 Op <= AtomicExpr::AO__c11_atomic_store) ||
4379 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4380 Op == AtomicExpr::AO__atomic_store_n ||
4381 Op == AtomicExpr::AO__atomic_exchange_n ||
4382 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4383 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4384 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4385 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4386 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4390 enum ArithOpExtraValueType {
4395 unsigned ArithAllows = AOEVT_None;
4398 case AtomicExpr::AO__c11_atomic_init:
4399 case AtomicExpr::AO__opencl_atomic_init:
4403 case AtomicExpr::AO__c11_atomic_load:
4404 case AtomicExpr::AO__opencl_atomic_load:
4405 case AtomicExpr::AO__hip_atomic_load:
4406 case AtomicExpr::AO__atomic_load_n:
4407 case AtomicExpr::AO__scoped_atomic_load_n:
4411 case AtomicExpr::AO__atomic_load:
4412 case AtomicExpr::AO__scoped_atomic_load:
4416 case AtomicExpr::AO__c11_atomic_store:
4417 case AtomicExpr::AO__opencl_atomic_store:
4418 case AtomicExpr::AO__hip_atomic_store:
4419 case AtomicExpr::AO__atomic_store:
4420 case AtomicExpr::AO__atomic_store_n:
4421 case AtomicExpr::AO__scoped_atomic_store:
4422 case AtomicExpr::AO__scoped_atomic_store_n:
4425 case AtomicExpr::AO__atomic_fetch_add:
4426 case AtomicExpr::AO__atomic_fetch_sub:
4427 case AtomicExpr::AO__atomic_add_fetch:
4428 case AtomicExpr::AO__atomic_sub_fetch:
4429 case AtomicExpr::AO__scoped_atomic_fetch_add:
4430 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4431 case AtomicExpr::AO__scoped_atomic_add_fetch:
4432 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4433 case AtomicExpr::AO__c11_atomic_fetch_add:
4434 case AtomicExpr::AO__c11_atomic_fetch_sub:
4435 case AtomicExpr::AO__opencl_atomic_fetch_add:
4436 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4437 case AtomicExpr::AO__hip_atomic_fetch_add:
4438 case AtomicExpr::AO__hip_atomic_fetch_sub:
4439 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4442 case AtomicExpr::AO__atomic_fetch_max:
4443 case AtomicExpr::AO__atomic_fetch_min:
4444 case AtomicExpr::AO__atomic_max_fetch:
4445 case AtomicExpr::AO__atomic_min_fetch:
4446 case AtomicExpr::AO__scoped_atomic_fetch_max:
4447 case AtomicExpr::AO__scoped_atomic_fetch_min:
4448 case AtomicExpr::AO__scoped_atomic_max_fetch:
4449 case AtomicExpr::AO__scoped_atomic_min_fetch:
4450 case AtomicExpr::AO__c11_atomic_fetch_max:
4451 case AtomicExpr::AO__c11_atomic_fetch_min:
4452 case AtomicExpr::AO__opencl_atomic_fetch_max:
4453 case AtomicExpr::AO__opencl_atomic_fetch_min:
4454 case AtomicExpr::AO__hip_atomic_fetch_max:
4455 case AtomicExpr::AO__hip_atomic_fetch_min:
4456 ArithAllows = AOEVT_FP;
4459 case AtomicExpr::AO__c11_atomic_fetch_and:
4460 case AtomicExpr::AO__c11_atomic_fetch_or:
4461 case AtomicExpr::AO__c11_atomic_fetch_xor:
4462 case AtomicExpr::AO__hip_atomic_fetch_and:
4463 case AtomicExpr::AO__hip_atomic_fetch_or:
4464 case AtomicExpr::AO__hip_atomic_fetch_xor:
4465 case AtomicExpr::AO__c11_atomic_fetch_nand:
4466 case AtomicExpr::AO__opencl_atomic_fetch_and:
4467 case AtomicExpr::AO__opencl_atomic_fetch_or:
4468 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4469 case AtomicExpr::AO__atomic_fetch_and:
4470 case AtomicExpr::AO__atomic_fetch_or:
4471 case AtomicExpr::AO__atomic_fetch_xor:
4472 case AtomicExpr::AO__atomic_fetch_nand:
4473 case AtomicExpr::AO__atomic_and_fetch:
4474 case AtomicExpr::AO__atomic_or_fetch:
4475 case AtomicExpr::AO__atomic_xor_fetch:
4476 case AtomicExpr::AO__atomic_nand_fetch:
4477 case AtomicExpr::AO__scoped_atomic_fetch_and:
4478 case AtomicExpr::AO__scoped_atomic_fetch_or:
4479 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4480 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4481 case AtomicExpr::AO__scoped_atomic_and_fetch:
4482 case AtomicExpr::AO__scoped_atomic_or_fetch:
4483 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4484 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4485 case AtomicExpr::AO__scoped_atomic_uinc_wrap:
4486 case AtomicExpr::AO__scoped_atomic_udec_wrap:
4490 case AtomicExpr::AO__c11_atomic_exchange:
4491 case AtomicExpr::AO__hip_atomic_exchange:
4492 case AtomicExpr::AO__opencl_atomic_exchange:
4493 case AtomicExpr::AO__atomic_exchange_n:
4494 case AtomicExpr::AO__scoped_atomic_exchange_n:
4498 case AtomicExpr::AO__atomic_exchange:
4499 case AtomicExpr::AO__scoped_atomic_exchange:
4503 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4504 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4505 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4506 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4507 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4508 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4512 case AtomicExpr::AO__atomic_compare_exchange:
4513 case AtomicExpr::AO__atomic_compare_exchange_n:
4514 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4515 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4519 case AtomicExpr::AO__atomic_test_and_set:
4520 Form = TestAndSetByte;
4523 case AtomicExpr::AO__atomic_clear:
4528 unsigned AdjustedNumArgs = NumArgs[Form];
4529 if ((IsOpenCL || IsHIP || IsScoped) &&
4530 Op != AtomicExpr::AO__opencl_atomic_init)
4533 if (Args.size() < AdjustedNumArgs) {
4534 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4535 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4538 }
else if (Args.size() > AdjustedNumArgs) {
4539 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4540 diag::err_typecheck_call_too_many_args)
4541 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4547 Expr *Ptr = Args[0];
4552 Ptr = ConvertedPtr.
get();
4555 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4565 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4571 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4577 }
else if (Form != Load && Form != LoadCopy) {
4579 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4585 if (Form != TestAndSetByte && Form != ClearByte) {
4588 diag::err_incomplete_type))
4591 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4592 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4602 pointerType->getPointeeType().getCVRQualifiers());
4612 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4621 auto IsAllowedValueType = [&](
QualType ValType,
4622 unsigned AllowedType) ->
bool {
4626 return AllowedType & AOEVT_Pointer;
4631 &
Context.getTargetInfo().getLongDoubleFormat() ==
4632 &llvm::APFloat::x87DoubleExtended())
4636 if (!IsAllowedValueType(ValType, ArithAllows)) {
4637 auto DID = ArithAllows & AOEVT_FP
4638 ? (ArithAllows & AOEVT_Pointer
4639 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4640 : diag::err_atomic_op_needs_atomic_int_or_fp)
4641 : diag::err_atomic_op_needs_atomic_int;
4648 diag::err_incomplete_type)) {
4654 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4665 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4681 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4693 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4696 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4702 bool IsPassedByAddress =
false;
4703 if (!IsC11 && !IsHIP && !IsN) {
4705 IsPassedByAddress =
true;
4710 APIOrderedArgs.push_back(Args[0]);
4714 APIOrderedArgs.push_back(Args[1]);
4720 APIOrderedArgs.push_back(Args[2]);
4721 APIOrderedArgs.push_back(Args[1]);
4724 APIOrderedArgs.push_back(Args[2]);
4725 APIOrderedArgs.push_back(Args[3]);
4726 APIOrderedArgs.push_back(Args[1]);
4729 APIOrderedArgs.push_back(Args[2]);
4730 APIOrderedArgs.push_back(Args[4]);
4731 APIOrderedArgs.push_back(Args[1]);
4732 APIOrderedArgs.push_back(Args[3]);
4735 APIOrderedArgs.push_back(Args[2]);
4736 APIOrderedArgs.push_back(Args[4]);
4737 APIOrderedArgs.push_back(Args[5]);
4738 APIOrderedArgs.push_back(Args[1]);
4739 APIOrderedArgs.push_back(Args[3]);
4741 case TestAndSetByte:
4743 APIOrderedArgs.push_back(Args[1]);
4747 APIOrderedArgs.append(Args.begin(), Args.end());
4754 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4756 if (i < NumVals[Form] + 1) {
4769 assert(Form != Load);
4771 Ty =
Context.getPointerDiffType();
4774 else if (Form ==
Copy || Form == Xchg) {
4775 if (IsPassedByAddress) {
4782 Expr *ValArg = APIOrderedArgs[i];
4789 AS = PtrTy->getPointeeType().getAddressSpace();
4798 if (IsPassedByAddress)
4818 APIOrderedArgs[i] = Arg.
get();
4823 SubExprs.push_back(Ptr);
4827 SubExprs.push_back(APIOrderedArgs[1]);
4830 case TestAndSetByte:
4832 SubExprs.push_back(APIOrderedArgs[1]);
4838 SubExprs.push_back(APIOrderedArgs[2]);
4839 SubExprs.push_back(APIOrderedArgs[1]);
4843 SubExprs.push_back(APIOrderedArgs[3]);
4844 SubExprs.push_back(APIOrderedArgs[1]);
4845 SubExprs.push_back(APIOrderedArgs[2]);
4848 SubExprs.push_back(APIOrderedArgs[3]);
4849 SubExprs.push_back(APIOrderedArgs[1]);
4850 SubExprs.push_back(APIOrderedArgs[4]);
4851 SubExprs.push_back(APIOrderedArgs[2]);
4854 SubExprs.push_back(APIOrderedArgs[4]);
4855 SubExprs.push_back(APIOrderedArgs[1]);
4856 SubExprs.push_back(APIOrderedArgs[5]);
4857 SubExprs.push_back(APIOrderedArgs[2]);
4858 SubExprs.push_back(APIOrderedArgs[3]);
4863 if (SubExprs.size() >= 2 && Form !=
Init) {
4864 std::optional<llvm::APSInt>
Success =
4865 SubExprs[1]->getIntegerConstantExpr(
Context);
4867 Diag(SubExprs[1]->getBeginLoc(),
4868 diag::warn_atomic_op_has_invalid_memory_order)
4869 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4870 << SubExprs[1]->getSourceRange();
4872 if (SubExprs.size() >= 5) {
4873 if (std::optional<llvm::APSInt> Failure =
4874 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4875 if (!llvm::is_contained(
4876 {llvm::AtomicOrderingCABI::relaxed,
4877 llvm::AtomicOrderingCABI::consume,
4878 llvm::AtomicOrderingCABI::acquire,
4879 llvm::AtomicOrderingCABI::seq_cst},
4880 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4881 Diag(SubExprs[3]->getBeginLoc(),
4882 diag::warn_atomic_op_has_invalid_memory_order)
4883 << 2 << SubExprs[3]->getSourceRange();
4890 auto *
Scope = Args[Args.size() - 1];
4891 if (std::optional<llvm::APSInt>
Result =
4893 if (!ScopeModel->isValid(
Result->getZExtValue()))
4894 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4895 <<
Scope->getSourceRange();
4897 SubExprs.push_back(
Scope);
4903 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4904 Op == AtomicExpr::AO__c11_atomic_store ||
4905 Op == AtomicExpr::AO__opencl_atomic_load ||
4906 Op == AtomicExpr::AO__hip_atomic_load ||
4907 Op == AtomicExpr::AO__opencl_atomic_store ||
4908 Op == AtomicExpr::AO__hip_atomic_store) &&
4909 Context.AtomicUsesUnsupportedLibcall(AE))
4911 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4912 Op == AtomicExpr::AO__opencl_atomic_load ||
4913 Op == AtomicExpr::AO__hip_atomic_load)
4918 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4934 assert(Fn &&
"builtin call without direct callee!");
4950 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4957 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4959 <<
Callee->getSourceRange();
4968 Expr *FirstArg = TheCall->
getArg(0);
4972 FirstArg = FirstArgResult.
get();
4973 TheCall->
setArg(0, FirstArg);
4985 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4992 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5022 QualType ResultType = ValType;
5027#define BUILTIN_ROW(x) \
5028 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5029 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5031 static const unsigned BuiltinIndices[][5] = {
5056 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5057 case 1: SizeIndex = 0;
break;
5058 case 2: SizeIndex = 1;
break;
5059 case 4: SizeIndex = 2;
break;
5060 case 8: SizeIndex = 3;
break;
5061 case 16: SizeIndex = 4;
break;
5073 unsigned BuiltinIndex, NumFixed = 1;
5074 bool WarnAboutSemanticsChange =
false;
5075 switch (BuiltinID) {
5076 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5077 case Builtin::BI__sync_fetch_and_add:
5078 case Builtin::BI__sync_fetch_and_add_1:
5079 case Builtin::BI__sync_fetch_and_add_2:
5080 case Builtin::BI__sync_fetch_and_add_4:
5081 case Builtin::BI__sync_fetch_and_add_8:
5082 case Builtin::BI__sync_fetch_and_add_16:
5086 case Builtin::BI__sync_fetch_and_sub:
5087 case Builtin::BI__sync_fetch_and_sub_1:
5088 case Builtin::BI__sync_fetch_and_sub_2:
5089 case Builtin::BI__sync_fetch_and_sub_4:
5090 case Builtin::BI__sync_fetch_and_sub_8:
5091 case Builtin::BI__sync_fetch_and_sub_16:
5095 case Builtin::BI__sync_fetch_and_or:
5096 case Builtin::BI__sync_fetch_and_or_1:
5097 case Builtin::BI__sync_fetch_and_or_2:
5098 case Builtin::BI__sync_fetch_and_or_4:
5099 case Builtin::BI__sync_fetch_and_or_8:
5100 case Builtin::BI__sync_fetch_and_or_16:
5104 case Builtin::BI__sync_fetch_and_and:
5105 case Builtin::BI__sync_fetch_and_and_1:
5106 case Builtin::BI__sync_fetch_and_and_2:
5107 case Builtin::BI__sync_fetch_and_and_4:
5108 case Builtin::BI__sync_fetch_and_and_8:
5109 case Builtin::BI__sync_fetch_and_and_16:
5113 case Builtin::BI__sync_fetch_and_xor:
5114 case Builtin::BI__sync_fetch_and_xor_1:
5115 case Builtin::BI__sync_fetch_and_xor_2:
5116 case Builtin::BI__sync_fetch_and_xor_4:
5117 case Builtin::BI__sync_fetch_and_xor_8:
5118 case Builtin::BI__sync_fetch_and_xor_16:
5122 case Builtin::BI__sync_fetch_and_nand:
5123 case Builtin::BI__sync_fetch_and_nand_1:
5124 case Builtin::BI__sync_fetch_and_nand_2:
5125 case Builtin::BI__sync_fetch_and_nand_4:
5126 case Builtin::BI__sync_fetch_and_nand_8:
5127 case Builtin::BI__sync_fetch_and_nand_16:
5129 WarnAboutSemanticsChange =
true;
5132 case Builtin::BI__sync_add_and_fetch:
5133 case Builtin::BI__sync_add_and_fetch_1:
5134 case Builtin::BI__sync_add_and_fetch_2:
5135 case Builtin::BI__sync_add_and_fetch_4:
5136 case Builtin::BI__sync_add_and_fetch_8:
5137 case Builtin::BI__sync_add_and_fetch_16:
5141 case Builtin::BI__sync_sub_and_fetch:
5142 case Builtin::BI__sync_sub_and_fetch_1:
5143 case Builtin::BI__sync_sub_and_fetch_2:
5144 case Builtin::BI__sync_sub_and_fetch_4:
5145 case Builtin::BI__sync_sub_and_fetch_8:
5146 case Builtin::BI__sync_sub_and_fetch_16:
5150 case Builtin::BI__sync_and_and_fetch:
5151 case Builtin::BI__sync_and_and_fetch_1:
5152 case Builtin::BI__sync_and_and_fetch_2:
5153 case Builtin::BI__sync_and_and_fetch_4:
5154 case Builtin::BI__sync_and_and_fetch_8:
5155 case Builtin::BI__sync_and_and_fetch_16:
5159 case Builtin::BI__sync_or_and_fetch:
5160 case Builtin::BI__sync_or_and_fetch_1:
5161 case Builtin::BI__sync_or_and_fetch_2:
5162 case Builtin::BI__sync_or_and_fetch_4:
5163 case Builtin::BI__sync_or_and_fetch_8:
5164 case Builtin::BI__sync_or_and_fetch_16:
5168 case Builtin::BI__sync_xor_and_fetch:
5169 case Builtin::BI__sync_xor_and_fetch_1:
5170 case Builtin::BI__sync_xor_and_fetch_2:
5171 case Builtin::BI__sync_xor_and_fetch_4:
5172 case Builtin::BI__sync_xor_and_fetch_8:
5173 case Builtin::BI__sync_xor_and_fetch_16:
5177 case Builtin::BI__sync_nand_and_fetch:
5178 case Builtin::BI__sync_nand_and_fetch_1:
5179 case Builtin::BI__sync_nand_and_fetch_2:
5180 case Builtin::BI__sync_nand_and_fetch_4:
5181 case Builtin::BI__sync_nand_and_fetch_8:
5182 case Builtin::BI__sync_nand_and_fetch_16:
5184 WarnAboutSemanticsChange =
true;
5187 case Builtin::BI__sync_val_compare_and_swap:
5188 case Builtin::BI__sync_val_compare_and_swap_1:
5189 case Builtin::BI__sync_val_compare_and_swap_2:
5190 case Builtin::BI__sync_val_compare_and_swap_4:
5191 case Builtin::BI__sync_val_compare_and_swap_8:
5192 case Builtin::BI__sync_val_compare_and_swap_16:
5197 case Builtin::BI__sync_bool_compare_and_swap:
5198 case Builtin::BI__sync_bool_compare_and_swap_1:
5199 case Builtin::BI__sync_bool_compare_and_swap_2:
5200 case Builtin::BI__sync_bool_compare_and_swap_4:
5201 case Builtin::BI__sync_bool_compare_and_swap_8:
5202 case Builtin::BI__sync_bool_compare_and_swap_16:
5208 case Builtin::BI__sync_lock_test_and_set:
5209 case Builtin::BI__sync_lock_test_and_set_1:
5210 case Builtin::BI__sync_lock_test_and_set_2:
5211 case Builtin::BI__sync_lock_test_and_set_4:
5212 case Builtin::BI__sync_lock_test_and_set_8:
5213 case Builtin::BI__sync_lock_test_and_set_16:
5217 case Builtin::BI__sync_lock_release:
5218 case Builtin::BI__sync_lock_release_1:
5219 case Builtin::BI__sync_lock_release_2:
5220 case Builtin::BI__sync_lock_release_4:
5221 case Builtin::BI__sync_lock_release_8:
5222 case Builtin::BI__sync_lock_release_16:
5228 case Builtin::BI__sync_swap:
5229 case Builtin::BI__sync_swap_1:
5230 case Builtin::BI__sync_swap_2:
5231 case Builtin::BI__sync_swap_4:
5232 case Builtin::BI__sync_swap_8:
5233 case Builtin::BI__sync_swap_16:
5241 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5242 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5243 <<
Callee->getSourceRange();
5247 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5248 <<
Callee->getSourceRange();
5250 if (WarnAboutSemanticsChange) {
5251 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5252 <<
Callee->getSourceRange();
5257 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5258 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5259 FunctionDecl *NewBuiltinDecl;
5260 if (NewBuiltinID == BuiltinID)
5261 NewBuiltinDecl = FDecl;
5264 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5267 assert(Res.getFoundDecl());
5268 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5269 if (!NewBuiltinDecl)
5276 for (
unsigned i = 0; i != NumFixed; ++i) {
5305 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5307 CK_BuiltinFnToFnPtr);
5318 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5319 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5320 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5324 return TheCallResult;
5328 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5333 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5334 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5335 "Unexpected nontemporal load/store builtin!");
5336 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5337 unsigned numArgs = isStore ? 2 : 1;
5347 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5353 PointerArg = PointerArgResult.
get();
5354 TheCall->
setArg(numArgs - 1, PointerArg);
5358 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5371 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5378 return TheCallResult;
5390 return TheCallResult;
5397 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5399 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5400 Literal = ObjcLiteral->getString();
5404 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5411 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5412 InitializedEntity Entity =
5422 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5423 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5424 TT.getArch() == llvm::Triple::aarch64_32);
5425 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5426 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5427 if (IsX64 || IsAArch64) {
5434 return S.
Diag(Fn->getBeginLoc(),
5435 diag::err_ms_va_start_used_in_sysv_function);
5442 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5443 return S.
Diag(Fn->getBeginLoc(),
5444 diag::err_va_start_used_in_wrong_abi_function)
5445 << !IsWindowsOrUEFI;
5451 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5459 bool IsVariadic =
false;
5462 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5463 IsVariadic =
Block->isVariadic();
5464 Params =
Block->parameters();
5465 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5468 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5469 IsVariadic = MD->isVariadic();
5471 Params = MD->parameters();
5474 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5478 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5483 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5488 *LastParam = Params.empty() ?
nullptr : Params.back();
5493bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5498 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5522 ParmVarDecl *LastParam;
5533 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5535 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5540 if (std::optional<llvm::APSInt> Val =
5542 Val &&
LangOpts.C23 && *Val == 0 &&
5543 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5544 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5551 SourceLocation ParamLoc;
5552 bool IsCRegister =
false;
5553 bool SecondArgIsLastNonVariadicArgument =
false;
5554 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5555 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5556 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5559 ParamLoc = PV->getLocation();
5565 if (!SecondArgIsLastNonVariadicArgument)
5567 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5568 else if (IsCRegister ||
Type->isReferenceType() ||
5569 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5572 if (!Context.isPromotableIntegerType(Type))
5574 const auto *ED = Type->getAsEnumDecl();
5577 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5579 unsigned Reason = 0;
5580 if (
Type->isReferenceType()) Reason = 1;
5581 else if (IsCRegister) Reason = 2;
5582 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5583 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5590 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5610 if (
Call->getNumArgs() < 3)
5612 diag::err_typecheck_call_too_few_args_at_least)
5613 << 0 << 3 <<
Call->getNumArgs()
5626 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5629 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5632 const QualType &ConstCharPtrTy =
5634 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5636 << Arg1->
getType() << ConstCharPtrTy << 1
5639 << 2 << Arg1->
getType() << ConstCharPtrTy;
5641 const QualType SizeTy =
Context.getSizeType();
5646 << Arg2->
getType() << SizeTy << 1
5649 << 3 << Arg2->
getType() << SizeTy;
5654bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5658 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5686 diag::err_typecheck_call_invalid_ordered_compare)
5694bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5695 unsigned BuiltinID) {
5700 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5701 BuiltinID == Builtin::BI__builtin_isinf ||
5702 BuiltinID == Builtin::BI__builtin_isinf_sign))
5706 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5707 BuiltinID == Builtin::BI__builtin_isunordered))
5711 bool IsFPClass = NumArgs == 2;
5714 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5718 for (
unsigned i = 0; i < FPArgNo; ++i) {
5719 Expr *Arg = TheCall->
getArg(i);
5732 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5740 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5745 OrigArg = Res.
get();
5751 OrigArg = Res.
get();
5753 TheCall->
setArg(FPArgNo, OrigArg);
5755 QualType VectorResultTy;
5756 QualType ElementTy = OrigArg->
getType();
5761 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5767 diag::err_typecheck_call_invalid_unary_fp)
5779 if (!VectorResultTy.
isNull())
5780 ResultTy = VectorResultTy;
5789bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5794 for (
unsigned I = 0; I != 2; ++I) {
5795 Expr *Arg = TheCall->
getArg(I);
5805 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5820 Expr *Real = TheCall->
getArg(0);
5821 Expr *Imag = TheCall->
getArg(1);
5824 diag::err_typecheck_call_different_arg_types)
5839 diag::err_typecheck_call_too_few_args_at_least)
5840 << 0 << 2 << NumArgs
5847 unsigned NumElements = 0;
5862 unsigned NumResElements = NumArgs - 2;
5871 diag::err_vec_builtin_incompatible_vector)
5876 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5878 diag::err_vec_builtin_incompatible_vector)
5883 }
else if (NumElements != NumResElements) {
5886 ?
Context.getExtVectorType(EltType, NumResElements)
5887 :
Context.getVectorType(EltType, NumResElements,
5892 for (
unsigned I = 2; I != NumArgs; ++I) {
5900 diag::err_shufflevector_nonconstant_argument)
5906 else if (
Result->getActiveBits() > 64 ||
5907 Result->getZExtValue() >= NumElements * 2)
5909 diag::err_shufflevector_argument_too_large)
5934 diag::err_convertvector_non_vector)
5937 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5939 <<
"__builtin_convertvector");
5944 if (SrcElts != DstElts)
5946 diag::err_convertvector_incompatible_vector)
5954bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5959 diag::err_typecheck_call_too_many_args_at_most)
5960 << 0 << 3 << NumArgs << 0
5965 for (
unsigned i = 1; i != NumArgs; ++i)
5972bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5973 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5974 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5984 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5994bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5995 Expr *Arg = TheCall->
getArg(0);
6006bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6008 Expr *Arg = TheCall->
getArg(1);
6012 if (
const auto *UE =
6014 if (UE->getKind() == UETT_AlignOf ||
6015 UE->getKind() == UETT_PreferredAlignOf)
6021 if (!
Result.isPowerOf2())
6022 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6029 if (
Result > std::numeric_limits<int32_t>::max())
6037bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6042 Expr *FirstArg = TheCall->
getArg(0);
6048 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6052 TheCall->
setArg(0, FirstArgResult.
get());
6056 Expr *SecondArg = TheCall->
getArg(1);
6064 if (!
Result.isPowerOf2())
6065 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6077 Expr *ThirdArg = TheCall->
getArg(2);
6080 TheCall->
setArg(2, ThirdArg);
6086bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6087 unsigned BuiltinID =
6089 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6092 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6093 if (NumArgs < NumRequiredArgs) {
6094 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6095 << 0 << NumRequiredArgs << NumArgs
6098 if (NumArgs >= NumRequiredArgs + 0x100) {
6100 diag::err_typecheck_call_too_many_args_at_most)
6101 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6112 if (Arg.isInvalid())
6114 TheCall->
setArg(i, Arg.get());
6119 unsigned FormatIdx = i;
6129 unsigned FirstDataArg = i;
6130 while (i < NumArgs) {
6148 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6150 bool Success = CheckFormatArguments(
6153 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6177 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6186 int High,
bool RangeIsError) {
6200 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6208 PDiag(diag::warn_argument_invalid_range)
6251 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6256 if (
Value.isNegative())
6267 if ((
Value & 0xFF) != 0)
6292 Result.setIsUnsigned(
true);
6297 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6317 Result.setIsUnsigned(
true);
6325 diag::err_argument_not_shifted_byte_or_xxff)
6329bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6330 if (!Context.getTargetInfo().hasSjLjLowering())
6331 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6342 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6348bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6349 if (!Context.getTargetInfo().hasSjLjLowering())
6350 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6355bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6370 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6375 diag::err_builtin_counted_by_ref_has_side_effects)
6378 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6379 if (!ME->isFlexibleArrayMemberLike(
6382 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6386 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6389 if (
const FieldDecl *CountFD = FAMDecl->findCountedByField()) {
6396 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6406bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6408 const CallExpr *CE =
6417 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6422 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6427 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6431 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6435 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6445class UncoveredArgHandler {
6446 enum {
Unknown = -1, AllCovered = -2 };
6448 signed FirstUncoveredArg =
Unknown;
6449 SmallVector<const Expr *, 4> DiagnosticExprs;
6452 UncoveredArgHandler() =
default;
6454 bool hasUncoveredArg()
const {
6455 return (FirstUncoveredArg >= 0);
6458 unsigned getUncoveredArg()
const {
6459 assert(hasUncoveredArg() &&
"no uncovered argument");
6460 return FirstUncoveredArg;
6463 void setAllCovered() {
6466 DiagnosticExprs.clear();
6467 FirstUncoveredArg = AllCovered;
6470 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6471 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6474 if (FirstUncoveredArg == AllCovered)
6479 if (NewFirstUncoveredArg == FirstUncoveredArg)
6480 DiagnosticExprs.push_back(StrExpr);
6481 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6482 DiagnosticExprs.clear();
6483 DiagnosticExprs.push_back(StrExpr);
6484 FirstUncoveredArg = NewFirstUncoveredArg;
6488 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6491enum StringLiteralCheckType {
6493 SLCT_UncheckedLiteral,
6501 bool AddendIsRight) {
6502 unsigned BitWidth = Offset.getBitWidth();
6503 unsigned AddendBitWidth = Addend.getBitWidth();
6505 if (Addend.isUnsigned()) {
6506 Addend = Addend.zext(++AddendBitWidth);
6507 Addend.setIsSigned(
true);
6510 if (AddendBitWidth > BitWidth) {
6511 Offset = Offset.sext(AddendBitWidth);
6512 BitWidth = AddendBitWidth;
6513 }
else if (BitWidth > AddendBitWidth) {
6514 Addend = Addend.sext(BitWidth);
6518 llvm::APSInt ResOffset = Offset;
6519 if (BinOpKind == BO_Add)
6520 ResOffset = Offset.sadd_ov(Addend, Ov);
6522 assert(AddendIsRight && BinOpKind == BO_Sub &&
6523 "operator must be add or sub with addend on the right");
6524 ResOffset = Offset.ssub_ov(Addend, Ov);
6530 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6531 "index (intermediate) result too big");
6532 Offset = Offset.sext(2 * BitWidth);
6533 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6545class FormatStringLiteral {
6546 const StringLiteral *FExpr;
6550 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6551 : FExpr(fexpr), Offset(Offset) {}
6553 const StringLiteral *getFormatString()
const {
return FExpr; }
6555 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6557 unsigned getByteLength()
const {
6558 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6561 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6568 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6569 bool isWide()
const {
return FExpr->
isWide(); }
6570 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6571 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6572 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6573 bool isPascal()
const {
return FExpr->
isPascal(); }
6575 SourceLocation getLocationOfByte(
6576 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6577 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6578 unsigned *StartTokenByteOffset =
nullptr)
const {
6580 StartToken, StartTokenByteOffset);
6583 SourceLocation getBeginLoc() const LLVM_READONLY {
6587 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6593 Sema &S,
const FormatStringLiteral *FExpr,
6598 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6599 bool IgnoreStringsWithoutSpecifiers);
6613 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6614 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6616 return SLCT_NotALiteral;
6618 assert(Offset.isSigned() &&
"invalid offset");
6621 return SLCT_NotALiteral;
6630 return SLCT_UncheckedLiteral;
6633 case Stmt::InitListExprClass:
6637 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6638 Type, CallType,
false, CheckedVarArgs,
6639 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6641 return SLCT_NotALiteral;
6642 case Stmt::BinaryConditionalOperatorClass:
6643 case Stmt::ConditionalOperatorClass: {
6652 bool CheckLeft =
true, CheckRight =
true;
6655 if (
C->getCond()->EvaluateAsBooleanCondition(
6667 StringLiteralCheckType Left;
6669 Left = SLCT_UncheckedLiteral;
6672 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6673 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6674 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6675 if (Left == SLCT_NotALiteral || !CheckRight) {
6681 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6682 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6683 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6685 return (CheckLeft && Left < Right) ? Left : Right;
6688 case Stmt::ImplicitCastExprClass:
6692 case Stmt::OpaqueValueExprClass:
6697 return SLCT_NotALiteral;
6699 case Stmt::PredefinedExprClass:
6703 return SLCT_UncheckedLiteral;
6705 case Stmt::DeclRefExprClass: {
6711 bool isConstant =
false;
6715 isConstant = AT->getElementType().isConstant(S.
Context);
6717 isConstant =
T.isConstant(S.
Context) &&
6718 PT->getPointeeType().isConstant(S.
Context);
6719 }
else if (
T->isObjCObjectPointerType()) {
6722 isConstant =
T.isConstant(S.
Context);
6726 if (
const Expr *
Init = VD->getAnyInitializer()) {
6729 if (InitList->isStringLiteralInit())
6730 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6733 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6734 firstDataArg,
Type, CallType,
6735 false, CheckedVarArgs, UncoveredArg, Offset);
6786 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6787 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6788 for (
const auto *PVFormatMatches :
6789 D->specific_attrs<FormatMatchesAttr>()) {
6794 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6798 S.
Diag(Args[format_idx]->getBeginLoc(),
6799 diag::warn_format_string_type_incompatible)
6800 << PVFormatMatches->getType()->getName()
6802 if (!InFunctionCall) {
6803 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6804 diag::note_format_string_defined);
6806 return SLCT_UncheckedLiteral;
6809 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6810 Args, APK, format_idx, firstDataArg,
Type, CallType,
6811 false, CheckedVarArgs, UncoveredArg,
6812 Offset, IgnoreStringsWithoutSpecifiers);
6816 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6819 PVFormat->getFirstArg(), &CallerFSI))
6821 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6825 S.
Diag(Args[format_idx]->getBeginLoc(),
6826 diag::warn_format_string_type_incompatible)
6827 << PVFormat->getType()->getName()
6829 if (!InFunctionCall) {
6832 return SLCT_UncheckedLiteral;
6845 return SLCT_UncheckedLiteral;
6853 return SLCT_NotALiteral;
6856 case Stmt::CallExprClass:
6857 case Stmt::CXXMemberCallExprClass: {
6861 StringLiteralCheckType CommonResult;
6862 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6863 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6865 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6866 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6867 Offset, IgnoreStringsWithoutSpecifiers);
6869 CommonResult = Result;
6874 return CommonResult;
6876 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6878 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6879 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6882 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6883 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6884 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6890 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6891 Type, CallType,
false, CheckedVarArgs,
6892 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6893 return SLCT_NotALiteral;
6895 case Stmt::ObjCMessageExprClass: {
6897 if (
const auto *MD = ME->getMethodDecl()) {
6898 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6907 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6909 MD->getSelector().isKeywordSelector(
6910 {
"localizedStringForKey",
"value",
"table"})) {
6911 IgnoreStringsWithoutSpecifiers =
true;
6914 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6916 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6917 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6918 Offset, IgnoreStringsWithoutSpecifiers);
6922 return SLCT_NotALiteral;
6924 case Stmt::ObjCStringLiteralClass:
6925 case Stmt::StringLiteralClass: {
6934 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6937 return SLCT_NotALiteral;
6939 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6941 format_idx, firstDataArg,
Type, InFunctionCall,
6942 CallType, CheckedVarArgs, UncoveredArg,
6943 IgnoreStringsWithoutSpecifiers);
6944 return SLCT_CheckedLiteral;
6947 return SLCT_NotALiteral;
6949 case Stmt::BinaryOperatorClass: {
6963 if (LIsInt != RIsInt) {
6967 if (BinOpKind == BO_Add) {
6980 return SLCT_NotALiteral;
6982 case Stmt::UnaryOperatorClass: {
6984 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6985 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6987 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6997 return SLCT_NotALiteral;
7001 return SLCT_NotALiteral;
7012 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7013 if (isa_and_nonnull<StringLiteral>(LVE))
7034 return "freebsd_kprintf";
7043 return llvm::StringSwitch<FormatStringType>(Flavor)
7045 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7050 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7066bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7070 llvm::SmallBitVector &CheckedVarArgs) {
7071 FormatStringInfo FSI;
7075 return CheckFormatArguments(
7076 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7081bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7085 llvm::SmallBitVector &CheckedVarArgs) {
7086 FormatStringInfo FSI;
7090 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7091 Format->getFormatString(), FSI.FormatIdx,
7093 CallType, Loc, Range, CheckedVarArgs);
7101 unsigned format_idx,
unsigned firstDataArg,
7105 llvm::SmallBitVector &CheckedVarArgs) {
7107 if (format_idx >= Args.size()) {
7108 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7112 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7126 UncoveredArgHandler UncoveredArg;
7128 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7129 firstDataArg,
Type, CallType,
7130 true, CheckedVarArgs, UncoveredArg,
7131 llvm::APSInt(64,
false) = 0);
7134 if (UncoveredArg.hasUncoveredArg()) {
7135 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7136 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7137 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7140 if (CT != SLCT_NotALiteral)
7142 return CT == SLCT_CheckedLiteral;
7153 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7160 if (Args.size() == firstDataArg) {
7161 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7169 Diag(FormatLoc, diag::note_format_security_fixit)
7173 Diag(FormatLoc, diag::note_format_security_fixit)
7178 Diag(FormatLoc, diag::warn_format_nonliteral)
7189 const FormatStringLiteral *FExpr;
7190 const Expr *OrigFormatExpr;
7192 const unsigned FirstDataArg;
7193 const unsigned NumDataArgs;
7196 ArrayRef<const Expr *> Args;
7198 llvm::SmallBitVector CoveredArgs;
7199 bool usesPositionalArgs =
false;
7200 bool atFirstArg =
true;
7201 bool inFunctionCall;
7203 llvm::SmallBitVector &CheckedVarArgs;
7204 UncoveredArgHandler &UncoveredArg;
7207 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7209 unsigned firstDataArg,
unsigned numDataArgs,
7211 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7213 llvm::SmallBitVector &CheckedVarArgs,
7214 UncoveredArgHandler &UncoveredArg)
7215 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7216 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7217 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7218 inFunctionCall(inFunctionCall), CallType(callType),
7219 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7220 CoveredArgs.resize(numDataArgs);
7221 CoveredArgs.reset();
7224 bool HasFormatArguments()
const {
7229 void DoneProcessing();
7231 void HandleIncompleteSpecifier(
const char *startSpecifier,
7232 unsigned specifierLen)
override;
7234 void HandleInvalidLengthModifier(
7235 const analyze_format_string::FormatSpecifier &FS,
7236 const analyze_format_string::ConversionSpecifier &CS,
7237 const char *startSpecifier,
unsigned specifierLen,
7240 void HandleNonStandardLengthModifier(
7241 const analyze_format_string::FormatSpecifier &FS,
7242 const char *startSpecifier,
unsigned specifierLen);
7244 void HandleNonStandardConversionSpecifier(
7245 const analyze_format_string::ConversionSpecifier &CS,
7246 const char *startSpecifier,
unsigned specifierLen);
7248 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7250 void HandleInvalidPosition(
const char *startSpecifier,
7251 unsigned specifierLen,
7254 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7256 void HandleNullChar(
const char *nullCharacter)
override;
7258 template <
typename Range>
7260 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7261 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7262 bool IsStringLocation, Range StringRange,
7263 ArrayRef<FixItHint> Fixit = {});
7266 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7267 const char *startSpec,
7268 unsigned specifierLen,
7269 const char *csStart,
unsigned csLen);
7271 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7272 const char *startSpec,
7273 unsigned specifierLen);
7275 SourceRange getFormatStringRange();
7276 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7277 unsigned specifierLen);
7278 SourceLocation getLocationOfByte(
const char *x);
7280 const Expr *getDataArg(
unsigned i)
const;
7282 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7283 const analyze_format_string::ConversionSpecifier &CS,
7284 const char *startSpecifier,
unsigned specifierLen,
7287 template <
typename Range>
7288 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7289 bool IsStringLocation, Range StringRange,
7290 ArrayRef<FixItHint> Fixit = {});
7295SourceRange CheckFormatHandler::getFormatStringRange() {
7300getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7302 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7310SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7315void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7316 unsigned specifierLen){
7317 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7318 getLocationOfByte(startSpecifier),
7320 getSpecifierRange(startSpecifier, specifierLen));
7323void CheckFormatHandler::HandleInvalidLengthModifier(
7326 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7338 getSpecifierRange(startSpecifier, specifierLen));
7340 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7341 << FixedLM->toString()
7346 if (DiagID == diag::warn_format_nonsensical_length)
7352 getSpecifierRange(startSpecifier, specifierLen),
7357void CheckFormatHandler::HandleNonStandardLengthModifier(
7359 const char *startSpecifier,
unsigned specifierLen) {
7368 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7372 getSpecifierRange(startSpecifier, specifierLen));
7374 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7375 << FixedLM->toString()
7379 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7383 getSpecifierRange(startSpecifier, specifierLen));
7387void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7389 const char *startSpecifier,
unsigned specifierLen) {
7395 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7399 getSpecifierRange(startSpecifier, specifierLen));
7402 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7403 << FixedCS->toString()
7406 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7410 getSpecifierRange(startSpecifier, specifierLen));
7414void CheckFormatHandler::HandlePosition(
const char *startPos,
7417 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7418 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7419 getLocationOfByte(startPos),
7421 getSpecifierRange(startPos, posLen));
7424void CheckFormatHandler::HandleInvalidPosition(
7425 const char *startSpecifier,
unsigned specifierLen,
7428 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7429 EmitFormatDiagnostic(
7430 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7431 getLocationOfByte(startSpecifier),
true,
7432 getSpecifierRange(startSpecifier, specifierLen));
7435void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7439 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7440 getLocationOfByte(startPos),
7442 getSpecifierRange(startPos, posLen));
7445void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7448 EmitFormatDiagnostic(
7449 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7450 getLocationOfByte(nullCharacter),
true,
7451 getFormatStringRange());
7457const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7458 return Args[FirstDataArg + i];
7461void CheckFormatHandler::DoneProcessing() {
7464 if (HasFormatArguments()) {
7467 signed notCoveredArg = CoveredArgs.find_first();
7468 if (notCoveredArg >= 0) {
7469 assert((
unsigned)notCoveredArg < NumDataArgs);
7470 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7472 UncoveredArg.setAllCovered();
7477void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7478 const Expr *ArgExpr) {
7479 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7491 for (
auto E : DiagnosticExprs)
7494 CheckFormatHandler::EmitFormatDiagnostic(
7495 S, IsFunctionCall, DiagnosticExprs[0],
7501CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7503 const char *startSpec,
7504 unsigned specifierLen,
7505 const char *csStart,
7507 bool keepGoing =
true;
7508 if (argIndex < NumDataArgs) {
7511 CoveredArgs.set(argIndex);
7527 std::string CodePointStr;
7528 if (!llvm::sys::locale::isPrint(*csStart)) {
7529 llvm::UTF32 CodePoint;
7530 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7531 const llvm::UTF8 *E =
7532 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7533 llvm::ConversionResult
Result =
7534 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7536 if (
Result != llvm::conversionOK) {
7537 unsigned char FirstChar = *csStart;
7538 CodePoint = (llvm::UTF32)FirstChar;
7541 llvm::raw_string_ostream
OS(CodePointStr);
7542 if (CodePoint < 256)
7543 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7544 else if (CodePoint <= 0xFFFF)
7545 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7547 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7551 EmitFormatDiagnostic(
7552 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7553 true, getSpecifierRange(startSpec, specifierLen));
7559CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7560 const char *startSpec,
7561 unsigned specifierLen) {
7562 EmitFormatDiagnostic(
7563 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7564 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7568CheckFormatHandler::CheckNumArgs(
7571 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7573 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7575 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7576 << (argIndex+1) << NumDataArgs)
7577 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7578 EmitFormatDiagnostic(
7579 PDiag, getLocationOfByte(CS.
getStart()),
true,
7580 getSpecifierRange(startSpecifier, specifierLen));
7584 UncoveredArg.setAllCovered();
7590template<
typename Range>
7593 bool IsStringLocation,
7596 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7597 Loc, IsStringLocation, StringRange, FixIt);
7627template <
typename Range>
7628void CheckFormatHandler::EmitFormatDiagnostic(
7629 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7632 if (InFunctionCall) {
7637 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7641 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7642 diag::note_format_string_defined);
7644 Note << StringRange;
7653class CheckPrintfHandler :
public CheckFormatHandler {
7655 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7657 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7659 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7661 llvm::SmallBitVector &CheckedVarArgs,
7662 UncoveredArgHandler &UncoveredArg)
7663 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7664 numDataArgs, beg, APK, Args, formatIdx,
7665 inFunctionCall, CallType, CheckedVarArgs,
7668 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7671 bool allowsObjCArg()
const {
7672 return FSType == FormatStringType::NSString ||
7673 FSType == FormatStringType::OSLog ||
7674 FSType == FormatStringType::OSTrace;
7677 bool HandleInvalidPrintfConversionSpecifier(
7678 const analyze_printf::PrintfSpecifier &FS,
7679 const char *startSpecifier,
7680 unsigned specifierLen)
override;
7682 void handleInvalidMaskType(StringRef MaskType)
override;
7684 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7685 const char *startSpecifier,
unsigned specifierLen,
7686 const TargetInfo &
Target)
override;
7687 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7688 const char *StartSpecifier,
7689 unsigned SpecifierLen,
7692 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7693 const char *startSpecifier,
unsigned specifierLen);
7694 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7695 const analyze_printf::OptionalAmount &Amt,
7697 const char *startSpecifier,
unsigned specifierLen);
7698 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7699 const analyze_printf::OptionalFlag &flag,
7700 const char *startSpecifier,
unsigned specifierLen);
7701 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7702 const analyze_printf::OptionalFlag &ignoredFlag,
7703 const analyze_printf::OptionalFlag &flag,
7704 const char *startSpecifier,
unsigned specifierLen);
7705 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7708 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7709 unsigned flagLen)
override;
7711 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7712 unsigned flagLen)
override;
7715 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7716 const char *flagsEnd,
7717 const char *conversionPosition)
override;
7722class EquatableFormatArgument {
7724 enum SpecifierSensitivity :
unsigned {
7731 enum FormatArgumentRole :
unsigned {
7739 analyze_format_string::ArgType ArgType;
7741 StringRef SpecifierLetter;
7742 CharSourceRange
Range;
7743 SourceLocation ElementLoc;
7744 FormatArgumentRole
Role : 2;
7745 SpecifierSensitivity Sensitivity : 2;
7746 unsigned Position : 14;
7747 unsigned ModifierFor : 14;
7749 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7750 bool InFunctionCall)
const;
7753 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7755 StringRef SpecifierLetter,
7756 analyze_format_string::ArgType ArgType,
7757 FormatArgumentRole
Role,
7758 SpecifierSensitivity Sensitivity,
unsigned Position,
7759 unsigned ModifierFor)
7760 : ArgType(ArgType), LengthMod(LengthMod),
7761 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7762 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7763 ModifierFor(ModifierFor) {}
7765 unsigned getPosition()
const {
return Position; }
7766 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7768 analyze_format_string::LengthModifier getLengthModifier()
const {
7769 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7771 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7773 std::string buildFormatSpecifier()
const {
7775 llvm::raw_string_ostream(result)
7776 << getLengthModifier().toString() << SpecifierLetter;
7780 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7781 const Expr *FmtExpr,
bool InFunctionCall)
const;
7785class DecomposePrintfHandler :
public CheckPrintfHandler {
7786 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7789 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7790 const Expr *origFormatExpr,
7792 unsigned numDataArgs,
bool isObjC,
const char *beg,
7794 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7796 llvm::SmallBitVector &CheckedVarArgs,
7797 UncoveredArgHandler &UncoveredArg,
7798 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7799 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7800 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7801 inFunctionCall, CallType, CheckedVarArgs,
7803 Specs(Specs), HadError(
false) {}
7807 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7809 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7811 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7812 const char *startSpecifier,
7813 unsigned specifierLen,
7814 const TargetInfo &
Target)
override;
7819bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7821 unsigned specifierLen) {
7825 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7827 startSpecifier, specifierLen,
7831void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7832 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7840 return T->isRecordType() ||
T->isComplexType();
7843bool CheckPrintfHandler::HandleAmount(
7845 const char *startSpecifier,
unsigned specifierLen) {
7847 if (HasFormatArguments()) {
7849 if (argIndex >= NumDataArgs) {
7850 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7854 getSpecifierRange(startSpecifier, specifierLen));
7864 CoveredArgs.set(argIndex);
7865 const Expr *Arg = getDataArg(argIndex);
7876 ? diag::err_printf_asterisk_wrong_type
7877 : diag::warn_printf_asterisk_wrong_type;
7878 EmitFormatDiagnostic(S.
PDiag(DiagID)
7883 getSpecifierRange(startSpecifier, specifierLen));
7893void CheckPrintfHandler::HandleInvalidAmount(
7897 const char *startSpecifier,
7898 unsigned specifierLen) {
7908 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7912 getSpecifierRange(startSpecifier, specifierLen),
7918 const char *startSpecifier,
7919 unsigned specifierLen) {
7923 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7927 getSpecifierRange(startSpecifier, specifierLen),
7932void CheckPrintfHandler::HandleIgnoredFlag(
7936 const char *startSpecifier,
7937 unsigned specifierLen) {
7939 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7943 getSpecifierRange(startSpecifier, specifierLen),
7945 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7948void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7951 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7952 getLocationOfByte(startFlag),
7954 getSpecifierRange(startFlag, flagLen));
7957void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7960 auto Range = getSpecifierRange(startFlag, flagLen);
7961 StringRef flag(startFlag, flagLen);
7962 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7963 getLocationOfByte(startFlag),
7968void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7969 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7971 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7972 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7973 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
7974 getLocationOfByte(conversionPosition),
7980 const Expr *FmtExpr,
7981 bool InFunctionCall)
const {
7982 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7983 ElementLoc,
true, Range);
7986bool EquatableFormatArgument::VerifyCompatible(
7987 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7988 bool InFunctionCall)
const {
7993 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
7994 FmtExpr, InFunctionCall);
7995 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7999 if (
Role != FAR_Data) {
8000 if (ModifierFor !=
Other.ModifierFor) {
8003 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8004 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8005 FmtExpr, InFunctionCall);
8006 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8012 bool HadError =
false;
8013 if (Sensitivity !=
Other.Sensitivity) {
8016 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8017 << Sensitivity <<
Other.Sensitivity,
8018 FmtExpr, InFunctionCall);
8019 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8020 << 0 <<
Other.Range;
8023 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8027 case MK::MatchPromotion:
8031 case MK::NoMatchTypeConfusion:
8032 case MK::NoMatchPromotionTypeConfusion:
8034 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8035 << buildFormatSpecifier()
8036 <<
Other.buildFormatSpecifier(),
8037 FmtExpr, InFunctionCall);
8038 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8039 << 0 <<
Other.Range;
8042 case MK::NoMatchPedantic:
8044 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8045 << buildFormatSpecifier()
8046 <<
Other.buildFormatSpecifier(),
8047 FmtExpr, InFunctionCall);
8048 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8049 << 0 <<
Other.Range;
8052 case MK::NoMatchSignedness:
8054 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8055 << buildFormatSpecifier()
8056 <<
Other.buildFormatSpecifier(),
8057 FmtExpr, InFunctionCall);
8058 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8059 << 0 <<
Other.Range;
8065bool DecomposePrintfHandler::GetSpecifiers(
8066 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8069 StringRef
Data = FSL->getString();
8070 const char *Str =
Data.data();
8071 llvm::SmallBitVector BV;
8072 UncoveredArgHandler UA;
8073 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8074 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8086 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8087 const EquatableFormatArgument &B) {
8088 return A.getPosition() < B.getPosition();
8093bool DecomposePrintfHandler::HandlePrintfSpecifier(
8096 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8111 const unsigned Unset = ~0;
8112 unsigned FieldWidthIndex = Unset;
8113 unsigned PrecisionIndex = Unset;
8117 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8118 FieldWidthIndex = Specs.size();
8119 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8120 getLocationOfByte(FieldWidth.getStart()),
8122 FieldWidth.getArgType(S.
Context),
8123 EquatableFormatArgument::FAR_FieldWidth,
8124 EquatableFormatArgument::SS_None,
8125 FieldWidth.usesPositionalArg()
8126 ? FieldWidth.getPositionalArgIndex() - 1
8132 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8133 PrecisionIndex = Specs.size();
8135 getSpecifierRange(startSpecifier, specifierLen),
8136 getLocationOfByte(Precision.getStart()),
8138 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8139 EquatableFormatArgument::SS_None,
8140 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8146 unsigned SpecIndex =
8148 if (FieldWidthIndex != Unset)
8149 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8150 if (PrecisionIndex != Unset)
8151 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8153 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8155 Sensitivity = EquatableFormatArgument::SS_Private;
8157 Sensitivity = EquatableFormatArgument::SS_Public;
8159 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8161 Sensitivity = EquatableFormatArgument::SS_None;
8164 getSpecifierRange(startSpecifier, specifierLen),
8167 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8172 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8177 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8178 SpecIndex + 1, SpecIndex);
8186template<
typename MemberKind>
8204 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8219 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8221 if ((*MI)->getMinRequiredArguments() == 0)
8229bool CheckPrintfHandler::checkForCStrMembers(
8236 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8239 if (
Method->getMinRequiredArguments() == 0 &&
8252bool CheckPrintfHandler::HandlePrintfSpecifier(
8266 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8267 startSpecifier, specifierLen);
8275 startSpecifier, specifierLen)) {
8280 startSpecifier, specifierLen)) {
8284 if (!CS.consumesDataArgument()) {
8292 if (argIndex < NumDataArgs) {
8296 CoveredArgs.set(argIndex);
8303 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8306 if (HasFormatArguments()) {
8308 CoveredArgs.set(argIndex + 1);
8311 const Expr *Ex = getDataArg(argIndex);
8315 : ArgType::CPointerTy;
8317 EmitFormatDiagnostic(
8318 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8322 getSpecifierRange(startSpecifier, specifierLen));
8325 Ex = getDataArg(argIndex + 1);
8328 EmitFormatDiagnostic(
8329 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8333 getSpecifierRange(startSpecifier, specifierLen));
8340 if (!allowsObjCArg() && CS.isObjCArg()) {
8341 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8348 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8355 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8356 getLocationOfByte(CS.getStart()),
8358 getSpecifierRange(startSpecifier, specifierLen));
8368 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8375 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8379 getSpecifierRange(startSpecifier, specifierLen));
8382 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8386 getSpecifierRange(startSpecifier, specifierLen));
8390 const llvm::Triple &Triple =
Target.getTriple();
8392 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8393 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8394 getLocationOfByte(CS.getStart()),
8396 getSpecifierRange(startSpecifier, specifierLen));
8402 startSpecifier, specifierLen);
8408 startSpecifier, specifierLen);
8414 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8415 getLocationOfByte(startSpecifier),
8417 getSpecifierRange(startSpecifier, specifierLen));
8426 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8428 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8437 startSpecifier, specifierLen);
8440 startSpecifier, specifierLen);
8445 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8446 diag::warn_format_nonsensical_length);
8448 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8450 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8451 diag::warn_format_non_standard_conversion_spec);
8454 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8457 if (!HasFormatArguments())
8460 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8463 const Expr *Arg = getDataArg(argIndex);
8467 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8479 case Stmt::ArraySubscriptExprClass:
8480 case Stmt::CallExprClass:
8481 case Stmt::CharacterLiteralClass:
8482 case Stmt::CXXBoolLiteralExprClass:
8483 case Stmt::DeclRefExprClass:
8484 case Stmt::FloatingLiteralClass:
8485 case Stmt::IntegerLiteralClass:
8486 case Stmt::MemberExprClass:
8487 case Stmt::ObjCArrayLiteralClass:
8488 case Stmt::ObjCBoolLiteralExprClass:
8489 case Stmt::ObjCBoxedExprClass:
8490 case Stmt::ObjCDictionaryLiteralClass:
8491 case Stmt::ObjCEncodeExprClass:
8492 case Stmt::ObjCIvarRefExprClass:
8493 case Stmt::ObjCMessageExprClass:
8494 case Stmt::ObjCPropertyRefExprClass:
8495 case Stmt::ObjCStringLiteralClass:
8496 case Stmt::ObjCSubscriptRefExprClass:
8497 case Stmt::ParenExprClass:
8498 case Stmt::StringLiteralClass:
8499 case Stmt::UnaryOperatorClass:
8506static std::pair<QualType, StringRef>
8513 StringRef Name = UserTy->getDecl()->getName();
8514 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8515 .Case(
"CFIndex", Context.getNSIntegerType())
8516 .Case(
"NSInteger", Context.getNSIntegerType())
8517 .Case(
"NSUInteger", Context.getNSUIntegerType())
8518 .Case(
"SInt32", Context.IntTy)
8519 .Case(
"UInt32", Context.UnsignedIntTy)
8523 return std::make_pair(CastTy, Name);
8525 TyTy = UserTy->desugar();
8529 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8531 PE->getSubExpr()->getType(),
8540 StringRef TrueName, FalseName;
8542 std::tie(TrueTy, TrueName) =
8544 CO->getTrueExpr()->getType(),
8546 std::tie(FalseTy, FalseName) =
8548 CO->getFalseExpr()->getType(),
8549 CO->getFalseExpr());
8551 if (TrueTy == FalseTy)
8552 return std::make_pair(TrueTy, TrueName);
8553 else if (TrueTy.
isNull())
8554 return std::make_pair(FalseTy, FalseName);
8555 else if (FalseTy.
isNull())
8556 return std::make_pair(TrueTy, TrueName);
8559 return std::make_pair(
QualType(), StringRef());
8578 From = VecTy->getElementType();
8580 To = VecTy->getElementType();
8591 diag::warn_format_conversion_argument_type_mismatch_signedness,
8595 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8604 const char *StartSpecifier,
8605 unsigned SpecifierLen,
8617 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8618 ExprTy = TET->getUnderlyingExpr()->getType();
8633 getSpecifierRange(StartSpecifier, SpecifierLen);
8635 llvm::raw_svector_ostream os(FSString);
8637 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8648 getSpecifierRange(StartSpecifier, SpecifierLen);
8649 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8659 if (
Match == ArgType::Match)
8663 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8672 E = ICE->getSubExpr();
8682 if (OrigMatch == ArgType::NoMatchSignedness &&
8683 ImplicitMatch != ArgType::NoMatchSignedness)
8690 if (ImplicitMatch == ArgType::Match)
8708 if (
Match == ArgType::MatchPromotion)
8712 if (
Match == ArgType::MatchPromotion) {
8716 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8717 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8721 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8722 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8723 Match = ImplicitMatch;
8724 assert(
Match != ArgType::MatchPromotion);
8727 bool IsEnum =
false;
8728 bool IsScopedEnum =
false;
8731 IntendedTy = ED->getIntegerType();
8732 if (!ED->isScoped()) {
8733 ExprTy = IntendedTy;
8738 IsScopedEnum =
true;
8745 if (isObjCContext() &&
8756 const llvm::APInt &
V = IL->getValue();
8766 if (TD->getUnderlyingType() == IntendedTy)
8776 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8784 if (!IsScopedEnum &&
8785 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8789 IntendedTy = CastTy;
8790 ShouldNotPrintDirectly =
true;
8795 PrintfSpecifier fixedFS = FS;
8802 llvm::raw_svector_ostream os(buf);
8805 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8807 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8813 llvm_unreachable(
"expected non-matching");
8815 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8818 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8821 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8824 Diag = diag::warn_format_conversion_argument_type_mismatch;
8845 llvm::raw_svector_ostream CastFix(CastBuf);
8846 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8848 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8854 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8859 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8881 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8887 Name = TypedefTy->getDecl()->getName();
8891 ? diag::warn_format_argument_needs_cast_pedantic
8892 : diag::warn_format_argument_needs_cast;
8893 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8904 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8905 : diag::warn_format_conversion_argument_type_mismatch;
8907 EmitFormatDiagnostic(
8919 bool EmitTypeMismatch =
false;
8928 llvm_unreachable(
"expected non-matching");
8930 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8933 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8936 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8940 ? diag::err_format_conversion_argument_type_mismatch
8941 : diag::warn_format_conversion_argument_type_mismatch;
8945 EmitFormatDiagnostic(
8954 EmitTypeMismatch =
true;
8956 EmitFormatDiagnostic(
8957 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8958 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8962 checkForCStrMembers(AT, E);
8968 EmitTypeMismatch =
true;
8970 EmitFormatDiagnostic(
8971 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8972 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8985 if (EmitTypeMismatch) {
8991 EmitFormatDiagnostic(
8992 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8998 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
8999 "format string specifier index out of range");
9000 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9010class CheckScanfHandler :
public CheckFormatHandler {
9012 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9014 unsigned firstDataArg,
unsigned numDataArgs,
9016 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9018 llvm::SmallBitVector &CheckedVarArgs,
9019 UncoveredArgHandler &UncoveredArg)
9020 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9021 numDataArgs, beg, APK, Args, formatIdx,
9022 inFunctionCall, CallType, CheckedVarArgs,
9025 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9026 const char *startSpecifier,
9027 unsigned specifierLen)
override;
9029 bool HandleInvalidScanfConversionSpecifier(
9030 const analyze_scanf::ScanfSpecifier &FS,
9031 const char *startSpecifier,
9032 unsigned specifierLen)
override;
9034 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9039void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9041 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9042 getLocationOfByte(end),
true,
9043 getSpecifierRange(start, end - start));
9046bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9048 const char *startSpecifier,
9049 unsigned specifierLen) {
9053 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9055 startSpecifier, specifierLen,
9059bool CheckScanfHandler::HandleScanfSpecifier(
9061 const char *startSpecifier,
9062 unsigned specifierLen) {
9076 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9077 startSpecifier, specifierLen);
9088 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9103 if (argIndex < NumDataArgs) {
9107 CoveredArgs.set(argIndex);
9113 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9114 diag::warn_format_nonsensical_length);
9116 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9118 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9119 diag::warn_format_non_standard_conversion_spec);
9122 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9125 if (!HasFormatArguments())
9128 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9132 const Expr *Ex = getDataArg(argIndex);
9150 ScanfSpecifier fixedFS = FS;
9155 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9157 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9158 : diag::warn_format_conversion_argument_type_mismatch;
9163 llvm::raw_svector_ostream os(buf);
9166 EmitFormatDiagnostic(
9171 getSpecifierRange(startSpecifier, specifierLen),
9173 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9180 getSpecifierRange(startSpecifier, specifierLen));
9190 const Expr *FmtExpr,
bool InFunctionCall) {
9191 bool HadError =
false;
9192 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9193 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9194 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9206 for (; FmtIter < FmtEnd; ++FmtIter) {
9210 if (FmtIter->getPosition() < RefIter->getPosition())
9214 if (FmtIter->getPosition() > RefIter->getPosition())
9218 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9222 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9223 return Arg.getPosition() != RefIter->getPosition();
9227 if (FmtIter < FmtEnd) {
9228 CheckFormatHandler::EmitFormatDiagnostic(
9229 S, InFunctionCall, FmtExpr,
9230 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9231 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9232 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9233 }
else if (RefIter < RefEnd) {
9234 CheckFormatHandler::EmitFormatDiagnostic(
9235 S, InFunctionCall, FmtExpr,
9236 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9239 << 1 << RefIter->getSourceRange();
9245 Sema &S,
const FormatStringLiteral *FExpr,
9250 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9251 bool IgnoreStringsWithoutSpecifiers) {
9253 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9254 CheckFormatHandler::EmitFormatDiagnostic(
9255 S, inFunctionCall, Args[format_idx],
9256 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9262 StringRef StrRef = FExpr->getString();
9263 const char *Str = StrRef.data();
9267 assert(
T &&
"String literal not of constant array type!");
9268 size_t TypeSize =
T->getZExtSize();
9269 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9270 const unsigned numDataArgs = Args.size() - firstDataArg;
9272 if (IgnoreStringsWithoutSpecifiers &&
9279 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9280 CheckFormatHandler::EmitFormatDiagnostic(
9281 S, inFunctionCall, Args[format_idx],
9282 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9283 FExpr->getBeginLoc(),
9289 if (StrLen == 0 && numDataArgs > 0) {
9290 CheckFormatHandler::EmitFormatDiagnostic(
9291 S, inFunctionCall, Args[format_idx],
9292 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9303 if (ReferenceFormatString ==
nullptr) {
9304 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9305 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9306 inFunctionCall, CallType, CheckedVarArgs,
9316 Type, ReferenceFormatString, FExpr->getFormatString(),
9317 inFunctionCall ?
nullptr : Args[format_idx]);
9320 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9321 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9322 CallType, CheckedVarArgs, UncoveredArg);
9342 FormatStringLiteral RefLit = AuthoritativeFormatString;
9343 FormatStringLiteral TestLit = TestedFormatString;
9345 bool DiagAtStringLiteral;
9346 if (FunctionCallArg) {
9347 Arg = FunctionCallArg;
9348 DiagAtStringLiteral =
false;
9350 Arg = TestedFormatString;
9351 DiagAtStringLiteral =
true;
9353 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9354 AuthoritativeFormatString,
Type,
9355 IsObjC,
true, RefArgs) &&
9356 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9357 DiagAtStringLiteral, FmtArgs)) {
9359 TestedFormatString, FmtArgs, Arg,
9360 DiagAtStringLiteral);
9373 FormatStringLiteral RefLit = Str;
9377 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9386 bool HadError =
false;
9387 auto Iter = Args.begin();
9388 auto End = Args.end();
9389 while (Iter != End) {
9390 const auto &FirstInGroup = *Iter;
9392 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9394 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9403 const char *Str = StrRef.data();
9406 assert(
T &&
"String literal not of constant array type!");
9407 size_t TypeSize =
T->getZExtSize();
9408 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9419 switch (AbsFunction) {
9423 case Builtin::BI__builtin_abs:
9424 return Builtin::BI__builtin_labs;
9425 case Builtin::BI__builtin_labs:
9426 return Builtin::BI__builtin_llabs;
9427 case Builtin::BI__builtin_llabs:
9430 case Builtin::BI__builtin_fabsf:
9431 return Builtin::BI__builtin_fabs;
9432 case Builtin::BI__builtin_fabs:
9433 return Builtin::BI__builtin_fabsl;
9434 case Builtin::BI__builtin_fabsl:
9437 case Builtin::BI__builtin_cabsf:
9438 return Builtin::BI__builtin_cabs;
9439 case Builtin::BI__builtin_cabs:
9440 return Builtin::BI__builtin_cabsl;
9441 case Builtin::BI__builtin_cabsl:
9444 case Builtin::BIabs:
9445 return Builtin::BIlabs;
9446 case Builtin::BIlabs:
9447 return Builtin::BIllabs;
9448 case Builtin::BIllabs:
9451 case Builtin::BIfabsf:
9452 return Builtin::BIfabs;
9453 case Builtin::BIfabs:
9454 return Builtin::BIfabsl;
9455 case Builtin::BIfabsl:
9458 case Builtin::BIcabsf:
9459 return Builtin::BIcabs;
9460 case Builtin::BIcabs:
9461 return Builtin::BIcabsl;
9462 case Builtin::BIcabsl:
9491 unsigned AbsFunctionKind) {
9492 unsigned BestKind = 0;
9493 uint64_t ArgSize = Context.getTypeSize(ArgType);
9494 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9497 if (Context.getTypeSize(ParamType) >= ArgSize) {
9500 else if (Context.hasSameType(ParamType, ArgType)) {
9516 if (
T->isIntegralOrEnumerationType())
9518 if (
T->isRealFloatingType())
9520 if (
T->isAnyComplexType())
9523 llvm_unreachable(
"Type not integer, floating, or complex");
9530 switch (ValueKind) {
9535 case Builtin::BI__builtin_fabsf:
9536 case Builtin::BI__builtin_fabs:
9537 case Builtin::BI__builtin_fabsl:
9538 case Builtin::BI__builtin_cabsf:
9539 case Builtin::BI__builtin_cabs:
9540 case Builtin::BI__builtin_cabsl:
9541 return Builtin::BI__builtin_abs;
9542 case Builtin::BIfabsf:
9543 case Builtin::BIfabs:
9544 case Builtin::BIfabsl:
9545 case Builtin::BIcabsf:
9546 case Builtin::BIcabs:
9547 case Builtin::BIcabsl:
9548 return Builtin::BIabs;
9554 case Builtin::BI__builtin_abs:
9555 case Builtin::BI__builtin_labs:
9556 case Builtin::BI__builtin_llabs:
9557 case Builtin::BI__builtin_cabsf:
9558 case Builtin::BI__builtin_cabs:
9559 case Builtin::BI__builtin_cabsl:
9560 return Builtin::BI__builtin_fabsf;
9561 case Builtin::BIabs:
9562 case Builtin::BIlabs:
9563 case Builtin::BIllabs:
9564 case Builtin::BIcabsf:
9565 case Builtin::BIcabs:
9566 case Builtin::BIcabsl:
9567 return Builtin::BIfabsf;
9573 case Builtin::BI__builtin_abs:
9574 case Builtin::BI__builtin_labs:
9575 case Builtin::BI__builtin_llabs:
9576 case Builtin::BI__builtin_fabsf:
9577 case Builtin::BI__builtin_fabs:
9578 case Builtin::BI__builtin_fabsl:
9579 return Builtin::BI__builtin_cabsf;
9580 case Builtin::BIabs:
9581 case Builtin::BIlabs:
9582 case Builtin::BIllabs:
9583 case Builtin::BIfabsf:
9584 case Builtin::BIfabs:
9585 case Builtin::BIfabsl:
9586 return Builtin::BIcabsf;
9589 llvm_unreachable(
"Unable to convert function");
9600 case Builtin::BI__builtin_abs:
9601 case Builtin::BI__builtin_fabs:
9602 case Builtin::BI__builtin_fabsf:
9603 case Builtin::BI__builtin_fabsl:
9604 case Builtin::BI__builtin_labs:
9605 case Builtin::BI__builtin_llabs:
9606 case Builtin::BI__builtin_cabs:
9607 case Builtin::BI__builtin_cabsf:
9608 case Builtin::BI__builtin_cabsl:
9609 case Builtin::BIabs:
9610 case Builtin::BIlabs:
9611 case Builtin::BIllabs:
9612 case Builtin::BIfabs:
9613 case Builtin::BIfabsf:
9614 case Builtin::BIfabsl:
9615 case Builtin::BIcabs:
9616 case Builtin::BIcabsf:
9617 case Builtin::BIcabsl:
9620 llvm_unreachable(
"Unknown Builtin type");
9626 unsigned AbsKind,
QualType ArgType) {
9627 bool EmitHeaderHint =
true;
9628 const char *HeaderName =
nullptr;
9629 std::string FunctionName;
9630 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9631 FunctionName =
"std::abs";
9632 if (ArgType->isIntegralOrEnumerationType()) {
9633 HeaderName =
"cstdlib";
9634 }
else if (ArgType->isRealFloatingType()) {
9635 HeaderName =
"cmath";
9637 llvm_unreachable(
"Invalid Type");
9646 for (
const auto *I : R) {
9649 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9651 FDecl = dyn_cast<FunctionDecl>(I);
9666 EmitHeaderHint =
false;
9684 EmitHeaderHint =
false;
9688 }
else if (!R.
empty()) {
9694 S.
Diag(Loc, diag::note_replace_abs_function)
9700 if (!EmitHeaderHint)
9703 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9707template <std::
size_t StrLen>
9709 const char (&Str)[StrLen]) {
9722 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9723 return llvm::is_contained(names, calleeName);
9728 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9729 "__builtin_nanf16",
"__builtin_nanf128"});
9731 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9732 "__builtin_inff16",
"__builtin_inff128"});
9734 llvm_unreachable(
"unknown MathCheck");
9738 if (FDecl->
getName() !=
"infinity")
9741 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9743 if (RDecl->
getName() !=
"numeric_limits")
9760 if (FPO.getNoHonorNaNs() &&
9763 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9764 << 1 << 0 <<
Call->getSourceRange();
9768 if (FPO.getNoHonorInfs() &&
9772 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9773 << 0 << 0 <<
Call->getSourceRange();
9777void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9779 if (
Call->getNumArgs() != 1)
9784 if (AbsKind == 0 && !IsStdAbs)
9787 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9788 QualType ParamType =
Call->getArg(0)->getType();
9793 std::string FunctionName =
9794 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9795 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9796 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9825 if (ArgValueKind == ParamValueKind) {
9826 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9830 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9831 << FDecl << ArgType << ParamType;
9833 if (NewAbsKind == 0)
9837 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9846 if (NewAbsKind == 0)
9849 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9850 << FDecl << ParamValueKind << ArgValueKind;
9853 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9859 if (!
Call || !FDecl)
return;
9863 if (
Call->getExprLoc().isMacroID())
return;
9866 if (
Call->getNumArgs() != 2)
return;
9869 if (!ArgList)
return;
9870 if (ArgList->size() != 1)
return;
9873 const auto& TA = ArgList->
get(0);
9875 QualType ArgType = TA.getAsType();
9879 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
9880 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
9881 if (!MTE)
return false;
9882 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9883 if (!
Num)
return false;
9884 if (
Num->getValue() != 0)
return false;
9888 const Expr *FirstArg =
Call->getArg(0);
9889 const Expr *SecondArg =
Call->getArg(1);
9890 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9891 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9894 if (IsFirstArgZero == IsSecondArgZero)
return;
9899 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9901 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9902 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9905 SourceRange RemovalRange;
9906 if (IsFirstArgZero) {
9907 RemovalRange = SourceRange(FirstRange.
getBegin(),
9914 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9929 const auto *Size = dyn_cast<BinaryOperator>(E);
9934 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9938 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9939 << SizeRange << FnName;
9940 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9945 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9956 bool &IsContained) {
9958 const Type *Ty =
T->getBaseElementTypeUnsafe();
9959 IsContained =
false;
9972 for (
auto *FD : RD->
fields()) {
9985 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
9986 if (Unary->getKind() == UETT_SizeOf)
9995 if (!
SizeOf->isArgumentType())
9996 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10003 return SizeOf->getTypeOfArgument();
10009struct SearchNonTrivialToInitializeField
10012 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10014 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10017 SourceLocation SL) {
10018 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10019 asDerived().visitArray(PDIK, AT, SL);
10023 Super::visitWithKind(PDIK, FT, SL);
10026 void visitARCStrong(QualType FT, SourceLocation SL) {
10029 void visitARCWeak(QualType FT, SourceLocation SL) {
10032 void visitStruct(QualType FT, SourceLocation SL) {
10037 const ArrayType *AT, SourceLocation SL) {
10038 visit(getContext().getBaseElementType(AT), SL);
10040 void visitTrivial(QualType FT, SourceLocation SL) {}
10042 static void diag(QualType RT,
const Expr *E, Sema &S) {
10043 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10052struct SearchNonTrivialToCopyField
10054 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10056 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10059 SourceLocation SL) {
10060 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10061 asDerived().visitArray(PCK, AT, SL);
10065 Super::visitWithKind(PCK, FT, SL);
10068 void visitARCStrong(QualType FT, SourceLocation SL) {
10071 void visitARCWeak(QualType FT, SourceLocation SL) {
10074 void visitPtrAuth(QualType FT, SourceLocation SL) {
10077 void visitStruct(QualType FT, SourceLocation SL) {
10082 SourceLocation SL) {
10083 visit(getContext().getBaseElementType(AT), SL);
10086 SourceLocation SL) {}
10087 void visitTrivial(QualType FT, SourceLocation SL) {}
10088 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10090 static void diag(QualType RT,
const Expr *E, Sema &S) {
10091 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10106 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10107 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10131 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10133 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10134 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10140 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10143 const Expr *SizeArg =
10144 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10146 auto isLiteralZero = [](
const Expr *E) {
10156 if (isLiteralZero(SizeArg) &&
10163 if (BId == Builtin::BIbzero ||
10166 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10167 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10168 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10169 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10170 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10178 if (BId == Builtin::BImemset &&
10182 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10183 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10188void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10195 unsigned ExpectedNumArgs =
10196 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10197 if (
Call->getNumArgs() < ExpectedNumArgs)
10200 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10201 BId == Builtin::BIstrndup ? 1 : 2);
10203 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10204 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10207 Call->getBeginLoc(),
Call->getRParenLoc()))
10216 llvm::FoldingSetNodeID SizeOfArgID;
10221 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10222 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10225 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10226 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10227 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10229 QualType DestTy = Dest->
getType();
10230 QualType PointeeTy;
10231 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10244 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10248 if (SizeOfArgID == llvm::FoldingSetNodeID())
10250 llvm::FoldingSetNodeID DestID;
10252 if (DestID == SizeOfArgID) {
10255 unsigned ActionIdx = 0;
10256 StringRef ReadableName = FnName->
getName();
10258 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10259 if (UnaryOp->getOpcode() == UO_AddrOf)
10268 SourceLocation SL = SizeOfArg->
getExprLoc();
10273 if (
SM.isMacroArgExpansion(SL)) {
10275 SL =
SM.getSpellingLoc(SL);
10276 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10278 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10283 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10290 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10301 if (SizeOfArgTy != QualType()) {
10303 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10305 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10306 << FnName << SizeOfArgTy << ArgIdx
10313 PointeeTy = DestTy;
10316 if (PointeeTy == QualType())
10321 if (
const CXXRecordDecl *ContainedRD =
10324 unsigned OperationType = 0;
10325 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10328 if (ArgIdx != 0 || IsCmp) {
10329 if (BId == Builtin::BImemcpy)
10331 else if(BId == Builtin::BImemmove)
10338 PDiag(diag::warn_dyn_class_memaccess)
10339 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10340 << IsContained << ContainedRD << OperationType
10341 <<
Call->getCallee()->getSourceRange());
10343 BId != Builtin::BImemset)
10346 PDiag(diag::warn_arc_object_memaccess)
10347 << ArgIdx << FnName << PointeeTy
10348 <<
Call->getCallee()->getSourceRange());
10355 bool NonTriviallyCopyableCXXRecord =
10359 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10362 PDiag(diag::warn_cstruct_memaccess)
10363 << ArgIdx << FnName << PointeeTy << 0);
10364 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10365 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10366 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10370 PDiag(diag::warn_cxxstruct_memaccess)
10371 << FnName << PointeeTy);
10372 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10375 PDiag(diag::warn_cstruct_memaccess)
10376 << ArgIdx << FnName << PointeeTy << 1);
10377 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10378 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10379 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10383 PDiag(diag::warn_cxxstruct_memaccess)
10384 << FnName << PointeeTy);
10393 PDiag(diag::note_bad_memaccess_silence)
10429 if (CAT->getZExtSize() <= 1)
10437void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10441 unsigned NumArgs =
Call->getNumArgs();
10442 if ((NumArgs != 3) && (NumArgs != 4))
10447 const Expr *CompareWithSrc =
nullptr;
10450 Call->getBeginLoc(),
Call->getRParenLoc()))
10455 CompareWithSrc = Ex;
10458 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10459 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10460 SizeCall->getNumArgs() == 1)
10465 if (!CompareWithSrc)
10472 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10476 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10477 if (!CompareWithSrcDRE ||
10481 const Expr *OriginalSizeArg =
Call->getArg(2);
10482 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10489 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10493 SmallString<128> sizeString;
10494 llvm::raw_svector_ostream
OS(sizeString);
10499 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10506 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10507 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10508 return D1->getDecl() == D2->getDecl();
10513 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10522void Sema::CheckStrncatArguments(
const CallExpr *CE,
10537 unsigned PatternType = 0;
10545 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10546 if (BE->getOpcode() == BO_Sub) {
10547 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10548 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10559 if (PatternType == 0)
10568 if (
SM.isMacroArgExpansion(SL)) {
10569 SL =
SM.getSpellingLoc(SL);
10570 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10575 QualType DstTy = DstArg->
getType();
10578 if (!isKnownSizeArray) {
10579 if (PatternType == 1)
10580 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10582 Diag(SL, diag::warn_strncat_src_size) << SR;
10586 if (PatternType == 1)
10587 Diag(SL, diag::warn_strncat_large_size) << SR;
10589 Diag(SL, diag::warn_strncat_src_size) << SR;
10591 SmallString<128> sizeString;
10592 llvm::raw_svector_ostream
OS(sizeString);
10600 Diag(SL, diag::note_strncat_wrong_size)
10605void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10614void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10616 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10617 const Decl *D = Lvalue->getDecl();
10618 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10619 if (!DD->getType()->isReferenceType())
10620 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10624 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10625 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10626 Lvalue->getMemberDecl());
10629void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10631 const auto *Lambda = dyn_cast<LambdaExpr>(
10636 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10637 << CalleeName << 2 ;
10640void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10642 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10643 if (Var ==
nullptr)
10647 << CalleeName << 0 << Var;
10650void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10653 llvm::raw_svector_ostream
OS(SizeString);
10656 if (Kind == clang::CK_BitCast &&
10657 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10659 if (Kind == clang::CK_IntegralToPointer &&
10661 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10664 switch (
Cast->getCastKind()) {
10665 case clang::CK_BitCast:
10666 case clang::CK_IntegralToPointer:
10667 case clang::CK_FunctionToPointerDecay:
10676 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10677 << CalleeName << 0 <<
OS.str();
10681void Sema::CheckFreeArguments(
const CallExpr *E) {
10682 const std::string CalleeName =
10687 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10689 case UnaryOperator::Opcode::UO_AddrOf:
10690 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10691 case UnaryOperator::Opcode::UO_Plus:
10692 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10697 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10699 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10701 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10702 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10703 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10709 << CalleeName << 1 ;
10714 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10715 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10719Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10728 Diag(ReturnLoc, diag::warn_null_ret)
10738 if (Op == OO_New || Op == OO_Array_New) {
10739 const FunctionProtoType *Proto
10743 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10749 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10754 if (
Context.getTargetInfo().getTriple().isPPC64())
10766 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10767 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10769 return FPLiteral && FPCast;
10772 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10778 llvm::APFloat TargetC = FPLiteral->
getValue();
10779 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10780 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10784 Diag(Loc, diag::warn_float_compare_literal)
10785 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10798 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10799 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10800 if (DRL->getDecl() == DRR->getDecl())
10808 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10809 if (FLL->isExact())
10811 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10812 if (FLR->isExact())
10816 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10817 CL &&
CL->getBuiltinCallee())
10820 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10821 CR && CR->getBuiltinCallee())
10825 Diag(Loc, diag::warn_floatingpoint_eq)
10846 IntRange(
unsigned Width,
bool NonNegative)
10847 : Width(Width), NonNegative(NonNegative) {}
10850 unsigned valueBits()
const {
10851 return NonNegative ? Width : Width - 1;
10855 static IntRange forBoolType() {
10856 return IntRange(1,
true);
10860 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
10861 return forValueOfCanonicalType(
C,
10866 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
10869 if (
const auto *VT = dyn_cast<VectorType>(
T))
10870 T = VT->getElementType().getTypePtr();
10871 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10872 T = CT->getElementType().getTypePtr();
10873 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10874 T = AT->getValueType().getTypePtr();
10876 if (!
C.getLangOpts().CPlusPlus) {
10879 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10884 if (
Enum->isFixed()) {
10885 return IntRange(
C.getIntWidth(QualType(
T, 0)),
10886 !
Enum->getIntegerType()->isSignedIntegerType());
10889 unsigned NumPositive =
Enum->getNumPositiveBits();
10890 unsigned NumNegative =
Enum->getNumNegativeBits();
10892 if (NumNegative == 0)
10893 return IntRange(NumPositive,
true);
10895 return IntRange(std::max(NumPositive + 1, NumNegative),
10899 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10900 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10913 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
10916 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10917 T = VT->getElementType().getTypePtr();
10918 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
10919 T = CT->getElementType().getTypePtr();
10920 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10921 T = AT->getValueType().getTypePtr();
10923 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10925 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10926 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10935 static IntRange join(IntRange L, IntRange R) {
10936 bool Unsigned = L.NonNegative && R.NonNegative;
10937 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10938 L.NonNegative && R.NonNegative);
10942 static IntRange bit_and(IntRange L, IntRange R) {
10943 unsigned Bits = std::max(L.Width, R.Width);
10944 bool NonNegative =
false;
10945 if (L.NonNegative) {
10946 Bits = std::min(Bits, L.Width);
10947 NonNegative =
true;
10949 if (R.NonNegative) {
10950 Bits = std::min(Bits, R.Width);
10951 NonNegative =
true;
10953 return IntRange(Bits, NonNegative);
10957 static IntRange sum(IntRange L, IntRange R) {
10958 bool Unsigned = L.NonNegative && R.NonNegative;
10959 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10964 static IntRange difference(IntRange L, IntRange R) {
10968 bool CanWiden = !L.NonNegative || !R.NonNegative;
10969 bool Unsigned = L.NonNegative && R.Width == 0;
10970 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10976 static IntRange product(IntRange L, IntRange R) {
10980 bool CanWiden = !L.NonNegative && !R.NonNegative;
10981 bool Unsigned = L.NonNegative && R.NonNegative;
10982 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10987 static IntRange rem(IntRange L, IntRange R) {
10991 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10999 if (value.isSigned() && value.isNegative())
11000 return IntRange(value.getSignificantBits(),
false);
11002 if (value.getBitWidth() > MaxWidth)
11003 value = value.trunc(MaxWidth);
11007 return IntRange(value.getActiveBits(),
true);
11011 if (result.
isInt())
11018 R = IntRange::join(R, El);
11026 return IntRange::join(R, I);
11041 Ty = AtomicRHS->getValueType();
11060 bool InConstantContext,
11061 bool Approximate) {
11072 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11073 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11077 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11079 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11080 CE->getCastKind() == CK_BooleanToSignedIntegral;
11083 if (!isIntegerCast)
11084 return OutputTypeRange;
11087 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11088 InConstantContext, Approximate);
11090 return std::nullopt;
11093 if (SubRange->Width >= OutputTypeRange.Width)
11094 return OutputTypeRange;
11098 return IntRange(SubRange->Width,
11099 SubRange->NonNegative || OutputTypeRange.NonNegative);
11102 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11105 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11107 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11108 InConstantContext, Approximate);
11113 Expr *TrueExpr = CO->getTrueExpr();
11115 return std::nullopt;
11117 std::optional<IntRange> L =
11120 return std::nullopt;
11122 Expr *FalseExpr = CO->getFalseExpr();
11124 return std::nullopt;
11126 std::optional<IntRange> R =
11129 return std::nullopt;
11131 return IntRange::join(*L, *R);
11134 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11135 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11137 switch (BO->getOpcode()) {
11139 llvm_unreachable(
"builtin <=> should have class type");
11150 return IntRange::forBoolType();
11179 Combine = IntRange::bit_and;
11187 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11188 if (I->getValue() == 1) {
11189 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11190 return IntRange(R.Width,
true);
11200 case BO_ShrAssign: {
11202 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11204 return std::nullopt;
11208 if (std::optional<llvm::APSInt> shift =
11209 BO->getRHS()->getIntegerConstantExpr(
C)) {
11210 if (shift->isNonNegative()) {
11211 if (shift->uge(L->Width))
11212 L->Width = (L->NonNegative ? 0 : 1);
11214 L->Width -= shift->getZExtValue();
11228 Combine = IntRange::sum;
11232 if (BO->getLHS()->getType()->isPointerType())
11235 Combine = IntRange::difference;
11240 Combine = IntRange::product;
11249 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11251 return std::nullopt;
11254 if (std::optional<llvm::APSInt> divisor =
11255 BO->getRHS()->getIntegerConstantExpr(
C)) {
11256 unsigned log2 = divisor->logBase2();
11257 if (
log2 >= L->Width)
11258 L->Width = (L->NonNegative ? 0 : 1);
11260 L->Width = std::min(L->Width -
log2, MaxWidth);
11268 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11270 return std::nullopt;
11272 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11276 Combine = IntRange::rem;
11288 unsigned opWidth =
C.getIntWidth(
T);
11290 InConstantContext, Approximate);
11292 return std::nullopt;
11295 InConstantContext, Approximate);
11297 return std::nullopt;
11299 IntRange
C = Combine(*L, *R);
11300 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11301 C.Width = std::min(
C.Width, MaxWidth);
11305 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11306 switch (UO->getOpcode()) {
11309 return IntRange::forBoolType();
11323 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11326 return std::nullopt;
11331 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11341 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11344 return std::nullopt;
11349 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11359 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11360 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11364 return IntRange(BitField->getBitWidthValue(),
11365 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11368 return std::nullopt;
11374 bool InConstantContext,
11375 bool Approximate) {
11384 const llvm::fltSemantics &Src,
11385 const llvm::fltSemantics &Tgt) {
11386 llvm::APFloat truncated = value;
11389 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11390 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11392 return truncated.bitwiseIsEqual(value);
11401 const llvm::fltSemantics &Src,
11402 const llvm::fltSemantics &Tgt) {
11419 bool IsListInit =
false);
11434 return MacroName !=
"YES" && MacroName !=
"NO" &&
11435 MacroName !=
"true" && MacroName !=
"false";
11443 (!E->
getType()->isSignedIntegerType() ||
11458struct PromotedRange {
11460 llvm::APSInt PromotedMin;
11462 llvm::APSInt PromotedMax;
11464 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11466 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11467 else if (R.Width >= BitWidth && !
Unsigned) {
11471 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11472 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11474 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11475 .extOrTrunc(BitWidth);
11476 PromotedMin.setIsUnsigned(
Unsigned);
11478 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11479 .extOrTrunc(BitWidth);
11480 PromotedMax.setIsUnsigned(
Unsigned);
11485 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11495 InRangeFlag = 0x40,
11498 Min =
LE | InRangeFlag,
11499 InRange = InRangeFlag,
11500 Max =
GE | InRangeFlag,
11503 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11508 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11509 Value.isUnsigned() == PromotedMin.isUnsigned());
11510 if (!isContiguous()) {
11511 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11512 if (
Value.isMinValue())
return Min;
11513 if (
Value.isMaxValue())
return Max;
11514 if (
Value >= PromotedMin)
return InRange;
11515 if (
Value <= PromotedMax)
return InRange;
11519 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11520 case -1:
return Less;
11521 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11523 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11524 case -1:
return InRange;
11525 case 0:
return Max;
11530 llvm_unreachable(
"impossible compare result");
11533 static std::optional<StringRef>
11535 if (Op == BO_Cmp) {
11537 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11539 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11540 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11541 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11542 return std::nullopt;
11549 }
else if (Op == BO_NE) {
11553 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11560 if (Op == BO_GE || Op == BO_LE)
11561 std::swap(TrueFlag, FalseFlag);
11564 return StringRef(
"true");
11566 return StringRef(
"false");
11567 return std::nullopt;
11574 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11575 if (ICE->getCastKind() != CK_IntegralCast &&
11576 ICE->getCastKind() != CK_NoOp)
11578 E = ICE->getSubExpr();
11587 enum ConstantValueKind {
11592 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11593 return BL->getValue() ? ConstantValueKind::LiteralTrue
11594 : ConstantValueKind::LiteralFalse;
11595 return ConstantValueKind::Miscellaneous;
11600 const llvm::APSInt &
Value,
11601 bool RhsConstant) {
11623 if (!OtherValueRange)
11628 OtherT = AT->getValueType();
11629 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11633 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11639 bool OtherIsBooleanDespiteType =
11641 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11642 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11646 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11647 Value.isUnsigned());
11648 auto Cmp = OtherPromotedValueRange.compare(
Value);
11649 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11655 bool TautologicalTypeCompare =
false;
11657 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11658 Value.isUnsigned());
11659 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11662 TautologicalTypeCompare =
true;
11670 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11679 bool InRange = Cmp & PromotedRange::InRangeFlag;
11685 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11686 Other->getType()->isUnsignedIntegerOrEnumerationType())
11687 TautologicalTypeCompare =
true;
11692 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11693 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11697 llvm::raw_svector_ostream OS(PrettySourceValue);
11699 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11700 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11702 OS << (BL->getValue() ?
"YES" :
"NO");
11707 if (!TautologicalTypeCompare) {
11709 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11715 if (IsObjCSignedCharBool) {
11717 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11718 << OS.str() << *Result);
11725 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11729 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11730 : diag::warn_tautological_bool_compare)
11732 << OtherIsBooleanDespiteType << *Result
11739 ? diag::warn_unsigned_enum_always_true_comparison
11740 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11741 : diag::warn_unsigned_always_true_comparison)
11742 : diag::warn_tautological_constant_compare;
11745 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11778 if (
T->isIntegralType(S.
Context)) {
11779 std::optional<llvm::APSInt> RHSValue =
11781 std::optional<llvm::APSInt> LHSValue =
11785 if (RHSValue && LHSValue)
11789 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11791 const bool RhsConstant = (
bool)RHSValue;
11792 Expr *Const = RhsConstant ? RHS : LHS;
11794 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11803 if (!
T->hasUnsignedIntegerRepresentation()) {
11817 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11819 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11825 Expr *signedOperand, *unsignedOperand;
11828 "unsigned comparison between two signed integer expressions?");
11829 signedOperand = LHS;
11830 unsignedOperand = RHS;
11832 signedOperand = RHS;
11833 unsignedOperand = LHS;
11839 std::optional<IntRange> signedRange =
11851 if (signedRange->NonNegative)
11863 if (!unsignedRange)
11868 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11870 if (unsignedRange->Width < comparisonWidth)
11875 S.
PDiag(diag::warn_mixed_sign_comparison)
11894 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11899 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11900 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11901 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11902 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11903 << BitfieldEnumDecl;
11910 Init->isValueDependent() ||
11911 Init->isTypeDependent())
11914 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11924 const PreferredTypeAttr *PTAttr =
nullptr;
11926 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11928 ED = PTAttr->getType()->getAsEnumDecl();
11936 bool SignedEnum = ED->getNumNegativeBits() > 0;
11943 unsigned DiagID = 0;
11944 if (SignedEnum && !SignedBitfield) {
11947 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11949 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11950 }
else if (SignedBitfield && !SignedEnum &&
11951 ED->getNumPositiveBits() == FieldWidth) {
11954 ? diag::warn_signed_bitfield_enum_conversion
11955 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11958 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11963 << SignedEnum << TypeRange;
11965 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11972 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11973 ED->getNumNegativeBits())
11974 : ED->getNumPositiveBits();
11977 if (BitsNeeded > FieldWidth) {
11981 ? diag::warn_bitfield_too_small_for_enum
11982 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11983 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11987 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11995 llvm::APSInt
Value = Result.Val.getInt();
11997 unsigned OriginalWidth =
Value.getBitWidth();
12003 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12004 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12011 if (!
Value.isSigned() ||
Value.isNegative())
12012 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12013 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12014 OriginalWidth =
Value.getSignificantBits();
12016 if (OriginalWidth <= FieldWidth)
12020 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12024 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12025 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12029 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12031 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12032 ? diag::warn_impcast_single_bit_bitield_precision_constant
12033 : diag::warn_impcast_bitfield_precision_constant)
12034 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12035 <<
Init->getSourceRange();
12067 bool PruneControlFlow =
false) {
12074 if (
T.hasAddressSpace())
12076 if (PruneControlFlow) {
12090 bool PruneControlFlow =
false) {
12097 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12102 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12103 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12108 llvm::APFloat
Value(0.0);
12114 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12119 diag::warn_impcast_float_integer, PruneWarnings);
12122 bool isExact =
false;
12125 T->hasUnsignedIntegerRepresentation());
12126 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12127 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12135 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12136 precision = (precision * 59 + 195) / 196;
12137 Value.toString(PrettySourceValue, precision);
12141 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12142 << PrettySourceValue);
12145 if (Result == llvm::APFloat::opOK && isExact) {
12146 if (IsLiteral)
return;
12147 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12153 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12156 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12157 : diag::warn_impcast_float_to_integer_out_of_range,
12160 unsigned DiagID = 0;
12163 DiagID = diag::warn_impcast_literal_float_to_integer;
12164 }
else if (IntegerValue == 0) {
12165 if (
Value.isZero()) {
12167 diag::warn_impcast_float_integer, PruneWarnings);
12170 DiagID = diag::warn_impcast_float_to_integer_zero;
12172 if (IntegerValue.isUnsigned()) {
12173 if (!IntegerValue.isMaxValue()) {
12175 diag::warn_impcast_float_integer, PruneWarnings);
12178 if (!IntegerValue.isMaxSignedValue() &&
12179 !IntegerValue.isMinSignedValue()) {
12181 diag::warn_impcast_float_integer, PruneWarnings);
12185 DiagID = diag::warn_impcast_float_to_integer;
12190 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12192 IntegerValue.toString(PrettyTargetValue);
12194 if (PruneWarnings) {
12197 << E->
getType() <<
T.getUnqualifiedType()
12198 << PrettySourceValue << PrettyTargetValue
12202 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12211 "Must be compound assignment operation");
12222 ->getComputationResultType()
12229 if (ResultBT->isInteger())
12231 E->
getExprLoc(), diag::warn_impcast_float_integer);
12233 if (!ResultBT->isFloatingPoint())
12242 diag::warn_impcast_float_result_precision);
12247 if (!Range.Width)
return "0";
12249 llvm::APSInt ValueInRange =
Value;
12250 ValueInRange.setIsSigned(!Range.NonNegative);
12251 ValueInRange = ValueInRange.trunc(Range.Width);
12252 return toString(ValueInRange, 10);
12262 const Type *Source =
12264 if (
Target->isDependentType())
12267 const auto *FloatCandidateBT =
12268 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12269 const Type *BoolCandidateType = ToBool ?
Target : Source;
12272 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12277 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12283 S, TheCall->
getArg(I - 1),
false));
12285 S, TheCall->
getArg(I + 1),
false));
12290 diag::warn_impcast_floating_point_to_bool);
12305 if (!IsGNUNullExpr && !HasNullPtrType)
12309 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12310 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12313 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12326 if (IsGNUNullExpr && Loc.
isMacroID()) {
12329 if (MacroName ==
"NULL")
12337 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12351 const char FirstLiteralCharacter =
12353 if (FirstLiteralCharacter ==
'0')
12359 if (CC.
isValid() &&
T->isCharType()) {
12360 const char FirstContextCharacter =
12362 if (FirstContextCharacter ==
'{')
12370 const auto *IL = dyn_cast<IntegerLiteral>(E);
12372 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12373 if (UO->getOpcode() == UO_Minus)
12374 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12385 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12389 if (Opc == BO_Shl) {
12392 if (LHS && LHS->getValue() == 0)
12393 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12395 RHS->getValue().isNonNegative() &&
12397 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12398 << (Result.Val.getInt() != 0);
12400 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12407 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12412 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12413 (RHS->getValue() == 0 || RHS->getValue() == 1))
12416 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12417 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12425 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12431 if (Source->isChar16Type() &&
Target->isChar32Type())
12437 llvm::APSInt
Value(32);
12438 Value = Result.Val.getInt();
12439 bool IsASCII =
Value <= 0x7F;
12440 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12441 bool ConversionPreservesSemantics =
12442 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12444 if (!ConversionPreservesSemantics) {
12445 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12446 const llvm::APSInt &
Value) {
12447 if (
T->isChar8Type())
12448 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12449 if (
T->isChar16Type())
12450 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12451 assert(
T->isChar32Type());
12452 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12455 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12464 LosesPrecision ? diag::warn_impcast_unicode_precision
12465 : diag::warn_impcast_unicode_char_type);
12470 From =
Context.getCanonicalType(From);
12471 To =
Context.getCanonicalType(To);
12474 From = MaybePointee;
12481 if (FromFn->getCFIUncheckedCalleeAttr() &&
12482 !ToFn->getCFIUncheckedCalleeAttr())
12490 bool *ICContext,
bool IsListInit) {
12495 if (Source ==
Target)
return;
12496 if (
Target->isDependentType())
return;
12506 if (Source->isAtomicType())
12510 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12516 diag::warn_impcast_string_literal_to_bool);
12522 diag::warn_impcast_objective_c_literal_to_bool);
12524 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12534 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12537 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12539 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12548 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12550 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12555 if (
Target->isSveVLSBuiltinType() &&
12562 if (
Target->isRVVVLSBuiltinType() &&
12572 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12579 diag::warn_hlsl_impcast_vector_truncation);
12591 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12592 Target = VecTy->getElementType().getTypePtr();
12602 ? diag::err_impcast_complex_scalar
12603 : diag::warn_impcast_complex_scalar);
12610 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12616 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12619 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12621 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12663 else if (Order < 0) {
12673 if (TargetBT && TargetBT->
isInteger()) {
12700 diag::warn_impcast_floating_point_to_bool);
12708 if (Source->isFixedPointType()) {
12709 if (
Target->isUnsaturatedFixedPointType()) {
12713 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12714 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12715 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12718 PDiag(diag::warn_impcast_fixed_point_range)
12719 <<
Value.toString() <<
T
12725 }
else if (
Target->isIntegerType()) {
12729 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12732 llvm::APSInt IntResult = FXResult.convertToInt(
12733 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12738 PDiag(diag::warn_impcast_fixed_point_range)
12739 << FXResult.toString() <<
T
12746 }
else if (
Target->isUnsaturatedFixedPointType()) {
12747 if (Source->isIntegerType()) {
12754 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12759 PDiag(diag::warn_impcast_fixed_point_range)
12780 unsigned int SourcePrecision =
SourceRange->Width;
12784 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12787 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12788 SourcePrecision > TargetPrecision) {
12790 if (std::optional<llvm::APSInt> SourceInt =
12795 llvm::APFloat TargetFloatValue(
12797 llvm::APFloat::opStatus ConversionStatus =
12798 TargetFloatValue.convertFromAPInt(
12800 llvm::APFloat::rmNearestTiesToEven);
12802 if (ConversionStatus != llvm::APFloat::opOK) {
12804 SourceInt->toString(PrettySourceValue, 10);
12806 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12810 PDiag(diag::warn_impcast_integer_float_precision_constant)
12811 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12817 diag::warn_impcast_integer_float_precision);
12826 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12831 if (
Target->isBooleanType())
12835 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12839 if (!Source->isIntegerType() || !
Target->isIntegerType())
12844 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12847 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
12850 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12855 if (!LikelySourceRange)
12858 IntRange SourceTypeRange =
12859 IntRange::forTargetOfCanonicalType(
Context, Source);
12860 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12862 if (LikelySourceRange->Width > TargetRange.Width) {
12868 llvm::APSInt
Value(32);
12878 PDiag(diag::warn_impcast_integer_precision_constant)
12879 << PrettySourceValue << PrettyTargetValue
12889 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12890 if (UO->getOpcode() == UO_Minus)
12892 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12895 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
12899 diag::warn_impcast_integer_precision);
12902 if (TargetRange.Width > SourceTypeRange.Width) {
12903 if (
auto *UO = dyn_cast<UnaryOperator>(E))
12904 if (UO->getOpcode() == UO_Minus)
12905 if (Source->isUnsignedIntegerType()) {
12906 if (
Target->isUnsignedIntegerType())
12908 diag::warn_impcast_high_order_zero_bits);
12909 if (
Target->isSignedIntegerType())
12911 diag::warn_impcast_nonnegative_result);
12915 if (TargetRange.Width == LikelySourceRange->Width &&
12916 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12917 Source->isSignedIntegerType()) {
12931 PDiag(diag::warn_impcast_integer_precision_constant)
12932 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12942 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12943 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12944 LikelySourceRange->Width == TargetRange.Width))) {
12948 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12950 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
12954 unsigned DiagID = diag::warn_impcast_integer_sign;
12962 DiagID = diag::warn_impcast_integer_sign_conditional;
12979 Source =
Context.getCanonicalType(SourceType).getTypePtr();
12981 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
12982 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
12983 if (SourceEnum->getDecl()->hasNameForLinkage() &&
12984 TargetEnum->getDecl()->hasNameForLinkage() &&
12985 SourceEnum != TargetEnum) {
12990 diag::warn_impcast_different_enum_types);
13004 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13017 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13018 TrueExpr = BCO->getCommon();
13020 bool Suspicious =
false;
13024 if (
T->isBooleanType())
13029 if (!Suspicious)
return;
13032 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13039 Suspicious =
false;
13044 E->
getType(), CC, &Suspicious);
13061struct AnalyzeImplicitConversionsWorkItem {
13070 bool ExtraCheckForImplicitConversion,
13073 WorkList.push_back({E, CC,
false});
13075 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13082 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13084 Expr *OrigE = Item.E;
13103 Expr *SourceExpr = E;
13108 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13109 if (
auto *Src = OVE->getSourceExpr())
13112 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13113 if (UO->getOpcode() == UO_Not &&
13114 UO->getSubExpr()->isKnownToHaveBooleanValue())
13115 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13119 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13120 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13121 BO->getLHS()->isKnownToHaveBooleanValue() &&
13122 BO->getRHS()->isKnownToHaveBooleanValue() &&
13123 BO->getLHS()->HasSideEffects(S.
Context) &&
13124 BO->getRHS()->HasSideEffects(S.
Context)) {
13135 if (SR.str() ==
"&" || SR.str() ==
"|") {
13137 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13138 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13141 BO->getOperatorLoc(),
13142 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13143 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13145 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13163 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13169 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13184 for (
auto *SE : POE->semantics())
13185 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13186 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13190 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13191 E = CE->getSubExpr();
13197 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13198 if (InitListE->getNumInits() == 1) {
13199 E = InitListE->getInit(0);
13206 WorkList.push_back({E, CC, IsListInit});
13210 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13211 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13215 if (OutArgE->isInOut())
13216 WorkList.push_back(
13217 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13218 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13224 if (BO->isComparisonOp())
13228 if (BO->getOpcode() == BO_Assign)
13231 if (BO->isAssignmentOp())
13247 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13249 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13253 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13254 if (ChildExpr == CSE->getOperand())
13260 if (IsLogicalAndOperator &&
13265 WorkList.push_back({ChildExpr, CC, IsListInit});
13279 if (
U->getOpcode() == UO_LNot) {
13281 }
else if (
U->getOpcode() != UO_AddrOf) {
13282 if (
U->getSubExpr()->getType()->isAtomicType())
13283 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13284 diag::warn_atomic_implicit_seq_cst);
13295 WorkList.push_back({OrigE, CC, IsListInit});
13296 while (!WorkList.empty())
13308 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13311 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13312 if (!M->getMemberDecl()->getType()->isReferenceType())
13314 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13315 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13317 FD =
Call->getDirectCallee();
13326 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13340 if (
SM.isMacroBodyExpansion(Loc))
13342 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13366 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13367 : diag::warn_this_bool_conversion;
13372 bool IsAddressOf =
false;
13374 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13375 if (UO->getOpcode() != UO_AddrOf)
13377 IsAddressOf =
true;
13378 E = UO->getSubExpr();
13382 unsigned DiagID = IsCompare
13383 ? diag::warn_address_of_reference_null_compare
13384 : diag::warn_address_of_reference_bool_conversion;
13392 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13395 llvm::raw_string_ostream S(Str);
13397 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13398 : diag::warn_cast_nonnull_to_bool;
13401 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13406 if (
auto *Callee =
Call->getDirectCallee()) {
13407 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13408 ComplainAboutNonnullParamOrCall(A);
13417 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13418 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13419 MRecordDecl && MRecordDecl->isLambda()) {
13422 << MRecordDecl->getSourceRange() << Range << IsEqual;
13432 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13433 D = M->getMemberDecl();
13441 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13444 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13445 ComplainAboutNonnullParamOrCall(A);
13449 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13453 auto ParamIter = llvm::find(FD->
parameters(), PV);
13455 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13459 ComplainAboutNonnullParamOrCall(
NonNull);
13464 if (ArgNo.getASTIndex() == ParamNo) {
13465 ComplainAboutNonnullParamOrCall(
NonNull);
13475 const bool IsArray =
T->isArrayType();
13476 const bool IsFunction =
T->isFunctionType();
13479 if (IsAddressOf && IsFunction) {
13484 if (!IsAddressOf && !IsFunction && !IsArray)
13489 llvm::raw_string_ostream S(Str);
13492 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13493 : diag::warn_impcast_pointer_to_bool;
13500 DiagType = AddressOf;
13501 else if (IsFunction)
13502 DiagType = FunctionPointer;
13504 DiagType = ArrayPointer;
13506 llvm_unreachable(
"Could not determine diagnostic.");
13508 << Range << IsEqual;
13521 if (ReturnType.
isNull())
13559 CheckArrayAccess(E);
13569void Sema::CheckForIntOverflow (
const Expr *E) {
13571 SmallVector<const Expr *, 2> Exprs(1, E);
13574 const Expr *OriginalE = Exprs.pop_back_val();
13582 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13583 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13586 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13587 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13588 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13590 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13591 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13592 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13593 Exprs.push_back(Temporary->getSubExpr());
13594 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13595 Exprs.push_back(Array->getIdx());
13596 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13597 Exprs.push_back(Compound->getInitializer());
13598 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13599 New &&
New->isArray()) {
13600 if (
auto ArraySize =
New->getArraySize())
13601 Exprs.push_back(*ArraySize);
13602 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13603 Exprs.push_back(MTE->getSubExpr());
13604 }
while (!Exprs.empty());
13612 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13619 class SequenceTree {
13621 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13622 unsigned Parent : 31;
13623 LLVM_PREFERRED_TYPE(
bool)
13624 unsigned Merged : 1;
13626 SmallVector<Value, 8> Values;
13632 friend class SequenceTree;
13636 explicit Seq(
unsigned N) : Index(N) {}
13639 Seq() : Index(0) {}
13642 SequenceTree() { Values.push_back(
Value(0)); }
13643 Seq root()
const {
return Seq(0); }
13648 Seq allocate(
Seq Parent) {
13649 Values.push_back(
Value(Parent.Index));
13650 return Seq(Values.size() - 1);
13654 void merge(
Seq S) {
13655 Values[S.Index].Merged =
true;
13661 bool isUnsequenced(
Seq Cur,
Seq Old) {
13662 unsigned C = representative(Cur.Index);
13663 unsigned Target = representative(Old.Index);
13667 C = Values[
C].Parent;
13674 unsigned representative(
unsigned K) {
13675 if (Values[K].Merged)
13677 return Values[K].Parent = representative(Values[K].Parent);
13683 using Object =
const NamedDecl *;
13697 UK_ModAsSideEffect,
13699 UK_Count = UK_ModAsSideEffect + 1
13705 const Expr *UsageExpr =
nullptr;
13706 SequenceTree::Seq
Seq;
13712 Usage Uses[UK_Count];
13715 bool Diagnosed =
false;
13719 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13727 UsageInfoMap UsageMap;
13730 SequenceTree::Seq Region;
13734 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13738 SmallVectorImpl<const Expr *> &WorkList;
13745 struct SequencedSubexpression {
13746 SequencedSubexpression(SequenceChecker &
Self)
13747 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13748 Self.ModAsSideEffect = &ModAsSideEffect;
13751 ~SequencedSubexpression() {
13752 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13756 UsageInfo &UI =
Self.UsageMap[M.first];
13757 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13758 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13759 SideEffectUsage = M.second;
13761 Self.ModAsSideEffect = OldModAsSideEffect;
13764 SequenceChecker &
Self;
13765 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13766 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13773 class EvaluationTracker {
13775 EvaluationTracker(SequenceChecker &
Self)
13777 Self.EvalTracker =
this;
13780 ~EvaluationTracker() {
13781 Self.EvalTracker = Prev;
13783 Prev->EvalOK &= EvalOK;
13786 bool evaluate(
const Expr *E,
bool &
Result) {
13791 Self.SemaRef.isConstantEvaluatedContext());
13796 SequenceChecker &
Self;
13797 EvaluationTracker *Prev;
13798 bool EvalOK =
true;
13799 } *EvalTracker =
nullptr;
13803 Object getObject(
const Expr *E,
bool Mod)
const {
13805 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13806 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13807 return getObject(UO->getSubExpr(), Mod);
13808 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13809 if (BO->getOpcode() == BO_Comma)
13810 return getObject(BO->getRHS(), Mod);
13811 if (Mod && BO->isAssignmentOp())
13812 return getObject(BO->getLHS(), Mod);
13813 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13816 return ME->getMemberDecl();
13817 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13826 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13828 Usage &U = UI.Uses[UK];
13829 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
13833 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13834 ModAsSideEffect->push_back(std::make_pair(O, U));
13836 U.UsageExpr = UsageExpr;
13846 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13847 UsageKind OtherKind,
bool IsModMod) {
13851 const Usage &U = UI.Uses[OtherKind];
13852 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
13855 const Expr *Mod = U.UsageExpr;
13856 const Expr *ModOrUse = UsageExpr;
13857 if (OtherKind == UK_Use)
13858 std::swap(Mod, ModOrUse);
13862 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13863 : diag::warn_unsequenced_mod_use)
13864 << O << SourceRange(ModOrUse->
getExprLoc()));
13865 UI.Diagnosed =
true;
13894 void notePreUse(Object O,
const Expr *UseExpr) {
13895 UsageInfo &UI = UsageMap[O];
13897 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13900 void notePostUse(Object O,
const Expr *UseExpr) {
13901 UsageInfo &UI = UsageMap[O];
13902 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13904 addUsage(O, UI, UseExpr, UK_Use);
13907 void notePreMod(Object O,
const Expr *ModExpr) {
13908 UsageInfo &UI = UsageMap[O];
13910 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13911 checkUsage(O, UI, ModExpr, UK_Use,
false);
13914 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13915 UsageInfo &UI = UsageMap[O];
13916 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13918 addUsage(O, UI, ModExpr, UK);
13922 SequenceChecker(Sema &S,
const Expr *E,
13923 SmallVectorImpl<const Expr *> &WorkList)
13924 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
13928 (void)this->WorkList;
13931 void VisitStmt(
const Stmt *S) {
13935 void VisitExpr(
const Expr *E) {
13937 Base::VisitStmt(E);
13940 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
13941 for (
auto *Sub : CSE->
children()) {
13942 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13957 void VisitCastExpr(
const CastExpr *E) {
13969 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13970 const Expr *SequencedAfter) {
13971 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
13972 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
13973 SequenceTree::Seq OldRegion = Region;
13976 SequencedSubexpression SeqBefore(*
this);
13977 Region = BeforeRegion;
13978 Visit(SequencedBefore);
13981 Region = AfterRegion;
13982 Visit(SequencedAfter);
13984 Region = OldRegion;
13986 Tree.merge(BeforeRegion);
13987 Tree.merge(AfterRegion);
13990 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
13995 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14002 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14003 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14004 void VisitBinPtrMem(
const BinaryOperator *BO) {
14009 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14016 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14017 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14018 void VisitBinShlShr(
const BinaryOperator *BO) {
14022 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14029 void VisitBinComma(
const BinaryOperator *BO) {
14034 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14037 void VisitBinAssign(
const BinaryOperator *BO) {
14038 SequenceTree::Seq RHSRegion;
14039 SequenceTree::Seq LHSRegion;
14041 RHSRegion = Tree.allocate(Region);
14042 LHSRegion = Tree.allocate(Region);
14044 RHSRegion = Region;
14045 LHSRegion = Region;
14047 SequenceTree::Seq OldRegion = Region;
14063 SequencedSubexpression SeqBefore(*
this);
14064 Region = RHSRegion;
14068 Region = LHSRegion;
14072 notePostUse(O, BO);
14076 Region = LHSRegion;
14080 notePostUse(O, BO);
14082 Region = RHSRegion;
14090 Region = OldRegion;
14094 : UK_ModAsSideEffect);
14096 Tree.merge(RHSRegion);
14097 Tree.merge(LHSRegion);
14101 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14102 VisitBinAssign(CAO);
14105 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14106 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14107 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14110 return VisitExpr(UO);
14118 : UK_ModAsSideEffect);
14121 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14122 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14123 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14126 return VisitExpr(UO);
14130 notePostMod(O, UO, UK_ModAsSideEffect);
14133 void VisitBinLOr(
const BinaryOperator *BO) {
14139 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14140 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14141 SequenceTree::Seq OldRegion = Region;
14143 EvaluationTracker Eval(*
this);
14145 SequencedSubexpression Sequenced(*
this);
14146 Region = LHSRegion;
14153 bool EvalResult =
false;
14154 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14155 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14156 if (ShouldVisitRHS) {
14157 Region = RHSRegion;
14161 Region = OldRegion;
14162 Tree.merge(LHSRegion);
14163 Tree.merge(RHSRegion);
14166 void VisitBinLAnd(
const BinaryOperator *BO) {
14172 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14173 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14174 SequenceTree::Seq OldRegion = Region;
14176 EvaluationTracker Eval(*
this);
14178 SequencedSubexpression Sequenced(*
this);
14179 Region = LHSRegion;
14185 bool EvalResult =
false;
14186 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14187 bool ShouldVisitRHS = !EvalOK || EvalResult;
14188 if (ShouldVisitRHS) {
14189 Region = RHSRegion;
14193 Region = OldRegion;
14194 Tree.merge(LHSRegion);
14195 Tree.merge(RHSRegion);
14198 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14203 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14219 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14220 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14221 SequenceTree::Seq OldRegion = Region;
14223 EvaluationTracker Eval(*
this);
14225 SequencedSubexpression Sequenced(*
this);
14226 Region = ConditionRegion;
14236 bool EvalResult =
false;
14237 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14238 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14239 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14240 if (ShouldVisitTrueExpr) {
14241 Region = TrueRegion;
14244 if (ShouldVisitFalseExpr) {
14245 Region = FalseRegion;
14249 Region = OldRegion;
14250 Tree.merge(ConditionRegion);
14251 Tree.merge(TrueRegion);
14252 Tree.merge(FalseRegion);
14255 void VisitCallExpr(
const CallExpr *CE) {
14267 SequencedSubexpression Sequenced(*
this);
14272 SequenceTree::Seq CalleeRegion;
14273 SequenceTree::Seq OtherRegion;
14274 if (SemaRef.getLangOpts().CPlusPlus17) {
14275 CalleeRegion = Tree.allocate(Region);
14276 OtherRegion = Tree.allocate(Region);
14278 CalleeRegion = Region;
14279 OtherRegion = Region;
14281 SequenceTree::Seq OldRegion = Region;
14284 Region = CalleeRegion;
14286 SequencedSubexpression Sequenced(*this);
14287 Visit(CE->getCallee());
14289 Visit(CE->getCallee());
14293 Region = OtherRegion;
14297 Region = OldRegion;
14299 Tree.merge(CalleeRegion);
14300 Tree.merge(OtherRegion);
14318 return VisitCallExpr(CXXOCE);
14329 case OO_MinusEqual:
14331 case OO_SlashEqual:
14332 case OO_PercentEqual:
14333 case OO_CaretEqual:
14336 case OO_LessLessEqual:
14337 case OO_GreaterGreaterEqual:
14338 SequencingKind = RHSBeforeLHS;
14342 case OO_GreaterGreater:
14348 SequencingKind = LHSBeforeRHS;
14352 SequencingKind = LHSBeforeRest;
14356 SequencingKind = NoSequencing;
14360 if (SequencingKind == NoSequencing)
14361 return VisitCallExpr(CXXOCE);
14364 SequencedSubexpression Sequenced(*
this);
14367 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14368 "Should only get there with C++17 and above!");
14369 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14370 "Should only get there with an overloaded binary operator"
14371 " or an overloaded call operator!");
14373 if (SequencingKind == LHSBeforeRest) {
14374 assert(CXXOCE->getOperator() == OO_Call &&
14375 "We should only have an overloaded call operator here!");
14384 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14385 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14386 SequenceTree::Seq OldRegion = Region;
14388 assert(CXXOCE->getNumArgs() >= 1 &&
14389 "An overloaded call operator must have at least one argument"
14390 " for the postfix-expression!");
14391 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14392 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14393 CXXOCE->getNumArgs() - 1);
14397 Region = PostfixExprRegion;
14398 SequencedSubexpression Sequenced(*this);
14399 Visit(PostfixExpr);
14403 Region = ArgsRegion;
14404 for (const Expr *Arg : Args)
14407 Region = OldRegion;
14408 Tree.merge(PostfixExprRegion);
14409 Tree.merge(ArgsRegion);
14411 assert(CXXOCE->getNumArgs() == 2 &&
14412 "Should only have two arguments here!");
14413 assert((SequencingKind == LHSBeforeRHS ||
14414 SequencingKind == RHSBeforeLHS) &&
14415 "Unexpected sequencing kind!");
14419 const Expr *E1 = CXXOCE->getArg(0);
14420 const Expr *E2 = CXXOCE->getArg(1);
14421 if (SequencingKind == RHSBeforeLHS)
14424 return VisitSequencedExpressions(E1, E2);
14431 SequencedSubexpression Sequenced(*
this);
14434 return VisitExpr(CCE);
14437 SequenceExpressionsInOrder(
14443 return VisitExpr(ILE);
14446 SequenceExpressionsInOrder(ILE->
inits());
14458 SequenceTree::Seq Parent = Region;
14459 for (
const Expr *E : ExpressionList) {
14462 Region = Tree.allocate(Parent);
14463 Elts.push_back(Region);
14469 for (
unsigned I = 0; I < Elts.size(); ++I)
14470 Tree.merge(Elts[I]);
14474SequenceChecker::UsageInfo::UsageInfo() =
default;
14478void Sema::CheckUnsequencedOperations(
const Expr *E) {
14479 SmallVector<const Expr *, 8> WorkList;
14480 WorkList.push_back(E);
14481 while (!WorkList.empty()) {
14482 const Expr *Item = WorkList.pop_back_val();
14483 SequenceChecker(*
this, Item, WorkList);
14488 bool IsConstexpr) {
14491 CheckImplicitConversions(E, CheckLoc);
14493 CheckUnsequencedOperations(E);
14495 CheckForIntOverflow(E);
14508 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14512 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14516 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14530 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14534 bool CheckParameterNames) {
14535 bool HasInvalidParm =
false;
14537 assert(Param &&
"null in a parameter list");
14546 if (!Param->isInvalidDecl() &&
14548 diag::err_typecheck_decl_incomplete_type) ||
14550 diag::err_abstract_type_in_decl,
14552 Param->setInvalidDecl();
14553 HasInvalidParm =
true;
14558 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14562 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14570 QualType PType = Param->getOriginalType();
14578 if (!Param->isInvalidDecl()) {
14579 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14580 if (!ClassDecl->isInvalidDecl() &&
14581 !ClassDecl->hasIrrelevantDestructor() &&
14582 !ClassDecl->isDependentContext() &&
14583 ClassDecl->isParamDestroyedInCallee()) {
14595 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14596 if (!Param->getType().isConstQualified())
14597 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14601 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14606 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14607 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14612 if (!Param->isInvalidDecl() &&
14613 Param->getOriginalType()->isWebAssemblyTableType()) {
14614 Param->setInvalidDecl();
14615 HasInvalidParm =
true;
14616 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14620 return HasInvalidParm;
14623std::optional<std::pair<
14632static std::pair<CharUnits, CharUnits>
14640 if (
Base->isVirtual()) {
14647 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14654 DerivedType =
Base->getType();
14657 return std::make_pair(BaseAlignment, Offset);
14661static std::optional<std::pair<CharUnits, CharUnits>>
14667 return std::nullopt;
14672 return std::nullopt;
14676 CharUnits Offset = EltSize * IdxRes->getExtValue();
14679 return std::make_pair(P->first, P->second + Offset);
14685 return std::make_pair(
14686 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14692std::optional<std::pair<
14700 case Stmt::CStyleCastExprClass:
14701 case Stmt::CXXStaticCastExprClass:
14702 case Stmt::ImplicitCastExprClass: {
14704 const Expr *From = CE->getSubExpr();
14705 switch (CE->getCastKind()) {
14710 case CK_UncheckedDerivedToBase:
14711 case CK_DerivedToBase: {
14721 case Stmt::ArraySubscriptExprClass: {
14726 case Stmt::DeclRefExprClass: {
14730 if (!VD->getType()->isReferenceType()) {
14732 if (VD->hasDependentAlignment())
14741 case Stmt::MemberExprClass: {
14743 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14747 std::optional<std::pair<CharUnits, CharUnits>> P;
14756 return std::make_pair(P->first,
14759 case Stmt::UnaryOperatorClass: {
14769 case Stmt::BinaryOperatorClass: {
14781 return std::nullopt;
14786std::optional<std::pair<
14795 case Stmt::CStyleCastExprClass:
14796 case Stmt::CXXStaticCastExprClass:
14797 case Stmt::ImplicitCastExprClass: {
14799 const Expr *From = CE->getSubExpr();
14800 switch (CE->getCastKind()) {
14805 case CK_ArrayToPointerDecay:
14807 case CK_UncheckedDerivedToBase:
14808 case CK_DerivedToBase: {
14818 case Stmt::CXXThisExprClass: {
14823 case Stmt::UnaryOperatorClass: {
14829 case Stmt::BinaryOperatorClass: {
14838 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14839 std::swap(LHS, RHS);
14849 return std::nullopt;
14854 std::optional<std::pair<CharUnits, CharUnits>> P =
14858 return P->first.alignmentAtOffset(P->second);
14876 if (!DestPtr)
return;
14882 if (DestAlign.
isOne())
return;
14886 if (!SrcPtr)
return;
14897 if (SrcAlign >= DestAlign)
return;
14902 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14906void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14908 bool AllowOnePastEnd,
bool IndexNegated) {
14917 const Type *EffectiveType =
14921 Context.getAsConstantArrayType(BaseExpr->
getType());
14924 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14926 const Type *BaseType =
14928 bool IsUnboundedArray =
14930 Context, StrictFlexArraysLevel,
14933 (!IsUnboundedArray && BaseType->isDependentType()))
14941 if (IndexNegated) {
14942 index.setIsUnsigned(
false);
14946 if (IsUnboundedArray) {
14949 if (
index.isUnsigned() || !
index.isNegative()) {
14951 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14953 if (
index.getBitWidth() < AddrBits)
14955 std::optional<CharUnits> ElemCharUnits =
14956 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14959 if (!ElemCharUnits || ElemCharUnits->isZero())
14961 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
14966 if (
index.getActiveBits() <= AddrBits) {
14968 llvm::APInt Product(
index);
14970 Product = Product.umul_ov(ElemBytes, Overflow);
14971 if (!Overflow && Product.getActiveBits() <= AddrBits)
14977 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14978 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14980 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14981 MaxElems = MaxElems.udiv(ElemBytes);
14984 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14985 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14990 PDiag(DiagID) << index << AddrBits
14991 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14992 << ElemBytes << MaxElems
14993 << MaxElems.getZExtValue()
14996 const NamedDecl *ND =
nullptr;
14998 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15000 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15002 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15003 ND = ME->getMemberDecl();
15007 PDiag(diag::note_array_declared_here) << ND);
15012 if (index.isUnsigned() || !index.isNegative()) {
15022 llvm::APInt size = ArrayTy->
getSize();
15024 if (BaseType != EffectiveType) {
15032 if (!ptrarith_typesize)
15033 ptrarith_typesize =
Context.getCharWidth();
15035 if (ptrarith_typesize != array_typesize) {
15037 uint64_t ratio = array_typesize / ptrarith_typesize;
15041 if (ptrarith_typesize * ratio == array_typesize)
15042 size *= llvm::APInt(size.getBitWidth(), ratio);
15046 if (size.getBitWidth() > index.getBitWidth())
15047 index = index.zext(size.getBitWidth());
15048 else if (size.getBitWidth() < index.getBitWidth())
15049 size = size.zext(index.getBitWidth());
15055 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15062 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15064 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15065 SourceLocation IndexLoc =
15067 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15072 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15073 : diag::warn_ptr_arith_exceeds_bounds;
15074 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15075 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15079 << index << ArrayTy->
desugar() << CastMsg
15082 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15084 DiagID = diag::warn_ptr_arith_precedes_bounds;
15085 if (index.isNegative()) index = -index;
15092 const NamedDecl *ND =
nullptr;
15094 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15096 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15098 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15099 ND = ME->getMemberDecl();
15103 PDiag(diag::note_array_declared_here) << ND);
15106void Sema::CheckArrayAccess(
const Expr *
expr) {
15107 int AllowOnePastEnd = 0;
15109 expr =
expr->IgnoreParenImpCasts();
15110 switch (
expr->getStmtClass()) {
15111 case Stmt::ArraySubscriptExprClass: {
15114 AllowOnePastEnd > 0);
15118 case Stmt::MemberExprClass: {
15122 case Stmt::ArraySectionExprClass: {
15128 nullptr, AllowOnePastEnd > 0);
15131 case Stmt::UnaryOperatorClass: {
15147 case Stmt::ConditionalOperatorClass: {
15149 if (
const Expr *lhs = cond->
getLHS())
15150 CheckArrayAccess(lhs);
15151 if (
const Expr *rhs = cond->
getRHS())
15152 CheckArrayAccess(rhs);
15155 case Stmt::CXXOperatorCallExprClass: {
15157 for (
const auto *Arg : OCE->arguments())
15158 CheckArrayAccess(Arg);
15168 Expr *RHS,
bool isProperty) {
15180 S.
Diag(Loc, diag::warn_arc_literal_assign)
15182 << (isProperty ? 0 : 1)
15190 Expr *RHS,
bool isProperty) {
15193 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15194 S.
Diag(Loc, diag::warn_arc_retained_assign)
15196 << (isProperty ? 0 : 1)
15200 RHS =
cast->getSubExpr();
15242 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15271 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15272 Diag(Loc, diag::warn_arc_retained_property_assign)
15276 RHS =
cast->getSubExpr();
15299 bool StmtLineInvalid;
15300 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15302 if (StmtLineInvalid)
15305 bool BodyLineInvalid;
15306 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15308 if (BodyLineInvalid)
15312 if (StmtLine != BodyLine)
15327 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15336 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15340 const Stmt *PossibleBody) {
15346 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15347 StmtLoc = FS->getRParenLoc();
15348 Body = FS->getBody();
15349 DiagID = diag::warn_empty_for_body;
15350 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15351 StmtLoc = WS->getRParenLoc();
15352 Body = WS->getBody();
15353 DiagID = diag::warn_empty_while_body;
15358 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15382 if (!ProbableTypo) {
15383 bool BodyColInvalid;
15384 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15386 if (BodyColInvalid)
15389 bool StmtColInvalid;
15392 if (StmtColInvalid)
15395 if (BodyCol > StmtCol)
15396 ProbableTypo =
true;
15399 if (ProbableTypo) {
15401 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15409 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15421 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15423 RHSExpr = CE->
getArg(0);
15424 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15425 CXXSCE && CXXSCE->isXValue())
15426 RHSExpr = CXXSCE->getSubExpr();
15430 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15431 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15434 if (LHSDeclRef && RHSDeclRef) {
15441 auto D =
Diag(OpLoc, diag::warn_self_move)
15457 const Expr *LHSBase = LHSExpr;
15458 const Expr *RHSBase = RHSExpr;
15459 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15460 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15461 if (!LHSME || !RHSME)
15464 while (LHSME && RHSME) {
15471 LHSME = dyn_cast<MemberExpr>(LHSBase);
15472 RHSME = dyn_cast<MemberExpr>(RHSBase);
15475 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15476 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15477 if (LHSDeclRef && RHSDeclRef) {
15484 Diag(OpLoc, diag::warn_self_move)
15491 Diag(OpLoc, diag::warn_self_move)
15515 bool AreUnionMembers =
false) {
15519 assert(((Field1Parent->isStructureOrClassType() &&
15520 Field2Parent->isStructureOrClassType()) ||
15521 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15522 "Can't evaluate layout compatibility between a struct field and a "
15524 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15525 (AreUnionMembers && Field1Parent->isUnionType())) &&
15526 "AreUnionMembers should be 'true' for union fields (only).");
15540 if (Bits1 != Bits2)
15544 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15545 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15548 if (!AreUnionMembers &&
15560 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15561 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15563 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15564 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15569 return isLayoutCompatible(C, F1, F2);
15580 for (
auto *Field1 : RD1->
fields()) {
15581 auto I = UnmatchedFields.begin();
15582 auto E = UnmatchedFields.end();
15584 for ( ; I != E; ++I) {
15586 bool Result = UnmatchedFields.erase(*I);
15596 return UnmatchedFields.empty();
15622 if (
C.hasSameType(T1, T2))
15631 if (TC1 == Type::Enum)
15633 if (TC1 == Type::Record) {
15652 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15683 const ValueDecl **VD, uint64_t *MagicValue,
15684 bool isConstantEvaluated) {
15692 case Stmt::UnaryOperatorClass: {
15701 case Stmt::DeclRefExprClass: {
15707 case Stmt::IntegerLiteralClass: {
15709 llvm::APInt MagicValueAPInt = IL->
getValue();
15710 if (MagicValueAPInt.getActiveBits() <= 64) {
15711 *MagicValue = MagicValueAPInt.getZExtValue();
15717 case Stmt::BinaryConditionalOperatorClass:
15718 case Stmt::ConditionalOperatorClass: {
15723 isConstantEvaluated)) {
15733 case Stmt::BinaryOperatorClass: {
15736 TypeExpr = BO->
getRHS();
15766 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15769 bool isConstantEvaluated) {
15770 FoundWrongKind =
false;
15775 uint64_t MagicValue;
15777 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15781 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15782 if (I->getArgumentKind() != ArgumentKind) {
15783 FoundWrongKind =
true;
15786 TypeInfo.Type = I->getMatchingCType();
15787 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15788 TypeInfo.MustBeNull = I->getMustBeNull();
15799 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15800 if (I == MagicValues->end())
15809 bool LayoutCompatible,
15811 if (!TypeTagForDatatypeMagicValues)
15812 TypeTagForDatatypeMagicValues.reset(
15813 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15816 (*TypeTagForDatatypeMagicValues)[Magic] =
15832 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15833 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15834 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15835 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15838void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15841 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
15842 bool IsPointerAttr = Attr->getIsPointer();
15845 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
15846 if (TypeTagIdxAST >= ExprArgs.size()) {
15847 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15848 << 0 << Attr->getTypeTagIdx().getSourceIndex();
15851 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15852 bool FoundWrongKind;
15855 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15857 if (FoundWrongKind)
15859 diag::warn_type_tag_for_datatype_wrong_kind)
15865 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
15866 if (ArgumentIdxAST >= ExprArgs.size()) {
15867 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15868 << 1 << Attr->getArgumentIdx().getSourceIndex();
15871 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15872 if (IsPointerAttr) {
15874 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15875 if (ICE->getType()->isVoidPointerType() &&
15876 ICE->getCastKind() == CK_BitCast)
15877 ArgumentExpr = ICE->getSubExpr();
15879 QualType ArgumentType = ArgumentExpr->
getType();
15885 if (TypeInfo.MustBeNull) {
15890 diag::warn_type_safety_null_pointer_required)
15898 QualType RequiredType = TypeInfo.Type;
15900 RequiredType =
Context.getPointerType(RequiredType);
15902 bool mismatch =
false;
15903 if (!TypeInfo.LayoutCompatible) {
15904 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
15925 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15926 << ArgumentType << ArgumentKind
15927 << TypeInfo.LayoutCompatible << RequiredType
15945 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15953 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
15959 auto &MisalignedMembersForExpr =
15961 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15962 if (MA != MisalignedMembersForExpr.end() &&
15963 (
T->isDependentType() ||
T->isIntegerType() ||
15964 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
15966 T->getPointeeType()) <= MA->Alignment))))
15967 MisalignedMembersForExpr.erase(MA);
15976 const auto *ME = dyn_cast<MemberExpr>(E);
15988 bool AnyIsPacked =
false;
15990 QualType BaseType = ME->getBase()->getType();
15991 if (BaseType->isDependentType())
15995 auto *RD = BaseType->castAsRecordDecl();
16000 auto *FD = dyn_cast<FieldDecl>(MD);
16006 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16007 ReverseMemberChain.push_back(FD);
16010 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16012 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16019 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16030 if (ExpectedAlignment.
isOne())
16035 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16036 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16040 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16044 if (DRE && !TopME->
isArrow()) {
16047 CompleteObjectAlignment =
16048 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16052 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16055 CompleteObjectAlignment < ExpectedAlignment) {
16066 for (
FieldDecl *FDI : ReverseMemberChain) {
16067 if (FDI->hasAttr<PackedAttr>() ||
16068 FDI->getParent()->hasAttr<PackedAttr>()) {
16070 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16076 assert(FD &&
"We did not find a packed FieldDecl!");
16077 Action(E, FD->
getParent(), FD, Alignment);
16081void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16082 using namespace std::placeholders;
16085 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16109bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16110 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16123 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16124 TheCall->
setType(VecTy0->getElementType());
16137 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16154 assert(!Args.empty() &&
"Should have at least one argument.");
16156 Expr *Arg0 = Args.front();
16159 auto EmitError = [&](
Expr *ArgI) {
16161 diag::err_typecheck_call_different_arg_types)
16162 << Arg0->
getType() << ArgI->getType();
16167 for (
Expr *ArgI : Args.drop_front())
16178 for (
Expr *ArgI : Args.drop_front()) {
16179 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16182 VecI->getElementType()) ||
16183 Vec0->getNumElements() != VecI->getNumElements()) {
16192std::optional<QualType>
16196 return std::nullopt;
16200 return std::nullopt;
16203 for (
int I = 0; I < 2; ++I) {
16207 return std::nullopt;
16208 Args[I] = Converted.
get();
16215 return std::nullopt;
16218 return std::nullopt;
16220 TheCall->
setArg(0, Args[0]);
16221 TheCall->
setArg(1, Args[1]);
16232 TheCall->
getArg(1), Loc) ||
16234 TheCall->
getArg(2), Loc))
16238 for (
int I = 0; I < 3; ++I) {
16243 Args[I] = Converted.
get();
16246 int ArgOrdinal = 1;
16247 for (
Expr *Arg : Args) {
16249 ArgTyRestr, ArgOrdinal++))
16256 for (
int I = 0; I < 3; ++I)
16257 TheCall->
setArg(I, Args[I]);
16263bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16275bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16284 diag::err_builtin_invalid_arg_type)
16285 << 1 << 2 << 1 << 1 << TyArg;
16299 Expr *Matrix = MatrixArg.
get();
16301 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16304 << 1 << 3 << 0 << 0
16311 QualType ResultType =
Context.getConstantMatrixType(
16312 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16315 TheCall->
setType(ResultType);
16318 TheCall->
setArg(0, Matrix);
16323static std::optional<unsigned>
16331 uint64_t
Dim =
Value->getZExtValue();
16350 unsigned PtrArgIdx = 0;
16351 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16352 Expr *RowsExpr = TheCall->
getArg(1);
16353 Expr *ColumnsExpr = TheCall->
getArg(2);
16354 Expr *StrideExpr = TheCall->
getArg(3);
16356 bool ArgError =
false;
16363 PtrExpr = PtrConv.
get();
16364 TheCall->
setArg(0, PtrExpr);
16371 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16372 QualType ElementTy;
16375 << PtrArgIdx + 1 << 0 << 5 << 0
16379 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16383 << PtrArgIdx + 1 << 0 << 5
16390 auto ApplyArgumentConversions = [
this](Expr *E) {
16399 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16401 RowsExpr = RowsConv.
get();
16402 TheCall->
setArg(1, RowsExpr);
16404 RowsExpr =
nullptr;
16406 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16408 ColumnsExpr = ColumnsConv.
get();
16409 TheCall->
setArg(2, ColumnsExpr);
16411 ColumnsExpr =
nullptr;
16422 std::optional<unsigned> MaybeRows;
16426 std::optional<unsigned> MaybeColumns;
16431 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16434 StrideExpr = StrideConv.
get();
16435 TheCall->
setArg(3, StrideExpr);
16438 if (std::optional<llvm::APSInt>
Value =
16441 if (Stride < *MaybeRows) {
16443 diag::err_builtin_matrix_stride_too_small);
16449 if (ArgError || !MaybeRows || !MaybeColumns)
16453 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16462 unsigned PtrArgIdx = 1;
16463 Expr *MatrixExpr = TheCall->
getArg(0);
16464 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16465 Expr *StrideExpr = TheCall->
getArg(2);
16467 bool ArgError =
false;
16473 MatrixExpr = MatrixConv.
get();
16474 TheCall->
setArg(0, MatrixExpr);
16481 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16484 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16492 PtrExpr = PtrConv.
get();
16493 TheCall->
setArg(1, PtrExpr);
16501 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16504 << PtrArgIdx + 1 << 0 << 5 << 0
16508 QualType ElementTy = PtrTy->getPointeeType();
16510 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16515 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16517 diag::err_builtin_matrix_pointer_arg_mismatch)
16518 << ElementTy << MatrixTy->getElementType();
16533 StrideExpr = StrideConv.
get();
16534 TheCall->
setArg(2, StrideExpr);
16539 if (std::optional<llvm::APSInt>
Value =
16542 if (Stride < MatrixTy->getNumRows()) {
16544 diag::err_builtin_matrix_stride_too_small);
16564 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16569 llvm::StringSet<> CalleeTCBs;
16570 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16571 CalleeTCBs.insert(A->getTCBName());
16572 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16573 CalleeTCBs.insert(A->getTCBName());
16577 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16578 StringRef CallerTCB = A->getTCBName();
16579 if (CalleeTCBs.count(CallerTCB) == 0) {
16580 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16581 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ConditionalOperator - The ?
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Expr * getOperand() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getBeginLoc() const
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isFlexibleArrayMemberLike(const ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
UnresolvedSetImpl::iterator iterator
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) const
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.