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_stpcpy:
1267 case Builtin::BIstpcpy:
1268 case Builtin::BI__builtin_strcpy:
1269 case Builtin::BIstrcpy: {
1270 DiagID = diag::warn_fortify_strlen_overflow;
1271 SourceSize = ComputeStrLenArgument(1);
1272 DestinationSize = ComputeSizeArgument(0);
1276 case Builtin::BI__builtin___stpcpy_chk:
1277 case Builtin::BI__builtin___strcpy_chk: {
1278 DiagID = diag::warn_fortify_strlen_overflow;
1279 SourceSize = ComputeStrLenArgument(1);
1280 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1281 IsChkVariant =
true;
1285 case Builtin::BIscanf:
1286 case Builtin::BIfscanf:
1287 case Builtin::BIsscanf: {
1288 unsigned FormatIndex = 1;
1289 unsigned DataIndex = 2;
1290 if (BuiltinID == Builtin::BIscanf) {
1295 const auto *FormatExpr =
1298 StringRef FormatStrRef;
1303 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1304 unsigned SourceSize) {
1305 DiagID = diag::warn_fortify_scanf_overflow;
1306 unsigned Index = ArgIndex + DataIndex;
1307 std::string FunctionName = GetFunctionName();
1309 PDiag(DiagID) << FunctionName << (Index + 1)
1310 << DestSize << SourceSize);
1313 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1314 return ComputeSizeArgument(Index + DataIndex);
1316 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1317 const char *FormatBytes = FormatStrRef.data();
1328 case Builtin::BIsprintf:
1329 case Builtin::BI__builtin___sprintf_chk: {
1330 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1333 StringRef FormatStrRef;
1336 EstimateSizeFormatHandler H(FormatStrRef);
1337 const char *FormatBytes = FormatStrRef.data();
1339 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1340 Context.getTargetInfo(),
false)) {
1341 DiagID = H.isKernelCompatible()
1342 ? diag::warn_format_overflow
1343 : diag::warn_format_overflow_non_kprintf;
1344 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1345 .extOrTrunc(SizeTypeWidth);
1346 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1347 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1348 IsChkVariant =
true;
1350 DestinationSize = ComputeSizeArgument(0);
1357 case Builtin::BI__builtin___memcpy_chk:
1358 case Builtin::BI__builtin___memmove_chk:
1359 case Builtin::BI__builtin___memset_chk:
1360 case Builtin::BI__builtin___strlcat_chk:
1361 case Builtin::BI__builtin___strlcpy_chk:
1362 case Builtin::BI__builtin___strncat_chk:
1363 case Builtin::BI__builtin___strncpy_chk:
1364 case Builtin::BI__builtin___stpncpy_chk:
1365 case Builtin::BI__builtin___memccpy_chk:
1366 case Builtin::BI__builtin___mempcpy_chk: {
1367 DiagID = diag::warn_builtin_chk_overflow;
1368 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1370 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1371 IsChkVariant =
true;
1375 case Builtin::BI__builtin___snprintf_chk:
1376 case Builtin::BI__builtin___vsnprintf_chk: {
1377 DiagID = diag::warn_builtin_chk_overflow;
1378 SourceSize = ComputeExplicitObjectSizeArgument(1);
1379 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1380 IsChkVariant =
true;
1384 case Builtin::BIstrncat:
1385 case Builtin::BI__builtin_strncat:
1386 case Builtin::BIstrncpy:
1387 case Builtin::BI__builtin_strncpy:
1388 case Builtin::BIstpncpy:
1389 case Builtin::BI__builtin_stpncpy: {
1395 DiagID = diag::warn_fortify_source_size_mismatch;
1396 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397 DestinationSize = ComputeSizeArgument(0);
1401 case Builtin::BImemcpy:
1402 case Builtin::BI__builtin_memcpy:
1403 case Builtin::BImemmove:
1404 case Builtin::BI__builtin_memmove:
1405 case Builtin::BImemset:
1406 case Builtin::BI__builtin_memset:
1407 case Builtin::BImempcpy:
1408 case Builtin::BI__builtin_mempcpy: {
1409 DiagID = diag::warn_fortify_source_overflow;
1410 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1411 DestinationSize = ComputeSizeArgument(0);
1414 case Builtin::BIsnprintf:
1415 case Builtin::BI__builtin_snprintf:
1416 case Builtin::BIvsnprintf:
1417 case Builtin::BI__builtin_vsnprintf: {
1418 DiagID = diag::warn_fortify_source_size_mismatch;
1419 SourceSize = ComputeExplicitObjectSizeArgument(1);
1421 StringRef FormatStrRef;
1425 EstimateSizeFormatHandler H(FormatStrRef);
1426 const char *FormatBytes = FormatStrRef.data();
1428 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1429 Context.getTargetInfo(),
false)) {
1430 llvm::APSInt FormatSize =
1431 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1432 .extOrTrunc(SizeTypeWidth);
1433 if (FormatSize > *SourceSize && *SourceSize != 0) {
1434 unsigned TruncationDiagID =
1435 H.isKernelCompatible() ? diag::warn_format_truncation
1436 : diag::warn_format_truncation_non_kprintf;
1437 SmallString<16> SpecifiedSizeStr;
1438 SmallString<16> FormatSizeStr;
1439 SourceSize->toString(SpecifiedSizeStr, 10);
1440 FormatSize.toString(FormatSizeStr, 10);
1442 PDiag(TruncationDiagID)
1443 << GetFunctionName() << SpecifiedSizeStr
1448 DestinationSize = ComputeSizeArgument(0);
1452 if (!SourceSize || !DestinationSize ||
1453 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1456 std::string FunctionName = GetFunctionName();
1458 SmallString<16> DestinationStr;
1459 SmallString<16> SourceStr;
1460 DestinationSize->toString(DestinationStr, 10);
1461 SourceSize->toString(SourceStr, 10);
1464 << FunctionName << DestinationStr << SourceStr);
1479 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1482 << DRE->getDecl()->getIdentifier();
1494 "__builtin_alloca has invalid address space");
1502enum PointerAuthOpKind {
1517 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1548 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1551 llvm::raw_svector_ostream Str(
Value);
1560 Result = KeyValue->getZExtValue();
1579 bool IsAddrDiscArg =
false;
1584 IsAddrDiscArg =
true;
1593 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1594 <<
Result->getExtValue();
1596 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1602 IntVal =
Result->getZExtValue();
1606static std::pair<const ValueDecl *, CharUnits>
1613 const auto *BaseDecl =
1618 return {BaseDecl, Result.Val.getLValueOffset()};
1622 bool RequireConstant =
false) {
1630 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1631 return OpKind != PAO_BlendInteger;
1633 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1634 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1635 OpKind == PAO_SignGeneric;
1644 }
else if (AllowsInteger(OpKind) &&
1651 <<
unsigned(OpKind == PAO_Discriminator ? 1
1652 : OpKind == PAO_BlendPointer ? 2
1653 : OpKind == PAO_BlendInteger ? 3
1655 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1665 if (!RequireConstant) {
1667 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1670 ? diag::warn_ptrauth_sign_null_pointer
1671 : diag::warn_ptrauth_auth_null_pointer)
1681 if (OpKind == PAO_Sign) {
1699 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1704 assert(OpKind == PAO_Discriminator);
1710 if (
Call->getBuiltinCallee() ==
1711 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1726 assert(
Pointer->getType()->isPointerType());
1738 assert(
Integer->getType()->isIntegerType());
1744 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1757 Call->setType(
Call->getArgs()[0]->getType());
1788 PointerAuthOpKind OpKind,
1789 bool RequireConstant) {
1800 Call->setType(
Call->getArgs()[0]->getType());
1816 Call->setType(
Call->getArgs()[0]->getType());
1825 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1828 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1829 if (!Literal || Literal->getCharByteWidth() != 1) {
1845 Call->setArg(0, FirstValue.
get());
1851 if (!FirstArgRecord) {
1852 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1853 << 0 << FirstArgType;
1858 diag::err_get_vtable_pointer_requires_complete_type)) {
1863 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1864 << 1 << FirstArgRecord;
1868 Call->setType(ReturnType);
1893 auto DiagSelect = [&]() -> std::optional<unsigned> {
1900 return std::optional<unsigned>{};
1915 diag::err_incomplete_type))
1919 "Unhandled non-object pointer case");
1947 if (PT->getPointeeType()->isFunctionType()) {
1949 diag::err_builtin_is_within_lifetime_invalid_arg)
1955 if (PT->getPointeeType()->isVariableArrayType()) {
1957 << 1 <<
"__builtin_is_within_lifetime";
1962 diag::err_builtin_is_within_lifetime_invalid_arg)
1976 diag::err_builtin_trivially_relocate_invalid_arg_type)
1983 diag::err_incomplete_type))
1987 T->isIncompleteArrayType()) {
1989 diag::err_builtin_trivially_relocate_invalid_arg_type)
1990 << (
T.isConstQualified() ? 1 : 2);
1999 diag::err_builtin_trivially_relocate_invalid_arg_type)
2006 if (Size.isInvalid())
2010 if (Size.isInvalid())
2012 SizeExpr = Size.get();
2013 TheCall->
setArg(2, SizeExpr);
2023 llvm::Triple::ObjectFormatType CurObjFormat =
2025 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2038 llvm::Triple::ArchType CurArch =
2040 if (llvm::is_contained(SupportedArchs, CurArch))
2050bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2057 case llvm::Triple::arm:
2058 case llvm::Triple::armeb:
2059 case llvm::Triple::thumb:
2060 case llvm::Triple::thumbeb:
2062 case llvm::Triple::aarch64:
2063 case llvm::Triple::aarch64_32:
2064 case llvm::Triple::aarch64_be:
2066 case llvm::Triple::bpfeb:
2067 case llvm::Triple::bpfel:
2069 case llvm::Triple::dxil:
2071 case llvm::Triple::hexagon:
2073 case llvm::Triple::mips:
2074 case llvm::Triple::mipsel:
2075 case llvm::Triple::mips64:
2076 case llvm::Triple::mips64el:
2078 case llvm::Triple::spirv:
2079 case llvm::Triple::spirv32:
2080 case llvm::Triple::spirv64:
2081 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2084 case llvm::Triple::systemz:
2086 case llvm::Triple::x86:
2087 case llvm::Triple::x86_64:
2089 case llvm::Triple::ppc:
2090 case llvm::Triple::ppcle:
2091 case llvm::Triple::ppc64:
2092 case llvm::Triple::ppc64le:
2094 case llvm::Triple::amdgcn:
2096 case llvm::Triple::riscv32:
2097 case llvm::Triple::riscv64:
2099 case llvm::Triple::loongarch32:
2100 case llvm::Triple::loongarch64:
2103 case llvm::Triple::wasm32:
2104 case llvm::Triple::wasm64:
2106 case llvm::Triple::nvptx:
2107 case llvm::Triple::nvptx64:
2121 EltTy = VecTy->getElementType();
2123 switch (ArgTyRestr) {
2127 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2128 << ArgOrdinal << 2 << 1 << 1
2134 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2135 << ArgOrdinal << 5 << 0
2141 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2142 << ArgOrdinal << 5 << 1
2148 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2162 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2163 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2164 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2165 "Expecting __builtin_cpu_...");
2167 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2169 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2170 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2171 (!IsCPUSupports && TInfo->supportsCpuIs()));
2173 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2180 ? diag::err_builtin_aix_os_unsupported
2181 : diag::err_builtin_target_unsupported)
2187 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2239 TheCall->
setArg(0, Arg0);
2256 TheCall->
setArg(1, Arg1);
2262 << 2 << 1 << 4 << 0 << Arg1Ty;
2271 unsigned Pos,
bool AllowConst,
2275 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2280 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2281 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2282 << Pos <<
"scalar pointer";
2291 diag::err_typecheck_convert_incompatible)
2300 bool TypeDependent =
false;
2301 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2329 Builtin::BI__builtin_masked_load))
2343 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2366 Builtin::BI__builtin_masked_store))
2374 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2384 diag::err_vec_builtin_incompatible_vector)
2413 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2426 << MaskTy << IdxTy);
2435 diag::err_vec_masked_load_store_ptr)
2464 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2480 << MaskTy << IdxTy);
2486 << MaskTy << ValTy);
2492 diag::err_vec_builtin_incompatible_vector)
2506 if (Args.size() == 0) {
2508 diag::err_typecheck_call_too_few_args_at_least)
2514 QualType FuncT = Args[0]->getType();
2517 if (Args.size() < 2) {
2519 diag::err_typecheck_call_too_few_args_at_least)
2525 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2526 QualType ObjectT = Args[1]->getType();
2528 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2577 tok::periodstar, ObjectArg.
get(), Args[0]);
2581 if (MPT->isMemberDataPointer())
2584 auto *MemCall =
new (S.
Context)
2595Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2600 unsigned ICEArguments = 0;
2602 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2607 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2609 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2614 if (ArgNo < TheCall->getNumArgs() &&
2617 ICEArguments &= ~(1 << ArgNo);
2621 switch (BuiltinID) {
2622 case Builtin::BI__builtin_cpu_supports:
2623 case Builtin::BI__builtin_cpu_is:
2625 Context.getAuxTargetInfo(), BuiltinID))
2628 case Builtin::BI__builtin_cpu_init:
2629 if (!
Context.getTargetInfo().supportsCpuInit()) {
2635 case Builtin::BI__builtin___CFStringMakeConstantString:
2639 *
this, BuiltinID, TheCall,
2640 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2643 "Wrong # arguments to builtin CFStringMakeConstantString");
2644 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2647 case Builtin::BI__builtin_ms_va_start:
2648 case Builtin::BI__builtin_stdarg_start:
2649 case Builtin::BI__builtin_va_start:
2650 case Builtin::BI__builtin_c23_va_start:
2651 if (BuiltinVAStart(BuiltinID, TheCall))
2654 case Builtin::BI__va_start: {
2655 switch (
Context.getTargetInfo().getTriple().getArch()) {
2656 case llvm::Triple::aarch64:
2657 case llvm::Triple::arm:
2658 case llvm::Triple::thumb:
2659 if (BuiltinVAStartARMMicrosoft(TheCall))
2663 if (BuiltinVAStart(BuiltinID, TheCall))
2671 case Builtin::BI_interlockedbittestandset_acq:
2672 case Builtin::BI_interlockedbittestandset_rel:
2673 case Builtin::BI_interlockedbittestandset_nf:
2674 case Builtin::BI_interlockedbittestandreset_acq:
2675 case Builtin::BI_interlockedbittestandreset_rel:
2676 case Builtin::BI_interlockedbittestandreset_nf:
2679 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2684 case Builtin::BI_bittest64:
2685 case Builtin::BI_bittestandcomplement64:
2686 case Builtin::BI_bittestandreset64:
2687 case Builtin::BI_bittestandset64:
2688 case Builtin::BI_interlockedbittestandreset64:
2689 case Builtin::BI_interlockedbittestandset64:
2692 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2693 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2698 case Builtin::BI_interlockedbittestandreset64_acq:
2699 case Builtin::BI_interlockedbittestandreset64_rel:
2700 case Builtin::BI_interlockedbittestandreset64_nf:
2701 case Builtin::BI_interlockedbittestandset64_acq:
2702 case Builtin::BI_interlockedbittestandset64_rel:
2703 case Builtin::BI_interlockedbittestandset64_nf:
2708 case Builtin::BI__builtin_set_flt_rounds:
2711 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2712 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2713 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2714 llvm::Triple::ppc64le}))
2718 case Builtin::BI__builtin_isgreater:
2719 case Builtin::BI__builtin_isgreaterequal:
2720 case Builtin::BI__builtin_isless:
2721 case Builtin::BI__builtin_islessequal:
2722 case Builtin::BI__builtin_islessgreater:
2723 case Builtin::BI__builtin_isunordered:
2724 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2727 case Builtin::BI__builtin_fpclassify:
2728 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2731 case Builtin::BI__builtin_isfpclass:
2732 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2735 case Builtin::BI__builtin_isfinite:
2736 case Builtin::BI__builtin_isinf:
2737 case Builtin::BI__builtin_isinf_sign:
2738 case Builtin::BI__builtin_isnan:
2739 case Builtin::BI__builtin_issignaling:
2740 case Builtin::BI__builtin_isnormal:
2741 case Builtin::BI__builtin_issubnormal:
2742 case Builtin::BI__builtin_iszero:
2743 case Builtin::BI__builtin_signbit:
2744 case Builtin::BI__builtin_signbitf:
2745 case Builtin::BI__builtin_signbitl:
2746 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2749 case Builtin::BI__builtin_shufflevector:
2753 case Builtin::BI__builtin_masked_load:
2754 case Builtin::BI__builtin_masked_expand_load:
2756 case Builtin::BI__builtin_masked_store:
2757 case Builtin::BI__builtin_masked_compress_store:
2759 case Builtin::BI__builtin_masked_gather:
2761 case Builtin::BI__builtin_masked_scatter:
2763 case Builtin::BI__builtin_invoke:
2765 case Builtin::BI__builtin_prefetch:
2766 if (BuiltinPrefetch(TheCall))
2769 case Builtin::BI__builtin_alloca_with_align:
2770 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2771 if (BuiltinAllocaWithAlign(TheCall))
2774 case Builtin::BI__builtin_alloca:
2775 case Builtin::BI__builtin_alloca_uninitialized:
2782 case Builtin::BI__arithmetic_fence:
2783 if (BuiltinArithmeticFence(TheCall))
2786 case Builtin::BI__assume:
2787 case Builtin::BI__builtin_assume:
2788 if (BuiltinAssume(TheCall))
2791 case Builtin::BI__builtin_assume_aligned:
2792 if (BuiltinAssumeAligned(TheCall))
2795 case Builtin::BI__builtin_dynamic_object_size:
2796 case Builtin::BI__builtin_object_size:
2800 case Builtin::BI__builtin_longjmp:
2801 if (BuiltinLongjmp(TheCall))
2804 case Builtin::BI__builtin_setjmp:
2805 if (BuiltinSetjmp(TheCall))
2808 case Builtin::BI__builtin_classify_type:
2813 case Builtin::BI__builtin_complex:
2814 if (BuiltinComplex(TheCall))
2817 case Builtin::BI__builtin_constant_p: {
2826 case Builtin::BI__builtin_launder:
2828 case Builtin::BI__builtin_is_within_lifetime:
2830 case Builtin::BI__builtin_trivially_relocate:
2833 case Builtin::BI__sync_fetch_and_add:
2834 case Builtin::BI__sync_fetch_and_add_1:
2835 case Builtin::BI__sync_fetch_and_add_2:
2836 case Builtin::BI__sync_fetch_and_add_4:
2837 case Builtin::BI__sync_fetch_and_add_8:
2838 case Builtin::BI__sync_fetch_and_add_16:
2839 case Builtin::BI__sync_fetch_and_sub:
2840 case Builtin::BI__sync_fetch_and_sub_1:
2841 case Builtin::BI__sync_fetch_and_sub_2:
2842 case Builtin::BI__sync_fetch_and_sub_4:
2843 case Builtin::BI__sync_fetch_and_sub_8:
2844 case Builtin::BI__sync_fetch_and_sub_16:
2845 case Builtin::BI__sync_fetch_and_or:
2846 case Builtin::BI__sync_fetch_and_or_1:
2847 case Builtin::BI__sync_fetch_and_or_2:
2848 case Builtin::BI__sync_fetch_and_or_4:
2849 case Builtin::BI__sync_fetch_and_or_8:
2850 case Builtin::BI__sync_fetch_and_or_16:
2851 case Builtin::BI__sync_fetch_and_and:
2852 case Builtin::BI__sync_fetch_and_and_1:
2853 case Builtin::BI__sync_fetch_and_and_2:
2854 case Builtin::BI__sync_fetch_and_and_4:
2855 case Builtin::BI__sync_fetch_and_and_8:
2856 case Builtin::BI__sync_fetch_and_and_16:
2857 case Builtin::BI__sync_fetch_and_xor:
2858 case Builtin::BI__sync_fetch_and_xor_1:
2859 case Builtin::BI__sync_fetch_and_xor_2:
2860 case Builtin::BI__sync_fetch_and_xor_4:
2861 case Builtin::BI__sync_fetch_and_xor_8:
2862 case Builtin::BI__sync_fetch_and_xor_16:
2863 case Builtin::BI__sync_fetch_and_nand:
2864 case Builtin::BI__sync_fetch_and_nand_1:
2865 case Builtin::BI__sync_fetch_and_nand_2:
2866 case Builtin::BI__sync_fetch_and_nand_4:
2867 case Builtin::BI__sync_fetch_and_nand_8:
2868 case Builtin::BI__sync_fetch_and_nand_16:
2869 case Builtin::BI__sync_add_and_fetch:
2870 case Builtin::BI__sync_add_and_fetch_1:
2871 case Builtin::BI__sync_add_and_fetch_2:
2872 case Builtin::BI__sync_add_and_fetch_4:
2873 case Builtin::BI__sync_add_and_fetch_8:
2874 case Builtin::BI__sync_add_and_fetch_16:
2875 case Builtin::BI__sync_sub_and_fetch:
2876 case Builtin::BI__sync_sub_and_fetch_1:
2877 case Builtin::BI__sync_sub_and_fetch_2:
2878 case Builtin::BI__sync_sub_and_fetch_4:
2879 case Builtin::BI__sync_sub_and_fetch_8:
2880 case Builtin::BI__sync_sub_and_fetch_16:
2881 case Builtin::BI__sync_and_and_fetch:
2882 case Builtin::BI__sync_and_and_fetch_1:
2883 case Builtin::BI__sync_and_and_fetch_2:
2884 case Builtin::BI__sync_and_and_fetch_4:
2885 case Builtin::BI__sync_and_and_fetch_8:
2886 case Builtin::BI__sync_and_and_fetch_16:
2887 case Builtin::BI__sync_or_and_fetch:
2888 case Builtin::BI__sync_or_and_fetch_1:
2889 case Builtin::BI__sync_or_and_fetch_2:
2890 case Builtin::BI__sync_or_and_fetch_4:
2891 case Builtin::BI__sync_or_and_fetch_8:
2892 case Builtin::BI__sync_or_and_fetch_16:
2893 case Builtin::BI__sync_xor_and_fetch:
2894 case Builtin::BI__sync_xor_and_fetch_1:
2895 case Builtin::BI__sync_xor_and_fetch_2:
2896 case Builtin::BI__sync_xor_and_fetch_4:
2897 case Builtin::BI__sync_xor_and_fetch_8:
2898 case Builtin::BI__sync_xor_and_fetch_16:
2899 case Builtin::BI__sync_nand_and_fetch:
2900 case Builtin::BI__sync_nand_and_fetch_1:
2901 case Builtin::BI__sync_nand_and_fetch_2:
2902 case Builtin::BI__sync_nand_and_fetch_4:
2903 case Builtin::BI__sync_nand_and_fetch_8:
2904 case Builtin::BI__sync_nand_and_fetch_16:
2905 case Builtin::BI__sync_val_compare_and_swap:
2906 case Builtin::BI__sync_val_compare_and_swap_1:
2907 case Builtin::BI__sync_val_compare_and_swap_2:
2908 case Builtin::BI__sync_val_compare_and_swap_4:
2909 case Builtin::BI__sync_val_compare_and_swap_8:
2910 case Builtin::BI__sync_val_compare_and_swap_16:
2911 case Builtin::BI__sync_bool_compare_and_swap:
2912 case Builtin::BI__sync_bool_compare_and_swap_1:
2913 case Builtin::BI__sync_bool_compare_and_swap_2:
2914 case Builtin::BI__sync_bool_compare_and_swap_4:
2915 case Builtin::BI__sync_bool_compare_and_swap_8:
2916 case Builtin::BI__sync_bool_compare_and_swap_16:
2917 case Builtin::BI__sync_lock_test_and_set:
2918 case Builtin::BI__sync_lock_test_and_set_1:
2919 case Builtin::BI__sync_lock_test_and_set_2:
2920 case Builtin::BI__sync_lock_test_and_set_4:
2921 case Builtin::BI__sync_lock_test_and_set_8:
2922 case Builtin::BI__sync_lock_test_and_set_16:
2923 case Builtin::BI__sync_lock_release:
2924 case Builtin::BI__sync_lock_release_1:
2925 case Builtin::BI__sync_lock_release_2:
2926 case Builtin::BI__sync_lock_release_4:
2927 case Builtin::BI__sync_lock_release_8:
2928 case Builtin::BI__sync_lock_release_16:
2929 case Builtin::BI__sync_swap:
2930 case Builtin::BI__sync_swap_1:
2931 case Builtin::BI__sync_swap_2:
2932 case Builtin::BI__sync_swap_4:
2933 case Builtin::BI__sync_swap_8:
2934 case Builtin::BI__sync_swap_16:
2935 return BuiltinAtomicOverloaded(TheCallResult);
2936 case Builtin::BI__sync_synchronize:
2940 case Builtin::BI__builtin_nontemporal_load:
2941 case Builtin::BI__builtin_nontemporal_store:
2942 return BuiltinNontemporalOverloaded(TheCallResult);
2943 case Builtin::BI__builtin_memcpy_inline: {
2944 clang::Expr *SizeOp = TheCall->
getArg(2);
2956 case Builtin::BI__builtin_memset_inline: {
2957 clang::Expr *SizeOp = TheCall->
getArg(2);
2967#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2968 case Builtin::BI##ID: \
2969 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2970#include "clang/Basic/Builtins.inc"
2971 case Builtin::BI__annotation:
2975 case Builtin::BI__builtin_annotation:
2979 case Builtin::BI__builtin_addressof:
2983 case Builtin::BI__builtin_function_start:
2987 case Builtin::BI__builtin_is_aligned:
2988 case Builtin::BI__builtin_align_up:
2989 case Builtin::BI__builtin_align_down:
2993 case Builtin::BI__builtin_add_overflow:
2994 case Builtin::BI__builtin_sub_overflow:
2995 case Builtin::BI__builtin_mul_overflow:
2999 case Builtin::BI__builtin_operator_new:
3000 case Builtin::BI__builtin_operator_delete: {
3001 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3003 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3006 case Builtin::BI__builtin_dump_struct:
3008 case Builtin::BI__builtin_expect_with_probability: {
3013 const Expr *ProbArg = TheCall->
getArg(2);
3014 SmallVector<PartialDiagnosticAt, 8> Notes;
3015 Expr::EvalResult Eval;
3019 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3026 bool LoseInfo =
false;
3027 Probability.convert(llvm::APFloat::IEEEdouble(),
3028 llvm::RoundingMode::Dynamic, &LoseInfo);
3029 if (!(Probability >= llvm::APFloat(0.0) &&
3030 Probability <= llvm::APFloat(1.0))) {
3037 case Builtin::BI__builtin_preserve_access_index:
3041 case Builtin::BI__builtin_call_with_static_chain:
3045 case Builtin::BI__exception_code:
3046 case Builtin::BI_exception_code:
3048 diag::err_seh___except_block))
3051 case Builtin::BI__exception_info:
3052 case Builtin::BI_exception_info:
3054 diag::err_seh___except_filter))
3057 case Builtin::BI__GetExceptionInfo:
3069 case Builtin::BIaddressof:
3070 case Builtin::BI__addressof:
3071 case Builtin::BIforward:
3072 case Builtin::BIforward_like:
3073 case Builtin::BImove:
3074 case Builtin::BImove_if_noexcept:
3075 case Builtin::BIas_const: {
3083 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3084 BuiltinID == Builtin::BI__addressof;
3086 (ReturnsPointer ?
Result->isAnyPointerType()
3087 :
Result->isReferenceType()) &&
3090 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3096 case Builtin::BI__builtin_ptrauth_strip:
3098 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3100 case Builtin::BI__builtin_ptrauth_sign_constant:
3103 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3106 case Builtin::BI__builtin_ptrauth_auth:
3109 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3111 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3113 case Builtin::BI__builtin_ptrauth_string_discriminator:
3116 case Builtin::BI__builtin_get_vtable_pointer:
3120 case Builtin::BIread_pipe:
3121 case Builtin::BIwrite_pipe:
3124 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3127 case Builtin::BIreserve_read_pipe:
3128 case Builtin::BIreserve_write_pipe:
3129 case Builtin::BIwork_group_reserve_read_pipe:
3130 case Builtin::BIwork_group_reserve_write_pipe:
3131 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3134 case Builtin::BIsub_group_reserve_read_pipe:
3135 case Builtin::BIsub_group_reserve_write_pipe:
3136 if (
OpenCL().checkSubgroupExt(TheCall) ||
3137 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3140 case Builtin::BIcommit_read_pipe:
3141 case Builtin::BIcommit_write_pipe:
3142 case Builtin::BIwork_group_commit_read_pipe:
3143 case Builtin::BIwork_group_commit_write_pipe:
3144 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3147 case Builtin::BIsub_group_commit_read_pipe:
3148 case Builtin::BIsub_group_commit_write_pipe:
3149 if (
OpenCL().checkSubgroupExt(TheCall) ||
3150 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3153 case Builtin::BIget_pipe_num_packets:
3154 case Builtin::BIget_pipe_max_packets:
3155 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3158 case Builtin::BIto_global:
3159 case Builtin::BIto_local:
3160 case Builtin::BIto_private:
3161 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3165 case Builtin::BIenqueue_kernel:
3166 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3169 case Builtin::BIget_kernel_work_group_size:
3170 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3171 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3174 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3175 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3176 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3179 case Builtin::BI__builtin_os_log_format:
3180 Cleanup.setExprNeedsCleanups(
true);
3182 case Builtin::BI__builtin_os_log_format_buffer_size:
3183 if (BuiltinOSLogFormat(TheCall))
3186 case Builtin::BI__builtin_frame_address:
3187 case Builtin::BI__builtin_return_address: {
3196 Result.Val.getInt() != 0)
3198 << ((BuiltinID == Builtin::BI__builtin_return_address)
3199 ?
"__builtin_return_address"
3200 :
"__builtin_frame_address")
3205 case Builtin::BI__builtin_nondeterministic_value: {
3206 if (BuiltinNonDeterministicValue(TheCall))
3213 case Builtin::BI__builtin_elementwise_abs:
3221 case Builtin::BI__builtin_elementwise_acos:
3222 case Builtin::BI__builtin_elementwise_asin:
3223 case Builtin::BI__builtin_elementwise_atan:
3224 case Builtin::BI__builtin_elementwise_ceil:
3225 case Builtin::BI__builtin_elementwise_cos:
3226 case Builtin::BI__builtin_elementwise_cosh:
3227 case Builtin::BI__builtin_elementwise_exp:
3228 case Builtin::BI__builtin_elementwise_exp2:
3229 case Builtin::BI__builtin_elementwise_exp10:
3230 case Builtin::BI__builtin_elementwise_floor:
3231 case Builtin::BI__builtin_elementwise_log:
3232 case Builtin::BI__builtin_elementwise_log2:
3233 case Builtin::BI__builtin_elementwise_log10:
3234 case Builtin::BI__builtin_elementwise_roundeven:
3235 case Builtin::BI__builtin_elementwise_round:
3236 case Builtin::BI__builtin_elementwise_rint:
3237 case Builtin::BI__builtin_elementwise_nearbyint:
3238 case Builtin::BI__builtin_elementwise_sin:
3239 case Builtin::BI__builtin_elementwise_sinh:
3240 case Builtin::BI__builtin_elementwise_sqrt:
3241 case Builtin::BI__builtin_elementwise_tan:
3242 case Builtin::BI__builtin_elementwise_tanh:
3243 case Builtin::BI__builtin_elementwise_trunc:
3244 case Builtin::BI__builtin_elementwise_canonicalize:
3249 case Builtin::BI__builtin_elementwise_fma:
3256 case Builtin::BI__builtin_elementwise_minnum:
3257 case Builtin::BI__builtin_elementwise_maxnum:
3258 case Builtin::BI__builtin_elementwise_minimum:
3259 case Builtin::BI__builtin_elementwise_maximum:
3260 case Builtin::BI__builtin_elementwise_minimumnum:
3261 case Builtin::BI__builtin_elementwise_maximumnum:
3262 case Builtin::BI__builtin_elementwise_atan2:
3263 case Builtin::BI__builtin_elementwise_fmod:
3264 case Builtin::BI__builtin_elementwise_pow:
3265 if (BuiltinElementwiseMath(TheCall,
3271 case Builtin::BI__builtin_elementwise_add_sat:
3272 case Builtin::BI__builtin_elementwise_sub_sat:
3273 if (BuiltinElementwiseMath(TheCall,
3277 case Builtin::BI__builtin_elementwise_fshl:
3278 case Builtin::BI__builtin_elementwise_fshr:
3283 case Builtin::BI__builtin_elementwise_min:
3284 case Builtin::BI__builtin_elementwise_max:
3285 if (BuiltinElementwiseMath(TheCall))
3288 case Builtin::BI__builtin_elementwise_popcount:
3289 case Builtin::BI__builtin_elementwise_bitreverse:
3294 case Builtin::BI__builtin_elementwise_copysign: {
3303 QualType MagnitudeTy = Magnitude.
get()->
getType();
3316 diag::err_typecheck_call_different_arg_types)
3317 << MagnitudeTy << SignTy;
3325 case Builtin::BI__builtin_elementwise_clzg:
3326 case Builtin::BI__builtin_elementwise_ctzg:
3334 }
else if (BuiltinElementwiseMath(
3338 case Builtin::BI__builtin_reduce_max:
3339 case Builtin::BI__builtin_reduce_min: {
3340 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3343 const Expr *Arg = TheCall->
getArg(0);
3348 ElTy = TyA->getElementType();
3352 if (ElTy.isNull()) {
3362 case Builtin::BI__builtin_reduce_maximum:
3363 case Builtin::BI__builtin_reduce_minimum: {
3364 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3367 const Expr *Arg = TheCall->
getArg(0);
3372 ElTy = TyA->getElementType();
3376 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3389 case Builtin::BI__builtin_reduce_add:
3390 case Builtin::BI__builtin_reduce_mul:
3391 case Builtin::BI__builtin_reduce_xor:
3392 case Builtin::BI__builtin_reduce_or:
3393 case Builtin::BI__builtin_reduce_and: {
3394 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3397 const Expr *Arg = TheCall->
getArg(0);
3402 ElTy = TyA->getElementType();
3406 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3417 case Builtin::BI__builtin_matrix_transpose:
3418 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3420 case Builtin::BI__builtin_matrix_column_major_load:
3421 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3423 case Builtin::BI__builtin_matrix_column_major_store:
3424 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3426 case Builtin::BI__builtin_verbose_trap:
3431 case Builtin::BI__builtin_get_device_side_mangled_name: {
3432 auto Check = [](CallExpr *TheCall) {
3438 auto *D = DRE->getDecl();
3441 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3442 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3444 if (!Check(TheCall)) {
3446 diag::err_hip_invalid_args_builtin_mangled_name);
3451 case Builtin::BI__builtin_popcountg:
3455 case Builtin::BI__builtin_clzg:
3456 case Builtin::BI__builtin_ctzg:
3461 case Builtin::BI__builtin_allow_runtime_check: {
3462 Expr *Arg = TheCall->
getArg(0);
3471 case Builtin::BI__builtin_counted_by_ref:
3472 if (BuiltinCountedByRef(TheCall))
3482 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3483 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3484 assert(
Context.getAuxTargetInfo() &&
3485 "Aux Target Builtin, but not an aux target?");
3487 if (CheckTSBuiltinFunctionCall(
3489 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3492 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3498 return TheCallResult;
3513 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3517 diag::err_argument_not_contiguous_bit_field)
3523 bool IsCXXMember =
false;
3524 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D))
3525 IsCXXMember = MD->isInstance();
3526 bool IsVariadic =
false;
3529 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3530 IsVariadic = BD->isVariadic();
3531 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3532 IsVariadic = OMD->isVariadic();
3538 bool IsCXXMember,
bool IsVariadic,
3542 else if (IsVariadic)
3583 UT && UT->getOriginalDecl()
3584 ->getMostRecentDecl()
3585 ->hasAttr<TransparentUnionAttr>()) {
3586 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3587 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3588 Expr = ILE->getInit(0);
3598 const Expr *ArgExpr,
3602 S.
PDiag(diag::warn_null_arg)
3608 if (
auto nullability =
type->getNullability())
3619 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3625 llvm::SmallBitVector NonNullArgs;
3631 for (
const auto *Arg : Args)
3638 unsigned IdxAST = Idx.getASTIndex();
3639 if (IdxAST >= Args.size())
3641 if (NonNullArgs.empty())
3642 NonNullArgs.resize(Args.size());
3643 NonNullArgs.set(IdxAST);
3652 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3657 unsigned ParamIndex = 0;
3659 I != E; ++I, ++ParamIndex) {
3662 if (NonNullArgs.empty())
3663 NonNullArgs.resize(Args.size());
3665 NonNullArgs.set(ParamIndex);
3672 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3677 type = blockType->getPointeeType();
3691 if (NonNullArgs.empty())
3692 NonNullArgs.resize(Args.size());
3694 NonNullArgs.set(Index);
3703 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3704 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3705 if (NonNullArgs[ArgIndex])
3711 StringRef ParamName,
QualType ArgTy,
3734 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3735 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3739 if (ArgAlign < ParamAlign)
3740 Diag(Loc, diag::warn_param_mismatched_alignment)
3742 << ParamName << (FDecl !=
nullptr) << FDecl;
3746 const Expr *ThisArg,
3748 if (!FD || Args.empty())
3750 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3751 if (Idx == LifetimeCaptureByAttr::Global ||
3752 Idx == LifetimeCaptureByAttr::Unknown)
3754 if (IsMemberFunction && Idx == 0)
3756 return Args[Idx - IsMemberFunction];
3758 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3763 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3764 for (
int CapturingParamIdx :
Attr->params()) {
3767 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3770 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3778 I + IsMemberFunction);
3780 if (IsMemberFunction) {
3788 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3801 llvm::SmallBitVector CheckedVarArgs;
3803 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3805 CheckedVarArgs.resize(Args.size());
3806 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3811 CheckedVarArgs.resize(Args.size());
3812 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3819 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3823 : isa_and_nonnull<FunctionDecl>(FDecl)
3825 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3829 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3831 if (
const Expr *Arg = Args[ArgIdx]) {
3832 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3839 if (FDecl || Proto) {
3844 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3845 CheckArgumentWithTypeTag(I, Args, Loc);
3851 if (!Proto && FDecl) {
3853 if (isa_and_nonnull<FunctionProtoType>(FT))
3859 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3861 bool IsScalableArg =
false;
3862 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3864 if (
const Expr *Arg = Args[ArgIdx]) {
3868 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3876 IsScalableArg =
true;
3878 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3887 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3888 llvm::StringMap<bool> CallerFeatureMap;
3889 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
3890 if (!CallerFeatureMap.contains(
"sme"))
3891 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3892 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
3893 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3902 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3904 (IsScalableArg || IsScalableRet)) {
3905 bool IsCalleeStreaming =
3907 bool IsCalleeStreamingCompatible =
3911 if (!IsCalleeStreamingCompatible &&
3915 unsigned VL = LO.VScaleMin * 128;
3916 unsigned SVL = LO.VScaleStreamingMin * 128;
3917 bool IsVLMismatch = VL && SVL && VL != SVL;
3919 auto EmitDiag = [&](
bool IsArg) {
3923 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
3924 << IsArg << IsCalleeStreaming << SVL << VL;
3927 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
3928 << IsArg << SVL << VL;
3930 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3947 bool CallerHasZAState =
false;
3948 bool CallerHasZT0State =
false;
3950 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3952 CallerHasZAState =
true;
3954 CallerHasZT0State =
true;
3958 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3960 CallerHasZT0State |=
3962 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3968 Diag(Loc, diag::err_sme_za_call_no_za_state);
3971 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
3975 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
3976 Diag(Loc, diag::note_sme_use_preserves_za);
3981 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3982 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3983 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3984 if (!Arg->isValueDependent()) {
3986 if (Arg->EvaluateAsInt(Align,
Context)) {
3987 const llvm::APSInt &I = Align.
Val.
getInt();
3988 if (!I.isPowerOf2())
3989 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3990 << Arg->getSourceRange();
3993 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4019 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4020 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4022 checkCall(FDecl, Proto,
nullptr, Args,
true,
4031 IsMemberOperatorCall;
4037 Expr *ImplicitThis =
nullptr;
4042 ImplicitThis = Args[0];
4045 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4056 ThisType =
Context.getPointerType(ThisType);
4062 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4080 CheckAbsoluteValueFunction(TheCall, FDecl);
4081 CheckMaxUnsignedZero(TheCall, FDecl);
4082 CheckInfNaNFunction(TheCall, FDecl);
4093 case Builtin::BIstrlcpy:
4094 case Builtin::BIstrlcat:
4095 CheckStrlcpycatArguments(TheCall, FnInfo);
4097 case Builtin::BIstrncat:
4098 CheckStrncatArguments(TheCall, FnInfo);
4100 case Builtin::BIfree:
4101 CheckFreeArguments(TheCall);
4104 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4113 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4114 Ty =
V->getType().getNonReferenceType();
4115 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4116 Ty = F->getType().getNonReferenceType();
4153 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4156 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4158 case AtomicExpr::AO__c11_atomic_init:
4159 case AtomicExpr::AO__opencl_atomic_init:
4160 llvm_unreachable(
"There is no ordering argument for an init");
4162 case AtomicExpr::AO__c11_atomic_load:
4163 case AtomicExpr::AO__opencl_atomic_load:
4164 case AtomicExpr::AO__hip_atomic_load:
4165 case AtomicExpr::AO__atomic_load_n:
4166 case AtomicExpr::AO__atomic_load:
4167 case AtomicExpr::AO__scoped_atomic_load_n:
4168 case AtomicExpr::AO__scoped_atomic_load:
4169 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4170 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4172 case AtomicExpr::AO__c11_atomic_store:
4173 case AtomicExpr::AO__opencl_atomic_store:
4174 case AtomicExpr::AO__hip_atomic_store:
4175 case AtomicExpr::AO__atomic_store:
4176 case AtomicExpr::AO__atomic_store_n:
4177 case AtomicExpr::AO__scoped_atomic_store:
4178 case AtomicExpr::AO__scoped_atomic_store_n:
4179 case AtomicExpr::AO__atomic_clear:
4180 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4181 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4182 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4241 const unsigned NumForm = ClearByte + 1;
4242 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4243 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4251 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4252 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4253 "need to update code for modified forms");
4254 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4255 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4256 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4257 "need to update code for modified C11 atomics");
4258 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4259 Op <= AtomicExpr::AO__opencl_atomic_store;
4260 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4261 Op <= AtomicExpr::AO__hip_atomic_store;
4262 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4263 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4264 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4265 Op <= AtomicExpr::AO__c11_atomic_store) ||
4267 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4268 Op == AtomicExpr::AO__atomic_store_n ||
4269 Op == AtomicExpr::AO__atomic_exchange_n ||
4270 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4271 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4272 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4273 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4274 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4278 enum ArithOpExtraValueType {
4283 unsigned ArithAllows = AOEVT_None;
4286 case AtomicExpr::AO__c11_atomic_init:
4287 case AtomicExpr::AO__opencl_atomic_init:
4291 case AtomicExpr::AO__c11_atomic_load:
4292 case AtomicExpr::AO__opencl_atomic_load:
4293 case AtomicExpr::AO__hip_atomic_load:
4294 case AtomicExpr::AO__atomic_load_n:
4295 case AtomicExpr::AO__scoped_atomic_load_n:
4299 case AtomicExpr::AO__atomic_load:
4300 case AtomicExpr::AO__scoped_atomic_load:
4304 case AtomicExpr::AO__c11_atomic_store:
4305 case AtomicExpr::AO__opencl_atomic_store:
4306 case AtomicExpr::AO__hip_atomic_store:
4307 case AtomicExpr::AO__atomic_store:
4308 case AtomicExpr::AO__atomic_store_n:
4309 case AtomicExpr::AO__scoped_atomic_store:
4310 case AtomicExpr::AO__scoped_atomic_store_n:
4313 case AtomicExpr::AO__atomic_fetch_add:
4314 case AtomicExpr::AO__atomic_fetch_sub:
4315 case AtomicExpr::AO__atomic_add_fetch:
4316 case AtomicExpr::AO__atomic_sub_fetch:
4317 case AtomicExpr::AO__scoped_atomic_fetch_add:
4318 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4319 case AtomicExpr::AO__scoped_atomic_add_fetch:
4320 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4321 case AtomicExpr::AO__c11_atomic_fetch_add:
4322 case AtomicExpr::AO__c11_atomic_fetch_sub:
4323 case AtomicExpr::AO__opencl_atomic_fetch_add:
4324 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4325 case AtomicExpr::AO__hip_atomic_fetch_add:
4326 case AtomicExpr::AO__hip_atomic_fetch_sub:
4327 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4330 case AtomicExpr::AO__atomic_fetch_max:
4331 case AtomicExpr::AO__atomic_fetch_min:
4332 case AtomicExpr::AO__atomic_max_fetch:
4333 case AtomicExpr::AO__atomic_min_fetch:
4334 case AtomicExpr::AO__scoped_atomic_fetch_max:
4335 case AtomicExpr::AO__scoped_atomic_fetch_min:
4336 case AtomicExpr::AO__scoped_atomic_max_fetch:
4337 case AtomicExpr::AO__scoped_atomic_min_fetch:
4338 case AtomicExpr::AO__c11_atomic_fetch_max:
4339 case AtomicExpr::AO__c11_atomic_fetch_min:
4340 case AtomicExpr::AO__opencl_atomic_fetch_max:
4341 case AtomicExpr::AO__opencl_atomic_fetch_min:
4342 case AtomicExpr::AO__hip_atomic_fetch_max:
4343 case AtomicExpr::AO__hip_atomic_fetch_min:
4344 ArithAllows = AOEVT_FP;
4347 case AtomicExpr::AO__c11_atomic_fetch_and:
4348 case AtomicExpr::AO__c11_atomic_fetch_or:
4349 case AtomicExpr::AO__c11_atomic_fetch_xor:
4350 case AtomicExpr::AO__hip_atomic_fetch_and:
4351 case AtomicExpr::AO__hip_atomic_fetch_or:
4352 case AtomicExpr::AO__hip_atomic_fetch_xor:
4353 case AtomicExpr::AO__c11_atomic_fetch_nand:
4354 case AtomicExpr::AO__opencl_atomic_fetch_and:
4355 case AtomicExpr::AO__opencl_atomic_fetch_or:
4356 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4357 case AtomicExpr::AO__atomic_fetch_and:
4358 case AtomicExpr::AO__atomic_fetch_or:
4359 case AtomicExpr::AO__atomic_fetch_xor:
4360 case AtomicExpr::AO__atomic_fetch_nand:
4361 case AtomicExpr::AO__atomic_and_fetch:
4362 case AtomicExpr::AO__atomic_or_fetch:
4363 case AtomicExpr::AO__atomic_xor_fetch:
4364 case AtomicExpr::AO__atomic_nand_fetch:
4365 case AtomicExpr::AO__scoped_atomic_fetch_and:
4366 case AtomicExpr::AO__scoped_atomic_fetch_or:
4367 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4368 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4369 case AtomicExpr::AO__scoped_atomic_and_fetch:
4370 case AtomicExpr::AO__scoped_atomic_or_fetch:
4371 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4372 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4376 case AtomicExpr::AO__c11_atomic_exchange:
4377 case AtomicExpr::AO__hip_atomic_exchange:
4378 case AtomicExpr::AO__opencl_atomic_exchange:
4379 case AtomicExpr::AO__atomic_exchange_n:
4380 case AtomicExpr::AO__scoped_atomic_exchange_n:
4384 case AtomicExpr::AO__atomic_exchange:
4385 case AtomicExpr::AO__scoped_atomic_exchange:
4389 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4390 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4391 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4392 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4393 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4394 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4398 case AtomicExpr::AO__atomic_compare_exchange:
4399 case AtomicExpr::AO__atomic_compare_exchange_n:
4400 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4401 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4405 case AtomicExpr::AO__atomic_test_and_set:
4406 Form = TestAndSetByte;
4409 case AtomicExpr::AO__atomic_clear:
4414 unsigned AdjustedNumArgs = NumArgs[Form];
4415 if ((IsOpenCL || IsHIP || IsScoped) &&
4416 Op != AtomicExpr::AO__opencl_atomic_init)
4419 if (Args.size() < AdjustedNumArgs) {
4420 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4421 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4424 }
else if (Args.size() > AdjustedNumArgs) {
4425 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4426 diag::err_typecheck_call_too_many_args)
4427 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4433 Expr *Ptr = Args[0];
4438 Ptr = ConvertedPtr.
get();
4441 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4451 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4457 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4463 }
else if (Form != Load && Form != LoadCopy) {
4465 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4471 if (Form != TestAndSetByte && Form != ClearByte) {
4474 diag::err_incomplete_type))
4477 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4478 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4488 pointerType->getPointeeType().getCVRQualifiers());
4498 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4507 auto IsAllowedValueType = [&](
QualType ValType,
4508 unsigned AllowedType) ->
bool {
4512 return AllowedType & AOEVT_Pointer;
4517 &
Context.getTargetInfo().getLongDoubleFormat() ==
4518 &llvm::APFloat::x87DoubleExtended())
4522 if (!IsAllowedValueType(ValType, ArithAllows)) {
4523 auto DID = ArithAllows & AOEVT_FP
4524 ? (ArithAllows & AOEVT_Pointer
4525 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4526 : diag::err_atomic_op_needs_atomic_int_or_fp)
4527 : diag::err_atomic_op_needs_atomic_int;
4534 diag::err_incomplete_type)) {
4540 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4551 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4567 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4579 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4582 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4588 bool IsPassedByAddress =
false;
4589 if (!IsC11 && !IsHIP && !IsN) {
4591 IsPassedByAddress =
true;
4596 APIOrderedArgs.push_back(Args[0]);
4600 APIOrderedArgs.push_back(Args[1]);
4606 APIOrderedArgs.push_back(Args[2]);
4607 APIOrderedArgs.push_back(Args[1]);
4610 APIOrderedArgs.push_back(Args[2]);
4611 APIOrderedArgs.push_back(Args[3]);
4612 APIOrderedArgs.push_back(Args[1]);
4615 APIOrderedArgs.push_back(Args[2]);
4616 APIOrderedArgs.push_back(Args[4]);
4617 APIOrderedArgs.push_back(Args[1]);
4618 APIOrderedArgs.push_back(Args[3]);
4621 APIOrderedArgs.push_back(Args[2]);
4622 APIOrderedArgs.push_back(Args[4]);
4623 APIOrderedArgs.push_back(Args[5]);
4624 APIOrderedArgs.push_back(Args[1]);
4625 APIOrderedArgs.push_back(Args[3]);
4627 case TestAndSetByte:
4629 APIOrderedArgs.push_back(Args[1]);
4633 APIOrderedArgs.append(Args.begin(), Args.end());
4640 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4642 if (i < NumVals[Form] + 1) {
4655 assert(Form != Load);
4657 Ty =
Context.getPointerDiffType();
4660 else if (Form ==
Copy || Form == Xchg) {
4661 if (IsPassedByAddress) {
4668 Expr *ValArg = APIOrderedArgs[i];
4675 AS = PtrTy->getPointeeType().getAddressSpace();
4684 if (IsPassedByAddress)
4704 APIOrderedArgs[i] = Arg.
get();
4709 SubExprs.push_back(Ptr);
4713 SubExprs.push_back(APIOrderedArgs[1]);
4716 case TestAndSetByte:
4718 SubExprs.push_back(APIOrderedArgs[1]);
4724 SubExprs.push_back(APIOrderedArgs[2]);
4725 SubExprs.push_back(APIOrderedArgs[1]);
4729 SubExprs.push_back(APIOrderedArgs[3]);
4730 SubExprs.push_back(APIOrderedArgs[1]);
4731 SubExprs.push_back(APIOrderedArgs[2]);
4734 SubExprs.push_back(APIOrderedArgs[3]);
4735 SubExprs.push_back(APIOrderedArgs[1]);
4736 SubExprs.push_back(APIOrderedArgs[4]);
4737 SubExprs.push_back(APIOrderedArgs[2]);
4740 SubExprs.push_back(APIOrderedArgs[4]);
4741 SubExprs.push_back(APIOrderedArgs[1]);
4742 SubExprs.push_back(APIOrderedArgs[5]);
4743 SubExprs.push_back(APIOrderedArgs[2]);
4744 SubExprs.push_back(APIOrderedArgs[3]);
4749 if (SubExprs.size() >= 2 && Form !=
Init) {
4750 std::optional<llvm::APSInt>
Success =
4751 SubExprs[1]->getIntegerConstantExpr(
Context);
4753 Diag(SubExprs[1]->getBeginLoc(),
4754 diag::warn_atomic_op_has_invalid_memory_order)
4755 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4756 << SubExprs[1]->getSourceRange();
4758 if (SubExprs.size() >= 5) {
4759 if (std::optional<llvm::APSInt> Failure =
4760 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4761 if (!llvm::is_contained(
4762 {llvm::AtomicOrderingCABI::relaxed,
4763 llvm::AtomicOrderingCABI::consume,
4764 llvm::AtomicOrderingCABI::acquire,
4765 llvm::AtomicOrderingCABI::seq_cst},
4766 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4767 Diag(SubExprs[3]->getBeginLoc(),
4768 diag::warn_atomic_op_has_invalid_memory_order)
4769 << 2 << SubExprs[3]->getSourceRange();
4776 auto *
Scope = Args[Args.size() - 1];
4777 if (std::optional<llvm::APSInt>
Result =
4779 if (!ScopeModel->isValid(
Result->getZExtValue()))
4780 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4781 <<
Scope->getSourceRange();
4783 SubExprs.push_back(
Scope);
4789 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4790 Op == AtomicExpr::AO__c11_atomic_store ||
4791 Op == AtomicExpr::AO__opencl_atomic_load ||
4792 Op == AtomicExpr::AO__hip_atomic_load ||
4793 Op == AtomicExpr::AO__opencl_atomic_store ||
4794 Op == AtomicExpr::AO__hip_atomic_store) &&
4795 Context.AtomicUsesUnsupportedLibcall(AE))
4797 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4798 Op == AtomicExpr::AO__opencl_atomic_load ||
4799 Op == AtomicExpr::AO__hip_atomic_load)
4804 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4820 assert(Fn &&
"builtin call without direct callee!");
4836 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4843 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4845 <<
Callee->getSourceRange();
4854 Expr *FirstArg = TheCall->
getArg(0);
4858 FirstArg = FirstArgResult.
get();
4859 TheCall->
setArg(0, FirstArg);
4871 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4878 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4908 QualType ResultType = ValType;
4913#define BUILTIN_ROW(x) \
4914 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4915 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4917 static const unsigned BuiltinIndices[][5] = {
4942 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
4943 case 1: SizeIndex = 0;
break;
4944 case 2: SizeIndex = 1;
break;
4945 case 4: SizeIndex = 2;
break;
4946 case 8: SizeIndex = 3;
break;
4947 case 16: SizeIndex = 4;
break;
4959 unsigned BuiltinIndex, NumFixed = 1;
4960 bool WarnAboutSemanticsChange =
false;
4961 switch (BuiltinID) {
4962 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4963 case Builtin::BI__sync_fetch_and_add:
4964 case Builtin::BI__sync_fetch_and_add_1:
4965 case Builtin::BI__sync_fetch_and_add_2:
4966 case Builtin::BI__sync_fetch_and_add_4:
4967 case Builtin::BI__sync_fetch_and_add_8:
4968 case Builtin::BI__sync_fetch_and_add_16:
4972 case Builtin::BI__sync_fetch_and_sub:
4973 case Builtin::BI__sync_fetch_and_sub_1:
4974 case Builtin::BI__sync_fetch_and_sub_2:
4975 case Builtin::BI__sync_fetch_and_sub_4:
4976 case Builtin::BI__sync_fetch_and_sub_8:
4977 case Builtin::BI__sync_fetch_and_sub_16:
4981 case Builtin::BI__sync_fetch_and_or:
4982 case Builtin::BI__sync_fetch_and_or_1:
4983 case Builtin::BI__sync_fetch_and_or_2:
4984 case Builtin::BI__sync_fetch_and_or_4:
4985 case Builtin::BI__sync_fetch_and_or_8:
4986 case Builtin::BI__sync_fetch_and_or_16:
4990 case Builtin::BI__sync_fetch_and_and:
4991 case Builtin::BI__sync_fetch_and_and_1:
4992 case Builtin::BI__sync_fetch_and_and_2:
4993 case Builtin::BI__sync_fetch_and_and_4:
4994 case Builtin::BI__sync_fetch_and_and_8:
4995 case Builtin::BI__sync_fetch_and_and_16:
4999 case Builtin::BI__sync_fetch_and_xor:
5000 case Builtin::BI__sync_fetch_and_xor_1:
5001 case Builtin::BI__sync_fetch_and_xor_2:
5002 case Builtin::BI__sync_fetch_and_xor_4:
5003 case Builtin::BI__sync_fetch_and_xor_8:
5004 case Builtin::BI__sync_fetch_and_xor_16:
5008 case Builtin::BI__sync_fetch_and_nand:
5009 case Builtin::BI__sync_fetch_and_nand_1:
5010 case Builtin::BI__sync_fetch_and_nand_2:
5011 case Builtin::BI__sync_fetch_and_nand_4:
5012 case Builtin::BI__sync_fetch_and_nand_8:
5013 case Builtin::BI__sync_fetch_and_nand_16:
5015 WarnAboutSemanticsChange =
true;
5018 case Builtin::BI__sync_add_and_fetch:
5019 case Builtin::BI__sync_add_and_fetch_1:
5020 case Builtin::BI__sync_add_and_fetch_2:
5021 case Builtin::BI__sync_add_and_fetch_4:
5022 case Builtin::BI__sync_add_and_fetch_8:
5023 case Builtin::BI__sync_add_and_fetch_16:
5027 case Builtin::BI__sync_sub_and_fetch:
5028 case Builtin::BI__sync_sub_and_fetch_1:
5029 case Builtin::BI__sync_sub_and_fetch_2:
5030 case Builtin::BI__sync_sub_and_fetch_4:
5031 case Builtin::BI__sync_sub_and_fetch_8:
5032 case Builtin::BI__sync_sub_and_fetch_16:
5036 case Builtin::BI__sync_and_and_fetch:
5037 case Builtin::BI__sync_and_and_fetch_1:
5038 case Builtin::BI__sync_and_and_fetch_2:
5039 case Builtin::BI__sync_and_and_fetch_4:
5040 case Builtin::BI__sync_and_and_fetch_8:
5041 case Builtin::BI__sync_and_and_fetch_16:
5045 case Builtin::BI__sync_or_and_fetch:
5046 case Builtin::BI__sync_or_and_fetch_1:
5047 case Builtin::BI__sync_or_and_fetch_2:
5048 case Builtin::BI__sync_or_and_fetch_4:
5049 case Builtin::BI__sync_or_and_fetch_8:
5050 case Builtin::BI__sync_or_and_fetch_16:
5054 case Builtin::BI__sync_xor_and_fetch:
5055 case Builtin::BI__sync_xor_and_fetch_1:
5056 case Builtin::BI__sync_xor_and_fetch_2:
5057 case Builtin::BI__sync_xor_and_fetch_4:
5058 case Builtin::BI__sync_xor_and_fetch_8:
5059 case Builtin::BI__sync_xor_and_fetch_16:
5063 case Builtin::BI__sync_nand_and_fetch:
5064 case Builtin::BI__sync_nand_and_fetch_1:
5065 case Builtin::BI__sync_nand_and_fetch_2:
5066 case Builtin::BI__sync_nand_and_fetch_4:
5067 case Builtin::BI__sync_nand_and_fetch_8:
5068 case Builtin::BI__sync_nand_and_fetch_16:
5070 WarnAboutSemanticsChange =
true;
5073 case Builtin::BI__sync_val_compare_and_swap:
5074 case Builtin::BI__sync_val_compare_and_swap_1:
5075 case Builtin::BI__sync_val_compare_and_swap_2:
5076 case Builtin::BI__sync_val_compare_and_swap_4:
5077 case Builtin::BI__sync_val_compare_and_swap_8:
5078 case Builtin::BI__sync_val_compare_and_swap_16:
5083 case Builtin::BI__sync_bool_compare_and_swap:
5084 case Builtin::BI__sync_bool_compare_and_swap_1:
5085 case Builtin::BI__sync_bool_compare_and_swap_2:
5086 case Builtin::BI__sync_bool_compare_and_swap_4:
5087 case Builtin::BI__sync_bool_compare_and_swap_8:
5088 case Builtin::BI__sync_bool_compare_and_swap_16:
5094 case Builtin::BI__sync_lock_test_and_set:
5095 case Builtin::BI__sync_lock_test_and_set_1:
5096 case Builtin::BI__sync_lock_test_and_set_2:
5097 case Builtin::BI__sync_lock_test_and_set_4:
5098 case Builtin::BI__sync_lock_test_and_set_8:
5099 case Builtin::BI__sync_lock_test_and_set_16:
5103 case Builtin::BI__sync_lock_release:
5104 case Builtin::BI__sync_lock_release_1:
5105 case Builtin::BI__sync_lock_release_2:
5106 case Builtin::BI__sync_lock_release_4:
5107 case Builtin::BI__sync_lock_release_8:
5108 case Builtin::BI__sync_lock_release_16:
5114 case Builtin::BI__sync_swap:
5115 case Builtin::BI__sync_swap_1:
5116 case Builtin::BI__sync_swap_2:
5117 case Builtin::BI__sync_swap_4:
5118 case Builtin::BI__sync_swap_8:
5119 case Builtin::BI__sync_swap_16:
5127 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5128 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5129 <<
Callee->getSourceRange();
5133 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5134 <<
Callee->getSourceRange();
5136 if (WarnAboutSemanticsChange) {
5137 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5138 <<
Callee->getSourceRange();
5143 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5144 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5145 FunctionDecl *NewBuiltinDecl;
5146 if (NewBuiltinID == BuiltinID)
5147 NewBuiltinDecl = FDecl;
5150 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5153 assert(Res.getFoundDecl());
5154 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5155 if (!NewBuiltinDecl)
5162 for (
unsigned i = 0; i != NumFixed; ++i) {
5191 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5193 CK_BuiltinFnToFnPtr);
5204 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5205 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5206 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5210 return TheCallResult;
5214 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5219 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5220 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5221 "Unexpected nontemporal load/store builtin!");
5222 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5223 unsigned numArgs = isStore ? 2 : 1;
5233 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5239 PointerArg = PointerArgResult.
get();
5240 TheCall->
setArg(numArgs - 1, PointerArg);
5244 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5257 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5264 return TheCallResult;
5276 return TheCallResult;
5283 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5285 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5286 Literal = ObjcLiteral->getString();
5290 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5297 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5298 InitializedEntity Entity =
5308 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5309 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5310 TT.getArch() == llvm::Triple::aarch64_32);
5311 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5312 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5313 if (IsX64 || IsAArch64) {
5320 return S.
Diag(Fn->getBeginLoc(),
5321 diag::err_ms_va_start_used_in_sysv_function);
5328 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5329 return S.
Diag(Fn->getBeginLoc(),
5330 diag::err_va_start_used_in_wrong_abi_function)
5331 << !IsWindowsOrUEFI;
5337 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5345 bool IsVariadic =
false;
5348 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5349 IsVariadic =
Block->isVariadic();
5350 Params =
Block->parameters();
5351 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5354 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5355 IsVariadic = MD->isVariadic();
5357 Params = MD->parameters();
5360 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5364 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5369 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5374 *LastParam = Params.empty() ?
nullptr : Params.back();
5379bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5384 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5408 ParmVarDecl *LastParam;
5419 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5421 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5426 if (std::optional<llvm::APSInt> Val =
5428 Val &&
LangOpts.C23 && *Val == 0 &&
5429 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5430 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5437 SourceLocation ParamLoc;
5438 bool IsCRegister =
false;
5439 bool SecondArgIsLastNonVariadicArgument =
false;
5440 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5441 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5442 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5445 ParamLoc = PV->getLocation();
5451 if (!SecondArgIsLastNonVariadicArgument)
5453 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5454 else if (IsCRegister ||
Type->isReferenceType() ||
5455 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5458 if (!Context.isPromotableIntegerType(Type))
5460 const auto *ED = Type->getAsEnumDecl();
5463 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5465 unsigned Reason = 0;
5466 if (
Type->isReferenceType()) Reason = 1;
5467 else if (IsCRegister) Reason = 2;
5468 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5469 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5476 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5496 if (
Call->getNumArgs() < 3)
5498 diag::err_typecheck_call_too_few_args_at_least)
5499 << 0 << 3 <<
Call->getNumArgs()
5512 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5515 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5518 const QualType &ConstCharPtrTy =
5520 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5522 << Arg1->
getType() << ConstCharPtrTy << 1
5525 << 2 << Arg1->
getType() << ConstCharPtrTy;
5527 const QualType SizeTy =
Context.getSizeType();
5532 << Arg2->
getType() << SizeTy << 1
5535 << 3 << Arg2->
getType() << SizeTy;
5540bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5544 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5572 diag::err_typecheck_call_invalid_ordered_compare)
5580bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5581 unsigned BuiltinID) {
5586 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5587 BuiltinID == Builtin::BI__builtin_isinf ||
5588 BuiltinID == Builtin::BI__builtin_isinf_sign))
5592 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5593 BuiltinID == Builtin::BI__builtin_isunordered))
5597 bool IsFPClass = NumArgs == 2;
5600 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5604 for (
unsigned i = 0; i < FPArgNo; ++i) {
5605 Expr *Arg = TheCall->
getArg(i);
5618 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5626 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5631 OrigArg = Res.
get();
5637 OrigArg = Res.
get();
5639 TheCall->
setArg(FPArgNo, OrigArg);
5641 QualType VectorResultTy;
5642 QualType ElementTy = OrigArg->
getType();
5647 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5653 diag::err_typecheck_call_invalid_unary_fp)
5665 if (!VectorResultTy.
isNull())
5666 ResultTy = VectorResultTy;
5675bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5680 for (
unsigned I = 0; I != 2; ++I) {
5681 Expr *Arg = TheCall->
getArg(I);
5691 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5706 Expr *Real = TheCall->
getArg(0);
5707 Expr *Imag = TheCall->
getArg(1);
5710 diag::err_typecheck_call_different_arg_types)
5725 diag::err_typecheck_call_too_few_args_at_least)
5726 << 0 << 2 << NumArgs
5733 unsigned NumElements = 0;
5748 unsigned NumResElements = NumArgs - 2;
5757 diag::err_vec_builtin_incompatible_vector)
5762 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5764 diag::err_vec_builtin_incompatible_vector)
5769 }
else if (NumElements != NumResElements) {
5772 ?
Context.getExtVectorType(EltType, NumResElements)
5773 :
Context.getVectorType(EltType, NumResElements,
5778 for (
unsigned I = 2; I != NumArgs; ++I) {
5786 diag::err_shufflevector_nonconstant_argument)
5792 else if (
Result->getActiveBits() > 64 ||
5793 Result->getZExtValue() >= NumElements * 2)
5795 diag::err_shufflevector_argument_too_large)
5820 diag::err_convertvector_non_vector)
5823 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5825 <<
"__builtin_convertvector");
5830 if (SrcElts != DstElts)
5832 diag::err_convertvector_incompatible_vector)
5840bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5845 diag::err_typecheck_call_too_many_args_at_most)
5846 << 0 << 3 << NumArgs << 0
5851 for (
unsigned i = 1; i != NumArgs; ++i)
5858bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5859 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5860 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5870 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5880bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5881 Expr *Arg = TheCall->
getArg(0);
5892bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5894 Expr *Arg = TheCall->
getArg(1);
5898 if (
const auto *UE =
5900 if (UE->getKind() == UETT_AlignOf ||
5901 UE->getKind() == UETT_PreferredAlignOf)
5907 if (!
Result.isPowerOf2())
5908 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5915 if (
Result > std::numeric_limits<int32_t>::max())
5923bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5928 Expr *FirstArg = TheCall->
getArg(0);
5934 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5938 TheCall->
setArg(0, FirstArgResult.
get());
5942 Expr *SecondArg = TheCall->
getArg(1);
5950 if (!
Result.isPowerOf2())
5951 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5960 Expr *ThirdArg = TheCall->
getArg(2);
5963 TheCall->
setArg(2, ThirdArg);
5969bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5970 unsigned BuiltinID =
5972 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5975 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5976 if (NumArgs < NumRequiredArgs) {
5977 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5978 << 0 << NumRequiredArgs << NumArgs
5981 if (NumArgs >= NumRequiredArgs + 0x100) {
5983 diag::err_typecheck_call_too_many_args_at_most)
5984 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5995 if (Arg.isInvalid())
5997 TheCall->
setArg(i, Arg.get());
6002 unsigned FormatIdx = i;
6012 unsigned FirstDataArg = i;
6013 while (i < NumArgs) {
6031 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6033 bool Success = CheckFormatArguments(
6036 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6060 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6069 int High,
bool RangeIsError) {
6083 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6091 PDiag(diag::warn_argument_invalid_range)
6134 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6139 if (
Value.isNegative())
6150 if ((
Value & 0xFF) != 0)
6175 Result.setIsUnsigned(
true);
6180 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6200 Result.setIsUnsigned(
true);
6208 diag::err_argument_not_shifted_byte_or_xxff)
6212bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6213 if (!Context.getTargetInfo().hasSjLjLowering())
6214 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6225 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6231bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6232 if (!Context.getTargetInfo().hasSjLjLowering())
6233 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6238bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6253 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6258 diag::err_builtin_counted_by_ref_has_side_effects)
6261 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6262 if (!ME->isFlexibleArrayMemberLike(
6265 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6269 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6272 if (
const FieldDecl *CountFD = FAMDecl->findCountedByField()) {
6279 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6289bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6291 const CallExpr *CE =
6300 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6305 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6310 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6314 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6318 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6328class UncoveredArgHandler {
6329 enum {
Unknown = -1, AllCovered = -2 };
6331 signed FirstUncoveredArg =
Unknown;
6332 SmallVector<const Expr *, 4> DiagnosticExprs;
6335 UncoveredArgHandler() =
default;
6337 bool hasUncoveredArg()
const {
6338 return (FirstUncoveredArg >= 0);
6341 unsigned getUncoveredArg()
const {
6342 assert(hasUncoveredArg() &&
"no uncovered argument");
6343 return FirstUncoveredArg;
6346 void setAllCovered() {
6349 DiagnosticExprs.clear();
6350 FirstUncoveredArg = AllCovered;
6353 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6354 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6357 if (FirstUncoveredArg == AllCovered)
6362 if (NewFirstUncoveredArg == FirstUncoveredArg)
6363 DiagnosticExprs.push_back(StrExpr);
6364 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6365 DiagnosticExprs.clear();
6366 DiagnosticExprs.push_back(StrExpr);
6367 FirstUncoveredArg = NewFirstUncoveredArg;
6371 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6374enum StringLiteralCheckType {
6376 SLCT_UncheckedLiteral,
6384 bool AddendIsRight) {
6385 unsigned BitWidth = Offset.getBitWidth();
6386 unsigned AddendBitWidth = Addend.getBitWidth();
6388 if (Addend.isUnsigned()) {
6389 Addend = Addend.zext(++AddendBitWidth);
6390 Addend.setIsSigned(
true);
6393 if (AddendBitWidth > BitWidth) {
6394 Offset = Offset.sext(AddendBitWidth);
6395 BitWidth = AddendBitWidth;
6396 }
else if (BitWidth > AddendBitWidth) {
6397 Addend = Addend.sext(BitWidth);
6401 llvm::APSInt ResOffset = Offset;
6402 if (BinOpKind == BO_Add)
6403 ResOffset = Offset.sadd_ov(Addend, Ov);
6405 assert(AddendIsRight && BinOpKind == BO_Sub &&
6406 "operator must be add or sub with addend on the right");
6407 ResOffset = Offset.ssub_ov(Addend, Ov);
6413 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6414 "index (intermediate) result too big");
6415 Offset = Offset.sext(2 * BitWidth);
6416 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6428class FormatStringLiteral {
6429 const StringLiteral *FExpr;
6433 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6434 : FExpr(fexpr), Offset(Offset) {}
6436 const StringLiteral *getFormatString()
const {
return FExpr; }
6438 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6440 unsigned getByteLength()
const {
6441 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6444 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6451 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6452 bool isWide()
const {
return FExpr->
isWide(); }
6453 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6454 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6455 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6456 bool isPascal()
const {
return FExpr->
isPascal(); }
6458 SourceLocation getLocationOfByte(
6459 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6460 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6461 unsigned *StartTokenByteOffset =
nullptr)
const {
6463 StartToken, StartTokenByteOffset);
6466 SourceLocation getBeginLoc() const LLVM_READONLY {
6470 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6476 Sema &S,
const FormatStringLiteral *FExpr,
6481 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6482 bool IgnoreStringsWithoutSpecifiers);
6496 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6497 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6499 return SLCT_NotALiteral;
6501 assert(Offset.isSigned() &&
"invalid offset");
6504 return SLCT_NotALiteral;
6513 return SLCT_UncheckedLiteral;
6516 case Stmt::InitListExprClass:
6520 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6521 Type, CallType,
false, CheckedVarArgs,
6522 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6524 return SLCT_NotALiteral;
6525 case Stmt::BinaryConditionalOperatorClass:
6526 case Stmt::ConditionalOperatorClass: {
6535 bool CheckLeft =
true, CheckRight =
true;
6538 if (
C->getCond()->EvaluateAsBooleanCondition(
6550 StringLiteralCheckType Left;
6552 Left = SLCT_UncheckedLiteral;
6555 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6556 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6557 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6558 if (Left == SLCT_NotALiteral || !CheckRight) {
6564 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6565 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6566 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6568 return (CheckLeft && Left < Right) ? Left : Right;
6571 case Stmt::ImplicitCastExprClass:
6575 case Stmt::OpaqueValueExprClass:
6580 return SLCT_NotALiteral;
6582 case Stmt::PredefinedExprClass:
6586 return SLCT_UncheckedLiteral;
6588 case Stmt::DeclRefExprClass: {
6594 bool isConstant =
false;
6598 isConstant = AT->getElementType().isConstant(S.
Context);
6600 isConstant =
T.isConstant(S.
Context) &&
6601 PT->getPointeeType().isConstant(S.
Context);
6602 }
else if (
T->isObjCObjectPointerType()) {
6605 isConstant =
T.isConstant(S.
Context);
6609 if (
const Expr *
Init = VD->getAnyInitializer()) {
6612 if (InitList->isStringLiteralInit())
6613 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6616 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6617 firstDataArg,
Type, CallType,
6618 false, CheckedVarArgs, UncoveredArg, Offset);
6669 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6670 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6671 for (
const auto *PVFormatMatches :
6672 D->specific_attrs<FormatMatchesAttr>()) {
6677 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6681 S.
Diag(Args[format_idx]->getBeginLoc(),
6682 diag::warn_format_string_type_incompatible)
6683 << PVFormatMatches->getType()->getName()
6685 if (!InFunctionCall) {
6686 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6687 diag::note_format_string_defined);
6689 return SLCT_UncheckedLiteral;
6692 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6693 Args, APK, format_idx, firstDataArg,
Type, CallType,
6694 false, CheckedVarArgs, UncoveredArg,
6695 Offset, IgnoreStringsWithoutSpecifiers);
6699 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6702 PVFormat->getFirstArg(), &CallerFSI))
6704 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6708 S.
Diag(Args[format_idx]->getBeginLoc(),
6709 diag::warn_format_string_type_incompatible)
6710 << PVFormat->getType()->getName()
6712 if (!InFunctionCall) {
6715 return SLCT_UncheckedLiteral;
6728 return SLCT_UncheckedLiteral;
6736 return SLCT_NotALiteral;
6739 case Stmt::CallExprClass:
6740 case Stmt::CXXMemberCallExprClass: {
6744 StringLiteralCheckType CommonResult;
6745 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6746 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6748 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6749 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6750 Offset, IgnoreStringsWithoutSpecifiers);
6752 CommonResult = Result;
6757 return CommonResult;
6759 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6761 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6762 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6765 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6766 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6767 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6773 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6774 Type, CallType,
false, CheckedVarArgs,
6775 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6776 return SLCT_NotALiteral;
6778 case Stmt::ObjCMessageExprClass: {
6780 if (
const auto *MD = ME->getMethodDecl()) {
6781 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6790 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6792 MD->getSelector().isKeywordSelector(
6793 {
"localizedStringForKey",
"value",
"table"})) {
6794 IgnoreStringsWithoutSpecifiers =
true;
6797 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6799 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6800 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6801 Offset, IgnoreStringsWithoutSpecifiers);
6805 return SLCT_NotALiteral;
6807 case Stmt::ObjCStringLiteralClass:
6808 case Stmt::StringLiteralClass: {
6817 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6820 return SLCT_NotALiteral;
6822 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6824 format_idx, firstDataArg,
Type, InFunctionCall,
6825 CallType, CheckedVarArgs, UncoveredArg,
6826 IgnoreStringsWithoutSpecifiers);
6827 return SLCT_CheckedLiteral;
6830 return SLCT_NotALiteral;
6832 case Stmt::BinaryOperatorClass: {
6846 if (LIsInt != RIsInt) {
6850 if (BinOpKind == BO_Add) {
6863 return SLCT_NotALiteral;
6865 case Stmt::UnaryOperatorClass: {
6867 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6868 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6870 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6880 return SLCT_NotALiteral;
6884 return SLCT_NotALiteral;
6895 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6896 if (isa_and_nonnull<StringLiteral>(LVE))
6917 return "freebsd_kprintf";
6926 return llvm::StringSwitch<FormatStringType>(Flavor)
6928 .Cases(
"gnu_printf",
"printf",
"printf0",
"syslog",
6933 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
6949bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6953 llvm::SmallBitVector &CheckedVarArgs) {
6954 FormatStringInfo FSI;
6958 return CheckFormatArguments(
6959 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
6964bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
6968 llvm::SmallBitVector &CheckedVarArgs) {
6969 FormatStringInfo FSI;
6973 return CheckFormatArguments(Args, FSI.ArgPassingKind,
6974 Format->getFormatString(), FSI.FormatIdx,
6976 CallType, Loc, Range, CheckedVarArgs);
6984 unsigned format_idx,
unsigned firstDataArg,
6988 llvm::SmallBitVector &CheckedVarArgs) {
6990 if (format_idx >= Args.size()) {
6991 Diag(Loc, diag::warn_missing_format_string) <<
Range;
6995 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7009 UncoveredArgHandler UncoveredArg;
7011 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7012 firstDataArg,
Type, CallType,
7013 true, CheckedVarArgs, UncoveredArg,
7014 llvm::APSInt(64,
false) = 0);
7017 if (UncoveredArg.hasUncoveredArg()) {
7018 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7019 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7020 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7023 if (CT != SLCT_NotALiteral)
7025 return CT == SLCT_CheckedLiteral;
7036 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7043 if (Args.size() == firstDataArg) {
7044 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7052 Diag(FormatLoc, diag::note_format_security_fixit)
7056 Diag(FormatLoc, diag::note_format_security_fixit)
7061 Diag(FormatLoc, diag::warn_format_nonliteral)
7072 const FormatStringLiteral *FExpr;
7073 const Expr *OrigFormatExpr;
7075 const unsigned FirstDataArg;
7076 const unsigned NumDataArgs;
7079 ArrayRef<const Expr *> Args;
7081 llvm::SmallBitVector CoveredArgs;
7082 bool usesPositionalArgs =
false;
7083 bool atFirstArg =
true;
7084 bool inFunctionCall;
7086 llvm::SmallBitVector &CheckedVarArgs;
7087 UncoveredArgHandler &UncoveredArg;
7090 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7092 unsigned firstDataArg,
unsigned numDataArgs,
7094 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7096 llvm::SmallBitVector &CheckedVarArgs,
7097 UncoveredArgHandler &UncoveredArg)
7098 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7099 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7100 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7101 inFunctionCall(inFunctionCall), CallType(callType),
7102 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7103 CoveredArgs.resize(numDataArgs);
7104 CoveredArgs.reset();
7107 bool HasFormatArguments()
const {
7112 void DoneProcessing();
7114 void HandleIncompleteSpecifier(
const char *startSpecifier,
7115 unsigned specifierLen)
override;
7117 void HandleInvalidLengthModifier(
7118 const analyze_format_string::FormatSpecifier &FS,
7119 const analyze_format_string::ConversionSpecifier &CS,
7120 const char *startSpecifier,
unsigned specifierLen,
7123 void HandleNonStandardLengthModifier(
7124 const analyze_format_string::FormatSpecifier &FS,
7125 const char *startSpecifier,
unsigned specifierLen);
7127 void HandleNonStandardConversionSpecifier(
7128 const analyze_format_string::ConversionSpecifier &CS,
7129 const char *startSpecifier,
unsigned specifierLen);
7131 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7133 void HandleInvalidPosition(
const char *startSpecifier,
7134 unsigned specifierLen,
7137 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7139 void HandleNullChar(
const char *nullCharacter)
override;
7141 template <
typename Range>
7143 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7144 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7145 bool IsStringLocation, Range StringRange,
7146 ArrayRef<FixItHint> Fixit = {});
7149 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7150 const char *startSpec,
7151 unsigned specifierLen,
7152 const char *csStart,
unsigned csLen);
7154 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7155 const char *startSpec,
7156 unsigned specifierLen);
7158 SourceRange getFormatStringRange();
7159 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7160 unsigned specifierLen);
7161 SourceLocation getLocationOfByte(
const char *x);
7163 const Expr *getDataArg(
unsigned i)
const;
7165 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7166 const analyze_format_string::ConversionSpecifier &CS,
7167 const char *startSpecifier,
unsigned specifierLen,
7170 template <
typename Range>
7171 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7172 bool IsStringLocation, Range StringRange,
7173 ArrayRef<FixItHint> Fixit = {});
7178SourceRange CheckFormatHandler::getFormatStringRange() {
7183getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7185 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7193SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7198void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7199 unsigned specifierLen){
7200 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7201 getLocationOfByte(startSpecifier),
7203 getSpecifierRange(startSpecifier, specifierLen));
7206void CheckFormatHandler::HandleInvalidLengthModifier(
7209 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7221 getSpecifierRange(startSpecifier, specifierLen));
7223 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7224 << FixedLM->toString()
7229 if (DiagID == diag::warn_format_nonsensical_length)
7235 getSpecifierRange(startSpecifier, specifierLen),
7240void CheckFormatHandler::HandleNonStandardLengthModifier(
7242 const char *startSpecifier,
unsigned specifierLen) {
7251 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7255 getSpecifierRange(startSpecifier, specifierLen));
7257 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7258 << FixedLM->toString()
7262 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7266 getSpecifierRange(startSpecifier, specifierLen));
7270void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7272 const char *startSpecifier,
unsigned specifierLen) {
7278 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7282 getSpecifierRange(startSpecifier, specifierLen));
7285 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7286 << FixedCS->toString()
7289 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7293 getSpecifierRange(startSpecifier, specifierLen));
7297void CheckFormatHandler::HandlePosition(
const char *startPos,
7300 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7301 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7302 getLocationOfByte(startPos),
7304 getSpecifierRange(startPos, posLen));
7307void CheckFormatHandler::HandleInvalidPosition(
7308 const char *startSpecifier,
unsigned specifierLen,
7311 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7312 EmitFormatDiagnostic(
7313 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7314 getLocationOfByte(startSpecifier),
true,
7315 getSpecifierRange(startSpecifier, specifierLen));
7318void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7322 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7323 getLocationOfByte(startPos),
7325 getSpecifierRange(startPos, posLen));
7328void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7331 EmitFormatDiagnostic(
7332 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7333 getLocationOfByte(nullCharacter),
true,
7334 getFormatStringRange());
7340const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7341 return Args[FirstDataArg + i];
7344void CheckFormatHandler::DoneProcessing() {
7347 if (HasFormatArguments()) {
7350 signed notCoveredArg = CoveredArgs.find_first();
7351 if (notCoveredArg >= 0) {
7352 assert((
unsigned)notCoveredArg < NumDataArgs);
7353 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7355 UncoveredArg.setAllCovered();
7360void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7361 const Expr *ArgExpr) {
7362 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7374 for (
auto E : DiagnosticExprs)
7377 CheckFormatHandler::EmitFormatDiagnostic(
7378 S, IsFunctionCall, DiagnosticExprs[0],
7384CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7386 const char *startSpec,
7387 unsigned specifierLen,
7388 const char *csStart,
7390 bool keepGoing =
true;
7391 if (argIndex < NumDataArgs) {
7394 CoveredArgs.set(argIndex);
7410 std::string CodePointStr;
7411 if (!llvm::sys::locale::isPrint(*csStart)) {
7412 llvm::UTF32 CodePoint;
7413 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7414 const llvm::UTF8 *E =
7415 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7416 llvm::ConversionResult
Result =
7417 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7419 if (
Result != llvm::conversionOK) {
7420 unsigned char FirstChar = *csStart;
7421 CodePoint = (llvm::UTF32)FirstChar;
7424 llvm::raw_string_ostream
OS(CodePointStr);
7425 if (CodePoint < 256)
7426 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7427 else if (CodePoint <= 0xFFFF)
7428 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7430 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7434 EmitFormatDiagnostic(
7435 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7436 true, getSpecifierRange(startSpec, specifierLen));
7442CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7443 const char *startSpec,
7444 unsigned specifierLen) {
7445 EmitFormatDiagnostic(
7446 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7447 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7451CheckFormatHandler::CheckNumArgs(
7454 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7456 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7458 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7459 << (argIndex+1) << NumDataArgs)
7460 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7461 EmitFormatDiagnostic(
7462 PDiag, getLocationOfByte(CS.
getStart()),
true,
7463 getSpecifierRange(startSpecifier, specifierLen));
7467 UncoveredArg.setAllCovered();
7473template<
typename Range>
7476 bool IsStringLocation,
7479 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7480 Loc, IsStringLocation, StringRange, FixIt);
7510template <
typename Range>
7511void CheckFormatHandler::EmitFormatDiagnostic(
7512 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7515 if (InFunctionCall) {
7520 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7524 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7525 diag::note_format_string_defined);
7527 Note << StringRange;
7536class CheckPrintfHandler :
public CheckFormatHandler {
7538 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7540 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7542 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7544 llvm::SmallBitVector &CheckedVarArgs,
7545 UncoveredArgHandler &UncoveredArg)
7546 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7547 numDataArgs, beg, APK, Args, formatIdx,
7548 inFunctionCall, CallType, CheckedVarArgs,
7551 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7554 bool allowsObjCArg()
const {
7555 return FSType == FormatStringType::NSString ||
7556 FSType == FormatStringType::OSLog ||
7557 FSType == FormatStringType::OSTrace;
7560 bool HandleInvalidPrintfConversionSpecifier(
7561 const analyze_printf::PrintfSpecifier &FS,
7562 const char *startSpecifier,
7563 unsigned specifierLen)
override;
7565 void handleInvalidMaskType(StringRef MaskType)
override;
7567 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7568 const char *startSpecifier,
unsigned specifierLen,
7569 const TargetInfo &
Target)
override;
7570 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7571 const char *StartSpecifier,
7572 unsigned SpecifierLen,
7575 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7576 const char *startSpecifier,
unsigned specifierLen);
7577 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7578 const analyze_printf::OptionalAmount &Amt,
7580 const char *startSpecifier,
unsigned specifierLen);
7581 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7582 const analyze_printf::OptionalFlag &flag,
7583 const char *startSpecifier,
unsigned specifierLen);
7584 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7585 const analyze_printf::OptionalFlag &ignoredFlag,
7586 const analyze_printf::OptionalFlag &flag,
7587 const char *startSpecifier,
unsigned specifierLen);
7588 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7591 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7592 unsigned flagLen)
override;
7594 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7595 unsigned flagLen)
override;
7598 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7599 const char *flagsEnd,
7600 const char *conversionPosition)
override;
7605class EquatableFormatArgument {
7607 enum SpecifierSensitivity :
unsigned {
7614 enum FormatArgumentRole :
unsigned {
7622 analyze_format_string::ArgType ArgType;
7624 StringRef SpecifierLetter;
7625 CharSourceRange
Range;
7626 SourceLocation ElementLoc;
7627 FormatArgumentRole
Role : 2;
7628 SpecifierSensitivity Sensitivity : 2;
7629 unsigned Position : 14;
7630 unsigned ModifierFor : 14;
7632 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7633 bool InFunctionCall)
const;
7636 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7638 StringRef SpecifierLetter,
7639 analyze_format_string::ArgType ArgType,
7640 FormatArgumentRole
Role,
7641 SpecifierSensitivity Sensitivity,
unsigned Position,
7642 unsigned ModifierFor)
7643 : ArgType(ArgType), LengthMod(LengthMod),
7644 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7645 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7646 ModifierFor(ModifierFor) {}
7648 unsigned getPosition()
const {
return Position; }
7649 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7651 analyze_format_string::LengthModifier getLengthModifier()
const {
7652 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7654 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7656 std::string buildFormatSpecifier()
const {
7658 llvm::raw_string_ostream(result)
7659 << getLengthModifier().toString() << SpecifierLetter;
7663 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7664 const Expr *FmtExpr,
bool InFunctionCall)
const;
7668class DecomposePrintfHandler :
public CheckPrintfHandler {
7669 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7672 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7673 const Expr *origFormatExpr,
7675 unsigned numDataArgs,
bool isObjC,
const char *beg,
7677 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7679 llvm::SmallBitVector &CheckedVarArgs,
7680 UncoveredArgHandler &UncoveredArg,
7681 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7682 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7683 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7684 inFunctionCall, CallType, CheckedVarArgs,
7686 Specs(Specs), HadError(
false) {}
7690 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7692 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7694 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7695 const char *startSpecifier,
7696 unsigned specifierLen,
7697 const TargetInfo &
Target)
override;
7702bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7704 unsigned specifierLen) {
7708 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7710 startSpecifier, specifierLen,
7714void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7715 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7723 return T->isRecordType() ||
T->isComplexType();
7726bool CheckPrintfHandler::HandleAmount(
7728 const char *startSpecifier,
unsigned specifierLen) {
7730 if (HasFormatArguments()) {
7732 if (argIndex >= NumDataArgs) {
7733 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7737 getSpecifierRange(startSpecifier, specifierLen));
7747 CoveredArgs.set(argIndex);
7748 const Expr *Arg = getDataArg(argIndex);
7759 ? diag::err_printf_asterisk_wrong_type
7760 : diag::warn_printf_asterisk_wrong_type;
7761 EmitFormatDiagnostic(S.
PDiag(DiagID)
7766 getSpecifierRange(startSpecifier, specifierLen));
7776void CheckPrintfHandler::HandleInvalidAmount(
7780 const char *startSpecifier,
7781 unsigned specifierLen) {
7791 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7795 getSpecifierRange(startSpecifier, specifierLen),
7801 const char *startSpecifier,
7802 unsigned specifierLen) {
7806 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7810 getSpecifierRange(startSpecifier, specifierLen),
7815void CheckPrintfHandler::HandleIgnoredFlag(
7819 const char *startSpecifier,
7820 unsigned specifierLen) {
7822 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7826 getSpecifierRange(startSpecifier, specifierLen),
7828 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7831void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7834 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7835 getLocationOfByte(startFlag),
7837 getSpecifierRange(startFlag, flagLen));
7840void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7843 auto Range = getSpecifierRange(startFlag, flagLen);
7844 StringRef flag(startFlag, flagLen);
7845 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7846 getLocationOfByte(startFlag),
7851void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7852 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7854 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7855 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7856 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
7857 getLocationOfByte(conversionPosition),
7863 const Expr *FmtExpr,
7864 bool InFunctionCall)
const {
7865 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7866 ElementLoc,
true, Range);
7869bool EquatableFormatArgument::VerifyCompatible(
7870 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7871 bool InFunctionCall)
const {
7876 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
7877 FmtExpr, InFunctionCall);
7878 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7882 if (
Role != FAR_Data) {
7883 if (ModifierFor !=
Other.ModifierFor) {
7886 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
7887 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
7888 FmtExpr, InFunctionCall);
7889 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7895 bool HadError =
false;
7896 if (Sensitivity !=
Other.Sensitivity) {
7899 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
7900 << Sensitivity <<
Other.Sensitivity,
7901 FmtExpr, InFunctionCall);
7902 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7903 << 0 <<
Other.Range;
7906 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
7910 case MK::MatchPromotion:
7914 case MK::NoMatchTypeConfusion:
7915 case MK::NoMatchPromotionTypeConfusion:
7917 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
7918 << buildFormatSpecifier()
7919 <<
Other.buildFormatSpecifier(),
7920 FmtExpr, InFunctionCall);
7921 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7922 << 0 <<
Other.Range;
7925 case MK::NoMatchPedantic:
7927 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
7928 << buildFormatSpecifier()
7929 <<
Other.buildFormatSpecifier(),
7930 FmtExpr, InFunctionCall);
7931 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7932 << 0 <<
Other.Range;
7935 case MK::NoMatchSignedness:
7937 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
7938 << buildFormatSpecifier()
7939 <<
Other.buildFormatSpecifier(),
7940 FmtExpr, InFunctionCall);
7941 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7942 << 0 <<
Other.Range;
7948bool DecomposePrintfHandler::GetSpecifiers(
7949 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7952 StringRef
Data = FSL->getString();
7953 const char *Str =
Data.data();
7954 llvm::SmallBitVector BV;
7955 UncoveredArgHandler UA;
7956 const Expr *PrintfArgs[] = {FSL->getFormatString()};
7957 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
7969 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
7970 const EquatableFormatArgument &B) {
7971 return A.getPosition() < B.getPosition();
7976bool DecomposePrintfHandler::HandlePrintfSpecifier(
7979 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
7994 const unsigned Unset = ~0;
7995 unsigned FieldWidthIndex = Unset;
7996 unsigned PrecisionIndex = Unset;
8000 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8001 FieldWidthIndex = Specs.size();
8002 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8003 getLocationOfByte(FieldWidth.getStart()),
8005 FieldWidth.getArgType(S.
Context),
8006 EquatableFormatArgument::FAR_FieldWidth,
8007 EquatableFormatArgument::SS_None,
8008 FieldWidth.usesPositionalArg()
8009 ? FieldWidth.getPositionalArgIndex() - 1
8015 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8016 PrecisionIndex = Specs.size();
8018 getSpecifierRange(startSpecifier, specifierLen),
8019 getLocationOfByte(Precision.getStart()),
8021 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8022 EquatableFormatArgument::SS_None,
8023 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8029 unsigned SpecIndex =
8031 if (FieldWidthIndex != Unset)
8032 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8033 if (PrecisionIndex != Unset)
8034 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8036 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8038 Sensitivity = EquatableFormatArgument::SS_Private;
8040 Sensitivity = EquatableFormatArgument::SS_Public;
8042 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8044 Sensitivity = EquatableFormatArgument::SS_None;
8047 getSpecifierRange(startSpecifier, specifierLen),
8050 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8055 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8060 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8061 SpecIndex + 1, SpecIndex);
8069template<
typename MemberKind>
8087 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8102 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8104 if ((*MI)->getMinRequiredArguments() == 0)
8112bool CheckPrintfHandler::checkForCStrMembers(
8119 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8122 if (
Method->getMinRequiredArguments() == 0 &&
8135bool CheckPrintfHandler::HandlePrintfSpecifier(
8149 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8150 startSpecifier, specifierLen);
8158 startSpecifier, specifierLen)) {
8163 startSpecifier, specifierLen)) {
8167 if (!CS.consumesDataArgument()) {
8175 if (argIndex < NumDataArgs) {
8179 CoveredArgs.set(argIndex);
8186 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8189 if (HasFormatArguments()) {
8191 CoveredArgs.set(argIndex + 1);
8194 const Expr *Ex = getDataArg(argIndex);
8198 : ArgType::CPointerTy;
8200 EmitFormatDiagnostic(
8201 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8205 getSpecifierRange(startSpecifier, specifierLen));
8208 Ex = getDataArg(argIndex + 1);
8211 EmitFormatDiagnostic(
8212 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8216 getSpecifierRange(startSpecifier, specifierLen));
8223 if (!allowsObjCArg() && CS.isObjCArg()) {
8224 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8231 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8238 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8239 getLocationOfByte(CS.getStart()),
8241 getSpecifierRange(startSpecifier, specifierLen));
8251 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8258 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8262 getSpecifierRange(startSpecifier, specifierLen));
8265 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8269 getSpecifierRange(startSpecifier, specifierLen));
8273 const llvm::Triple &Triple =
Target.getTriple();
8275 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8276 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8277 getLocationOfByte(CS.getStart()),
8279 getSpecifierRange(startSpecifier, specifierLen));
8285 startSpecifier, specifierLen);
8291 startSpecifier, specifierLen);
8297 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8298 getLocationOfByte(startSpecifier),
8300 getSpecifierRange(startSpecifier, specifierLen));
8309 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8311 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8320 startSpecifier, specifierLen);
8323 startSpecifier, specifierLen);
8328 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8329 diag::warn_format_nonsensical_length);
8331 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8333 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8334 diag::warn_format_non_standard_conversion_spec);
8337 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8340 if (!HasFormatArguments())
8343 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8346 const Expr *Arg = getDataArg(argIndex);
8350 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8362 case Stmt::ArraySubscriptExprClass:
8363 case Stmt::CallExprClass:
8364 case Stmt::CharacterLiteralClass:
8365 case Stmt::CXXBoolLiteralExprClass:
8366 case Stmt::DeclRefExprClass:
8367 case Stmt::FloatingLiteralClass:
8368 case Stmt::IntegerLiteralClass:
8369 case Stmt::MemberExprClass:
8370 case Stmt::ObjCArrayLiteralClass:
8371 case Stmt::ObjCBoolLiteralExprClass:
8372 case Stmt::ObjCBoxedExprClass:
8373 case Stmt::ObjCDictionaryLiteralClass:
8374 case Stmt::ObjCEncodeExprClass:
8375 case Stmt::ObjCIvarRefExprClass:
8376 case Stmt::ObjCMessageExprClass:
8377 case Stmt::ObjCPropertyRefExprClass:
8378 case Stmt::ObjCStringLiteralClass:
8379 case Stmt::ObjCSubscriptRefExprClass:
8380 case Stmt::ParenExprClass:
8381 case Stmt::StringLiteralClass:
8382 case Stmt::UnaryOperatorClass:
8389static std::pair<QualType, StringRef>
8396 StringRef Name = UserTy->getDecl()->getName();
8397 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8398 .Case(
"CFIndex", Context.getNSIntegerType())
8399 .Case(
"NSInteger", Context.getNSIntegerType())
8400 .Case(
"NSUInteger", Context.getNSUIntegerType())
8401 .Case(
"SInt32", Context.IntTy)
8402 .Case(
"UInt32", Context.UnsignedIntTy)
8406 return std::make_pair(CastTy, Name);
8408 TyTy = UserTy->desugar();
8412 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8414 PE->getSubExpr()->getType(),
8423 StringRef TrueName, FalseName;
8425 std::tie(TrueTy, TrueName) =
8427 CO->getTrueExpr()->getType(),
8429 std::tie(FalseTy, FalseName) =
8431 CO->getFalseExpr()->getType(),
8432 CO->getFalseExpr());
8434 if (TrueTy == FalseTy)
8435 return std::make_pair(TrueTy, TrueName);
8436 else if (TrueTy.
isNull())
8437 return std::make_pair(FalseTy, FalseName);
8438 else if (FalseTy.
isNull())
8439 return std::make_pair(TrueTy, TrueName);
8442 return std::make_pair(
QualType(), StringRef());
8461 From = VecTy->getElementType();
8463 To = VecTy->getElementType();
8474 diag::warn_format_conversion_argument_type_mismatch_signedness,
8478 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8487 const char *StartSpecifier,
8488 unsigned SpecifierLen,
8500 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8501 ExprTy = TET->getUnderlyingExpr()->getType();
8516 getSpecifierRange(StartSpecifier, SpecifierLen);
8518 llvm::raw_svector_ostream os(FSString);
8520 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8531 getSpecifierRange(StartSpecifier, SpecifierLen);
8532 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8542 if (
Match == ArgType::Match)
8546 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8555 E = ICE->getSubExpr();
8565 if (OrigMatch == ArgType::NoMatchSignedness &&
8566 ImplicitMatch != ArgType::NoMatchSignedness)
8573 if (ImplicitMatch == ArgType::Match)
8591 if (
Match == ArgType::MatchPromotion)
8595 if (
Match == ArgType::MatchPromotion) {
8599 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8600 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8604 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8605 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8606 Match = ImplicitMatch;
8607 assert(
Match != ArgType::MatchPromotion);
8610 bool IsEnum =
false;
8611 bool IsScopedEnum =
false;
8614 IntendedTy = ED->getIntegerType();
8615 if (!ED->isScoped()) {
8616 ExprTy = IntendedTy;
8621 IsScopedEnum =
true;
8628 if (isObjCContext() &&
8639 const llvm::APInt &
V = IL->getValue();
8649 if (TD->getUnderlyingType() == IntendedTy)
8659 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8667 if (!IsScopedEnum &&
8668 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8672 IntendedTy = CastTy;
8673 ShouldNotPrintDirectly =
true;
8678 PrintfSpecifier fixedFS = FS;
8685 llvm::raw_svector_ostream os(buf);
8688 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8690 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8696 llvm_unreachable(
"expected non-matching");
8698 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8701 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8704 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8707 Diag = diag::warn_format_conversion_argument_type_mismatch;
8728 llvm::raw_svector_ostream CastFix(CastBuf);
8729 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8731 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8737 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8742 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8764 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8770 Name = TypedefTy->getDecl()->getName();
8774 ? diag::warn_format_argument_needs_cast_pedantic
8775 : diag::warn_format_argument_needs_cast;
8776 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8787 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8788 : diag::warn_format_conversion_argument_type_mismatch;
8790 EmitFormatDiagnostic(
8802 bool EmitTypeMismatch =
false;
8812 llvm_unreachable(
"expected non-matching");
8814 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8817 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8821 ? diag::err_format_conversion_argument_type_mismatch
8822 : diag::warn_format_conversion_argument_type_mismatch;
8826 EmitFormatDiagnostic(
8835 EmitTypeMismatch =
true;
8837 EmitFormatDiagnostic(
8838 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8839 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8843 checkForCStrMembers(AT, E);
8849 EmitTypeMismatch =
true;
8851 EmitFormatDiagnostic(
8852 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8853 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8866 if (EmitTypeMismatch) {
8872 EmitFormatDiagnostic(
8873 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8879 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
8880 "format string specifier index out of range");
8881 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
8891class CheckScanfHandler :
public CheckFormatHandler {
8893 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8895 unsigned firstDataArg,
unsigned numDataArgs,
8897 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8899 llvm::SmallBitVector &CheckedVarArgs,
8900 UncoveredArgHandler &UncoveredArg)
8901 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8902 numDataArgs, beg, APK, Args, formatIdx,
8903 inFunctionCall, CallType, CheckedVarArgs,
8906 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
8907 const char *startSpecifier,
8908 unsigned specifierLen)
override;
8910 bool HandleInvalidScanfConversionSpecifier(
8911 const analyze_scanf::ScanfSpecifier &FS,
8912 const char *startSpecifier,
8913 unsigned specifierLen)
override;
8915 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8920void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8922 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
8923 getLocationOfByte(end),
true,
8924 getSpecifierRange(start, end - start));
8927bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
8929 const char *startSpecifier,
8930 unsigned specifierLen) {
8934 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8936 startSpecifier, specifierLen,
8940bool CheckScanfHandler::HandleScanfSpecifier(
8942 const char *startSpecifier,
8943 unsigned specifierLen) {
8957 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
8958 startSpecifier, specifierLen);
8969 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
8984 if (argIndex < NumDataArgs) {
8988 CoveredArgs.set(argIndex);
8994 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8995 diag::warn_format_nonsensical_length);
8997 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8999 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9000 diag::warn_format_non_standard_conversion_spec);
9003 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9006 if (!HasFormatArguments())
9009 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9013 const Expr *Ex = getDataArg(argIndex);
9031 ScanfSpecifier fixedFS = FS;
9036 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9038 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9039 : diag::warn_format_conversion_argument_type_mismatch;
9044 llvm::raw_svector_ostream os(buf);
9047 EmitFormatDiagnostic(
9052 getSpecifierRange(startSpecifier, specifierLen),
9054 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9061 getSpecifierRange(startSpecifier, specifierLen));
9071 const Expr *FmtExpr,
bool InFunctionCall) {
9072 bool HadError =
false;
9073 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9074 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9075 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9087 for (; FmtIter < FmtEnd; ++FmtIter) {
9091 if (FmtIter->getPosition() < RefIter->getPosition())
9095 if (FmtIter->getPosition() > RefIter->getPosition())
9099 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9103 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9104 return Arg.getPosition() != RefIter->getPosition();
9108 if (FmtIter < FmtEnd) {
9109 CheckFormatHandler::EmitFormatDiagnostic(
9110 S, InFunctionCall, FmtExpr,
9111 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9112 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9113 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9114 }
else if (RefIter < RefEnd) {
9115 CheckFormatHandler::EmitFormatDiagnostic(
9116 S, InFunctionCall, FmtExpr,
9117 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9120 << 1 << RefIter->getSourceRange();
9126 Sema &S,
const FormatStringLiteral *FExpr,
9131 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9132 bool IgnoreStringsWithoutSpecifiers) {
9134 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9135 CheckFormatHandler::EmitFormatDiagnostic(
9136 S, inFunctionCall, Args[format_idx],
9137 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9143 StringRef StrRef = FExpr->getString();
9144 const char *Str = StrRef.data();
9148 assert(
T &&
"String literal not of constant array type!");
9149 size_t TypeSize =
T->getZExtSize();
9150 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9151 const unsigned numDataArgs = Args.size() - firstDataArg;
9153 if (IgnoreStringsWithoutSpecifiers &&
9160 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9161 CheckFormatHandler::EmitFormatDiagnostic(
9162 S, inFunctionCall, Args[format_idx],
9163 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9164 FExpr->getBeginLoc(),
9170 if (StrLen == 0 && numDataArgs > 0) {
9171 CheckFormatHandler::EmitFormatDiagnostic(
9172 S, inFunctionCall, Args[format_idx],
9173 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9184 if (ReferenceFormatString ==
nullptr) {
9185 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9186 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9187 inFunctionCall, CallType, CheckedVarArgs,
9197 Type, ReferenceFormatString, FExpr->getFormatString(),
9198 inFunctionCall ?
nullptr : Args[format_idx]);
9201 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9202 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9203 CallType, CheckedVarArgs, UncoveredArg);
9223 FormatStringLiteral RefLit = AuthoritativeFormatString;
9224 FormatStringLiteral TestLit = TestedFormatString;
9226 bool DiagAtStringLiteral;
9227 if (FunctionCallArg) {
9228 Arg = FunctionCallArg;
9229 DiagAtStringLiteral =
false;
9231 Arg = TestedFormatString;
9232 DiagAtStringLiteral =
true;
9234 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9235 AuthoritativeFormatString,
Type,
9236 IsObjC,
true, RefArgs) &&
9237 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9238 DiagAtStringLiteral, FmtArgs)) {
9240 TestedFormatString, FmtArgs, Arg,
9241 DiagAtStringLiteral);
9254 FormatStringLiteral RefLit = Str;
9258 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9267 bool HadError =
false;
9268 auto Iter = Args.begin();
9269 auto End = Args.end();
9270 while (Iter != End) {
9271 const auto &FirstInGroup = *Iter;
9273 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9275 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9284 const char *Str = StrRef.data();
9287 assert(
T &&
"String literal not of constant array type!");
9288 size_t TypeSize =
T->getZExtSize();
9289 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9300 switch (AbsFunction) {
9304 case Builtin::BI__builtin_abs:
9305 return Builtin::BI__builtin_labs;
9306 case Builtin::BI__builtin_labs:
9307 return Builtin::BI__builtin_llabs;
9308 case Builtin::BI__builtin_llabs:
9311 case Builtin::BI__builtin_fabsf:
9312 return Builtin::BI__builtin_fabs;
9313 case Builtin::BI__builtin_fabs:
9314 return Builtin::BI__builtin_fabsl;
9315 case Builtin::BI__builtin_fabsl:
9318 case Builtin::BI__builtin_cabsf:
9319 return Builtin::BI__builtin_cabs;
9320 case Builtin::BI__builtin_cabs:
9321 return Builtin::BI__builtin_cabsl;
9322 case Builtin::BI__builtin_cabsl:
9325 case Builtin::BIabs:
9326 return Builtin::BIlabs;
9327 case Builtin::BIlabs:
9328 return Builtin::BIllabs;
9329 case Builtin::BIllabs:
9332 case Builtin::BIfabsf:
9333 return Builtin::BIfabs;
9334 case Builtin::BIfabs:
9335 return Builtin::BIfabsl;
9336 case Builtin::BIfabsl:
9339 case Builtin::BIcabsf:
9340 return Builtin::BIcabs;
9341 case Builtin::BIcabs:
9342 return Builtin::BIcabsl;
9343 case Builtin::BIcabsl:
9372 unsigned AbsFunctionKind) {
9373 unsigned BestKind = 0;
9374 uint64_t ArgSize = Context.getTypeSize(ArgType);
9375 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9378 if (Context.getTypeSize(ParamType) >= ArgSize) {
9381 else if (Context.hasSameType(ParamType, ArgType)) {
9397 if (
T->isIntegralOrEnumerationType())
9399 if (
T->isRealFloatingType())
9401 if (
T->isAnyComplexType())
9404 llvm_unreachable(
"Type not integer, floating, or complex");
9411 switch (ValueKind) {
9416 case Builtin::BI__builtin_fabsf:
9417 case Builtin::BI__builtin_fabs:
9418 case Builtin::BI__builtin_fabsl:
9419 case Builtin::BI__builtin_cabsf:
9420 case Builtin::BI__builtin_cabs:
9421 case Builtin::BI__builtin_cabsl:
9422 return Builtin::BI__builtin_abs;
9423 case Builtin::BIfabsf:
9424 case Builtin::BIfabs:
9425 case Builtin::BIfabsl:
9426 case Builtin::BIcabsf:
9427 case Builtin::BIcabs:
9428 case Builtin::BIcabsl:
9429 return Builtin::BIabs;
9435 case Builtin::BI__builtin_abs:
9436 case Builtin::BI__builtin_labs:
9437 case Builtin::BI__builtin_llabs:
9438 case Builtin::BI__builtin_cabsf:
9439 case Builtin::BI__builtin_cabs:
9440 case Builtin::BI__builtin_cabsl:
9441 return Builtin::BI__builtin_fabsf;
9442 case Builtin::BIabs:
9443 case Builtin::BIlabs:
9444 case Builtin::BIllabs:
9445 case Builtin::BIcabsf:
9446 case Builtin::BIcabs:
9447 case Builtin::BIcabsl:
9448 return Builtin::BIfabsf;
9454 case Builtin::BI__builtin_abs:
9455 case Builtin::BI__builtin_labs:
9456 case Builtin::BI__builtin_llabs:
9457 case Builtin::BI__builtin_fabsf:
9458 case Builtin::BI__builtin_fabs:
9459 case Builtin::BI__builtin_fabsl:
9460 return Builtin::BI__builtin_cabsf;
9461 case Builtin::BIabs:
9462 case Builtin::BIlabs:
9463 case Builtin::BIllabs:
9464 case Builtin::BIfabsf:
9465 case Builtin::BIfabs:
9466 case Builtin::BIfabsl:
9467 return Builtin::BIcabsf;
9470 llvm_unreachable(
"Unable to convert function");
9481 case Builtin::BI__builtin_abs:
9482 case Builtin::BI__builtin_fabs:
9483 case Builtin::BI__builtin_fabsf:
9484 case Builtin::BI__builtin_fabsl:
9485 case Builtin::BI__builtin_labs:
9486 case Builtin::BI__builtin_llabs:
9487 case Builtin::BI__builtin_cabs:
9488 case Builtin::BI__builtin_cabsf:
9489 case Builtin::BI__builtin_cabsl:
9490 case Builtin::BIabs:
9491 case Builtin::BIlabs:
9492 case Builtin::BIllabs:
9493 case Builtin::BIfabs:
9494 case Builtin::BIfabsf:
9495 case Builtin::BIfabsl:
9496 case Builtin::BIcabs:
9497 case Builtin::BIcabsf:
9498 case Builtin::BIcabsl:
9501 llvm_unreachable(
"Unknown Builtin type");
9507 unsigned AbsKind,
QualType ArgType) {
9508 bool EmitHeaderHint =
true;
9509 const char *HeaderName =
nullptr;
9510 std::string FunctionName;
9511 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9512 FunctionName =
"std::abs";
9513 if (ArgType->isIntegralOrEnumerationType()) {
9514 HeaderName =
"cstdlib";
9515 }
else if (ArgType->isRealFloatingType()) {
9516 HeaderName =
"cmath";
9518 llvm_unreachable(
"Invalid Type");
9527 for (
const auto *I : R) {
9530 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9532 FDecl = dyn_cast<FunctionDecl>(I);
9547 EmitHeaderHint =
false;
9565 EmitHeaderHint =
false;
9569 }
else if (!R.
empty()) {
9575 S.
Diag(Loc, diag::note_replace_abs_function)
9581 if (!EmitHeaderHint)
9584 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9588template <std::
size_t StrLen>
9590 const char (&Str)[StrLen]) {
9603 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9604 return llvm::is_contained(names, calleeName);
9609 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9610 "__builtin_nanf16",
"__builtin_nanf128"});
9612 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9613 "__builtin_inff16",
"__builtin_inff128"});
9615 llvm_unreachable(
"unknown MathCheck");
9619 if (FDecl->
getName() !=
"infinity")
9622 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9624 if (RDecl->
getName() !=
"numeric_limits")
9641 if (FPO.getNoHonorNaNs() &&
9644 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9645 << 1 << 0 <<
Call->getSourceRange();
9649 if (FPO.getNoHonorInfs() &&
9653 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9654 << 0 << 0 <<
Call->getSourceRange();
9658void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9660 if (
Call->getNumArgs() != 1)
9665 if (AbsKind == 0 && !IsStdAbs)
9668 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9669 QualType ParamType =
Call->getArg(0)->getType();
9674 std::string FunctionName =
9675 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9676 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9677 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9706 if (ArgValueKind == ParamValueKind) {
9707 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9711 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9712 << FDecl << ArgType << ParamType;
9714 if (NewAbsKind == 0)
9718 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9727 if (NewAbsKind == 0)
9730 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9731 << FDecl << ParamValueKind << ArgValueKind;
9734 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9740 if (!
Call || !FDecl)
return;
9744 if (
Call->getExprLoc().isMacroID())
return;
9747 if (
Call->getNumArgs() != 2)
return;
9750 if (!ArgList)
return;
9751 if (ArgList->size() != 1)
return;
9754 const auto& TA = ArgList->
get(0);
9756 QualType ArgType = TA.getAsType();
9760 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
9761 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
9762 if (!MTE)
return false;
9763 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9764 if (!
Num)
return false;
9765 if (
Num->getValue() != 0)
return false;
9769 const Expr *FirstArg =
Call->getArg(0);
9770 const Expr *SecondArg =
Call->getArg(1);
9771 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9772 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9775 if (IsFirstArgZero == IsSecondArgZero)
return;
9780 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9782 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9783 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9786 SourceRange RemovalRange;
9787 if (IsFirstArgZero) {
9788 RemovalRange = SourceRange(FirstRange.
getBegin(),
9795 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9810 const auto *Size = dyn_cast<BinaryOperator>(E);
9815 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9819 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9820 << SizeRange << FnName;
9821 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9826 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9837 bool &IsContained) {
9839 const Type *Ty =
T->getBaseElementTypeUnsafe();
9840 IsContained =
false;
9853 for (
auto *FD : RD->
fields()) {
9866 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
9867 if (Unary->getKind() == UETT_SizeOf)
9876 if (!
SizeOf->isArgumentType())
9877 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9884 return SizeOf->getTypeOfArgument();
9890struct SearchNonTrivialToInitializeField
9893 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
9895 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
9898 SourceLocation SL) {
9899 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9900 asDerived().visitArray(PDIK, AT, SL);
9904 Super::visitWithKind(PDIK, FT, SL);
9907 void visitARCStrong(QualType FT, SourceLocation SL) {
9910 void visitARCWeak(QualType FT, SourceLocation SL) {
9913 void visitStruct(QualType FT, SourceLocation SL) {
9918 const ArrayType *AT, SourceLocation SL) {
9919 visit(getContext().getBaseElementType(AT), SL);
9921 void visitTrivial(QualType FT, SourceLocation SL) {}
9923 static void diag(QualType RT,
const Expr *E, Sema &S) {
9924 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
9933struct SearchNonTrivialToCopyField
9935 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
9937 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
9940 SourceLocation SL) {
9941 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9942 asDerived().visitArray(PCK, AT, SL);
9946 Super::visitWithKind(PCK, FT, SL);
9949 void visitARCStrong(QualType FT, SourceLocation SL) {
9952 void visitARCWeak(QualType FT, SourceLocation SL) {
9955 void visitPtrAuth(QualType FT, SourceLocation SL) {
9958 void visitStruct(QualType FT, SourceLocation SL) {
9963 SourceLocation SL) {
9964 visit(getContext().getBaseElementType(AT), SL);
9967 SourceLocation SL) {}
9968 void visitTrivial(QualType FT, SourceLocation SL) {}
9969 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
9971 static void diag(QualType RT,
const Expr *E, Sema &S) {
9972 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
9987 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
9988 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10012 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10014 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10015 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10021 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10024 const Expr *SizeArg =
10025 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10027 auto isLiteralZero = [](
const Expr *E) {
10037 if (isLiteralZero(SizeArg) &&
10044 if (BId == Builtin::BIbzero ||
10047 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10048 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10049 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10050 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10051 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10059 if (BId == Builtin::BImemset &&
10063 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10064 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10069void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10076 unsigned ExpectedNumArgs =
10077 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10078 if (
Call->getNumArgs() < ExpectedNumArgs)
10081 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10082 BId == Builtin::BIstrndup ? 1 : 2);
10084 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10085 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10088 Call->getBeginLoc(),
Call->getRParenLoc()))
10097 llvm::FoldingSetNodeID SizeOfArgID;
10102 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10103 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10106 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10107 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10108 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10110 QualType DestTy = Dest->
getType();
10111 QualType PointeeTy;
10112 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10125 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10129 if (SizeOfArgID == llvm::FoldingSetNodeID())
10131 llvm::FoldingSetNodeID DestID;
10133 if (DestID == SizeOfArgID) {
10136 unsigned ActionIdx = 0;
10137 StringRef ReadableName = FnName->
getName();
10139 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10140 if (UnaryOp->getOpcode() == UO_AddrOf)
10149 SourceLocation SL = SizeOfArg->
getExprLoc();
10154 if (
SM.isMacroArgExpansion(SL)) {
10156 SL =
SM.getSpellingLoc(SL);
10157 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10159 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10164 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10171 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10182 if (SizeOfArgTy != QualType()) {
10184 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10186 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10187 << FnName << SizeOfArgTy << ArgIdx
10194 PointeeTy = DestTy;
10197 if (PointeeTy == QualType())
10202 if (
const CXXRecordDecl *ContainedRD =
10205 unsigned OperationType = 0;
10206 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10209 if (ArgIdx != 0 || IsCmp) {
10210 if (BId == Builtin::BImemcpy)
10212 else if(BId == Builtin::BImemmove)
10219 PDiag(diag::warn_dyn_class_memaccess)
10220 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10221 << IsContained << ContainedRD << OperationType
10222 <<
Call->getCallee()->getSourceRange());
10224 BId != Builtin::BImemset)
10227 PDiag(diag::warn_arc_object_memaccess)
10228 << ArgIdx << FnName << PointeeTy
10229 <<
Call->getCallee()->getSourceRange());
10236 bool NonTriviallyCopyableCXXRecord =
10240 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10243 PDiag(diag::warn_cstruct_memaccess)
10244 << ArgIdx << FnName << PointeeTy << 0);
10245 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10246 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10247 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10251 PDiag(diag::warn_cxxstruct_memaccess)
10252 << FnName << PointeeTy);
10253 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10256 PDiag(diag::warn_cstruct_memaccess)
10257 << ArgIdx << FnName << PointeeTy << 1);
10258 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10259 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10260 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10264 PDiag(diag::warn_cxxstruct_memaccess)
10265 << FnName << PointeeTy);
10274 PDiag(diag::note_bad_memaccess_silence)
10310 if (CAT->getZExtSize() <= 1)
10318void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10322 unsigned NumArgs =
Call->getNumArgs();
10323 if ((NumArgs != 3) && (NumArgs != 4))
10328 const Expr *CompareWithSrc =
nullptr;
10331 Call->getBeginLoc(),
Call->getRParenLoc()))
10336 CompareWithSrc = Ex;
10339 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10340 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10341 SizeCall->getNumArgs() == 1)
10346 if (!CompareWithSrc)
10353 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10357 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10358 if (!CompareWithSrcDRE ||
10362 const Expr *OriginalSizeArg =
Call->getArg(2);
10363 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10370 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10374 SmallString<128> sizeString;
10375 llvm::raw_svector_ostream
OS(sizeString);
10380 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10387 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10388 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10389 return D1->getDecl() == D2->getDecl();
10394 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10403void Sema::CheckStrncatArguments(
const CallExpr *CE,
10418 unsigned PatternType = 0;
10426 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10427 if (BE->getOpcode() == BO_Sub) {
10428 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10429 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10440 if (PatternType == 0)
10449 if (
SM.isMacroArgExpansion(SL)) {
10450 SL =
SM.getSpellingLoc(SL);
10451 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10456 QualType DstTy = DstArg->
getType();
10459 if (!isKnownSizeArray) {
10460 if (PatternType == 1)
10461 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10463 Diag(SL, diag::warn_strncat_src_size) << SR;
10467 if (PatternType == 1)
10468 Diag(SL, diag::warn_strncat_large_size) << SR;
10470 Diag(SL, diag::warn_strncat_src_size) << SR;
10472 SmallString<128> sizeString;
10473 llvm::raw_svector_ostream
OS(sizeString);
10481 Diag(SL, diag::note_strncat_wrong_size)
10486void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10495void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10497 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10498 const Decl *D = Lvalue->getDecl();
10499 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10500 if (!DD->getType()->isReferenceType())
10501 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10505 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10506 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10507 Lvalue->getMemberDecl());
10510void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10512 const auto *Lambda = dyn_cast<LambdaExpr>(
10517 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10518 << CalleeName << 2 ;
10521void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10523 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10524 if (Var ==
nullptr)
10528 << CalleeName << 0 << Var;
10531void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10534 llvm::raw_svector_ostream
OS(SizeString);
10537 if (Kind == clang::CK_BitCast &&
10538 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10540 if (Kind == clang::CK_IntegralToPointer &&
10542 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10545 switch (
Cast->getCastKind()) {
10546 case clang::CK_BitCast:
10547 case clang::CK_IntegralToPointer:
10548 case clang::CK_FunctionToPointerDecay:
10557 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10558 << CalleeName << 0 <<
OS.str();
10562void Sema::CheckFreeArguments(
const CallExpr *E) {
10563 const std::string CalleeName =
10568 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10570 case UnaryOperator::Opcode::UO_AddrOf:
10571 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10572 case UnaryOperator::Opcode::UO_Plus:
10573 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10578 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10580 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10582 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10583 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10584 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10590 << CalleeName << 1 ;
10595 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10596 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10600Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10609 Diag(ReturnLoc, diag::warn_null_ret)
10619 if (Op == OO_New || Op == OO_Array_New) {
10620 const FunctionProtoType *Proto
10624 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10630 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10635 if (
Context.getTargetInfo().getTriple().isPPC64())
10647 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10648 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10650 return FPLiteral && FPCast;
10653 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10659 llvm::APFloat TargetC = FPLiteral->
getValue();
10660 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10661 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10665 Diag(Loc, diag::warn_float_compare_literal)
10666 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10679 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10680 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10681 if (DRL->getDecl() == DRR->getDecl())
10689 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10690 if (FLL->isExact())
10692 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10693 if (FLR->isExact())
10697 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10698 CL &&
CL->getBuiltinCallee())
10701 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10702 CR && CR->getBuiltinCallee())
10706 Diag(Loc, diag::warn_floatingpoint_eq)
10727 IntRange(
unsigned Width,
bool NonNegative)
10728 : Width(Width), NonNegative(NonNegative) {}
10731 unsigned valueBits()
const {
10732 return NonNegative ? Width : Width - 1;
10736 static IntRange forBoolType() {
10737 return IntRange(1,
true);
10741 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
10742 return forValueOfCanonicalType(
C,
10747 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
10750 if (
const auto *VT = dyn_cast<VectorType>(
T))
10751 T = VT->getElementType().getTypePtr();
10752 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10753 T = CT->getElementType().getTypePtr();
10754 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10755 T = AT->getValueType().getTypePtr();
10757 if (!
C.getLangOpts().CPlusPlus) {
10760 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10765 if (
Enum->isFixed()) {
10766 return IntRange(
C.getIntWidth(QualType(
T, 0)),
10767 !
Enum->getIntegerType()->isSignedIntegerType());
10770 unsigned NumPositive =
Enum->getNumPositiveBits();
10771 unsigned NumNegative =
Enum->getNumNegativeBits();
10773 if (NumNegative == 0)
10774 return IntRange(NumPositive,
true);
10776 return IntRange(std::max(NumPositive + 1, NumNegative),
10780 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10781 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10794 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
10797 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10798 T = VT->getElementType().getTypePtr();
10799 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
10800 T = CT->getElementType().getTypePtr();
10801 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10802 T = AT->getValueType().getTypePtr();
10804 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10806 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10807 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10816 static IntRange join(IntRange L, IntRange R) {
10817 bool Unsigned = L.NonNegative && R.NonNegative;
10818 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10819 L.NonNegative && R.NonNegative);
10823 static IntRange bit_and(IntRange L, IntRange R) {
10824 unsigned Bits = std::max(L.Width, R.Width);
10825 bool NonNegative =
false;
10826 if (L.NonNegative) {
10827 Bits = std::min(Bits, L.Width);
10828 NonNegative =
true;
10830 if (R.NonNegative) {
10831 Bits = std::min(Bits, R.Width);
10832 NonNegative =
true;
10834 return IntRange(Bits, NonNegative);
10838 static IntRange sum(IntRange L, IntRange R) {
10839 bool Unsigned = L.NonNegative && R.NonNegative;
10840 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10845 static IntRange difference(IntRange L, IntRange R) {
10849 bool CanWiden = !L.NonNegative || !R.NonNegative;
10850 bool Unsigned = L.NonNegative && R.Width == 0;
10851 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10857 static IntRange product(IntRange L, IntRange R) {
10861 bool CanWiden = !L.NonNegative && !R.NonNegative;
10862 bool Unsigned = L.NonNegative && R.NonNegative;
10863 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10868 static IntRange rem(IntRange L, IntRange R) {
10872 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10880 if (value.isSigned() && value.isNegative())
10881 return IntRange(value.getSignificantBits(),
false);
10883 if (value.getBitWidth() > MaxWidth)
10884 value = value.trunc(MaxWidth);
10888 return IntRange(value.getActiveBits(),
true);
10892 if (result.
isInt())
10899 R = IntRange::join(R, El);
10907 return IntRange::join(R, I);
10922 Ty = AtomicRHS->getValueType();
10941 bool InConstantContext,
10942 bool Approximate) {
10953 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
10954 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
10958 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
10960 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
10961 CE->getCastKind() == CK_BooleanToSignedIntegral;
10964 if (!isIntegerCast)
10965 return OutputTypeRange;
10968 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
10969 InConstantContext, Approximate);
10971 return std::nullopt;
10974 if (SubRange->Width >= OutputTypeRange.Width)
10975 return OutputTypeRange;
10979 return IntRange(SubRange->Width,
10980 SubRange->NonNegative || OutputTypeRange.NonNegative);
10983 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
10986 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
10988 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
10989 InConstantContext, Approximate);
10994 Expr *TrueExpr = CO->getTrueExpr();
10996 return std::nullopt;
10998 std::optional<IntRange> L =
11001 return std::nullopt;
11003 Expr *FalseExpr = CO->getFalseExpr();
11005 return std::nullopt;
11007 std::optional<IntRange> R =
11010 return std::nullopt;
11012 return IntRange::join(*L, *R);
11015 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11016 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11018 switch (BO->getOpcode()) {
11020 llvm_unreachable(
"builtin <=> should have class type");
11031 return IntRange::forBoolType();
11060 Combine = IntRange::bit_and;
11068 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11069 if (I->getValue() == 1) {
11070 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11071 return IntRange(R.Width,
true);
11081 case BO_ShrAssign: {
11083 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11085 return std::nullopt;
11089 if (std::optional<llvm::APSInt> shift =
11090 BO->getRHS()->getIntegerConstantExpr(
C)) {
11091 if (shift->isNonNegative()) {
11092 if (shift->uge(L->Width))
11093 L->Width = (L->NonNegative ? 0 : 1);
11095 L->Width -= shift->getZExtValue();
11109 Combine = IntRange::sum;
11113 if (BO->getLHS()->getType()->isPointerType())
11116 Combine = IntRange::difference;
11121 Combine = IntRange::product;
11130 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11132 return std::nullopt;
11135 if (std::optional<llvm::APSInt> divisor =
11136 BO->getRHS()->getIntegerConstantExpr(
C)) {
11137 unsigned log2 = divisor->logBase2();
11138 if (
log2 >= L->Width)
11139 L->Width = (L->NonNegative ? 0 : 1);
11141 L->Width = std::min(L->Width -
log2, MaxWidth);
11149 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11151 return std::nullopt;
11153 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11157 Combine = IntRange::rem;
11169 unsigned opWidth =
C.getIntWidth(
T);
11171 InConstantContext, Approximate);
11173 return std::nullopt;
11176 InConstantContext, Approximate);
11178 return std::nullopt;
11180 IntRange
C = Combine(*L, *R);
11181 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11182 C.Width = std::min(
C.Width, MaxWidth);
11186 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11187 switch (UO->getOpcode()) {
11190 return IntRange::forBoolType();
11204 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11207 return std::nullopt;
11212 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11222 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11225 return std::nullopt;
11230 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11240 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11241 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11245 return IntRange(BitField->getBitWidthValue(),
11246 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11249 return std::nullopt;
11255 bool InConstantContext,
11256 bool Approximate) {
11265 const llvm::fltSemantics &Src,
11266 const llvm::fltSemantics &Tgt) {
11267 llvm::APFloat truncated = value;
11270 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11271 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11273 return truncated.bitwiseIsEqual(value);
11282 const llvm::fltSemantics &Src,
11283 const llvm::fltSemantics &Tgt) {
11300 bool IsListInit =
false);
11315 return MacroName !=
"YES" && MacroName !=
"NO" &&
11316 MacroName !=
"true" && MacroName !=
"false";
11324 (!E->
getType()->isSignedIntegerType() ||
11339struct PromotedRange {
11341 llvm::APSInt PromotedMin;
11343 llvm::APSInt PromotedMax;
11345 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11347 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11348 else if (R.Width >= BitWidth && !
Unsigned) {
11352 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11353 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11355 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11356 .extOrTrunc(BitWidth);
11357 PromotedMin.setIsUnsigned(
Unsigned);
11359 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11360 .extOrTrunc(BitWidth);
11361 PromotedMax.setIsUnsigned(
Unsigned);
11366 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11376 InRangeFlag = 0x40,
11379 Min =
LE | InRangeFlag,
11380 InRange = InRangeFlag,
11381 Max =
GE | InRangeFlag,
11384 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11389 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11390 Value.isUnsigned() == PromotedMin.isUnsigned());
11391 if (!isContiguous()) {
11392 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11393 if (
Value.isMinValue())
return Min;
11394 if (
Value.isMaxValue())
return Max;
11395 if (
Value >= PromotedMin)
return InRange;
11396 if (
Value <= PromotedMax)
return InRange;
11400 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11401 case -1:
return Less;
11402 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11404 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11405 case -1:
return InRange;
11406 case 0:
return Max;
11411 llvm_unreachable(
"impossible compare result");
11414 static std::optional<StringRef>
11416 if (Op == BO_Cmp) {
11418 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11420 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11421 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11422 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11423 return std::nullopt;
11430 }
else if (Op == BO_NE) {
11434 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11441 if (Op == BO_GE || Op == BO_LE)
11442 std::swap(TrueFlag, FalseFlag);
11445 return StringRef(
"true");
11447 return StringRef(
"false");
11448 return std::nullopt;
11455 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11456 if (ICE->getCastKind() != CK_IntegralCast &&
11457 ICE->getCastKind() != CK_NoOp)
11459 E = ICE->getSubExpr();
11468 enum ConstantValueKind {
11473 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11474 return BL->getValue() ? ConstantValueKind::LiteralTrue
11475 : ConstantValueKind::LiteralFalse;
11476 return ConstantValueKind::Miscellaneous;
11481 const llvm::APSInt &
Value,
11482 bool RhsConstant) {
11504 if (!OtherValueRange)
11509 OtherT = AT->getValueType();
11510 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11514 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11520 bool OtherIsBooleanDespiteType =
11522 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11523 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11527 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11528 Value.isUnsigned());
11529 auto Cmp = OtherPromotedValueRange.compare(
Value);
11530 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11536 bool TautologicalTypeCompare =
false;
11538 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11539 Value.isUnsigned());
11540 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11543 TautologicalTypeCompare =
true;
11551 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11560 bool InRange = Cmp & PromotedRange::InRangeFlag;
11566 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11567 Other->getType()->isUnsignedIntegerOrEnumerationType())
11568 TautologicalTypeCompare =
true;
11573 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11574 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11578 llvm::raw_svector_ostream OS(PrettySourceValue);
11580 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11581 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11583 OS << (BL->getValue() ?
"YES" :
"NO");
11588 if (!TautologicalTypeCompare) {
11590 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11596 if (IsObjCSignedCharBool) {
11598 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11599 << OS.str() << *Result);
11606 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11610 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11611 : diag::warn_tautological_bool_compare)
11613 << OtherIsBooleanDespiteType << *Result
11620 ? diag::warn_unsigned_enum_always_true_comparison
11621 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11622 : diag::warn_unsigned_always_true_comparison)
11623 : diag::warn_tautological_constant_compare;
11626 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11659 if (
T->isIntegralType(S.
Context)) {
11660 std::optional<llvm::APSInt> RHSValue =
11662 std::optional<llvm::APSInt> LHSValue =
11666 if (RHSValue && LHSValue)
11670 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11672 const bool RhsConstant = (
bool)RHSValue;
11673 Expr *Const = RhsConstant ? RHS : LHS;
11675 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11684 if (!
T->hasUnsignedIntegerRepresentation()) {
11698 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11700 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11706 Expr *signedOperand, *unsignedOperand;
11709 "unsigned comparison between two signed integer expressions?");
11710 signedOperand = LHS;
11711 unsignedOperand = RHS;
11713 signedOperand = RHS;
11714 unsignedOperand = LHS;
11720 std::optional<IntRange> signedRange =
11732 if (signedRange->NonNegative)
11744 if (!unsignedRange)
11749 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11751 if (unsignedRange->Width < comparisonWidth)
11756 S.
PDiag(diag::warn_mixed_sign_comparison)
11775 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11780 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11781 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11782 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11783 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11784 << BitfieldEnumDecl;
11791 Init->isValueDependent() ||
11792 Init->isTypeDependent())
11795 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11805 const PreferredTypeAttr *PTAttr =
nullptr;
11807 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11809 ED = PTAttr->getType()->getAsEnumDecl();
11817 bool SignedEnum = ED->getNumNegativeBits() > 0;
11824 unsigned DiagID = 0;
11825 if (SignedEnum && !SignedBitfield) {
11828 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11830 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11831 }
else if (SignedBitfield && !SignedEnum &&
11832 ED->getNumPositiveBits() == FieldWidth) {
11835 ? diag::warn_signed_bitfield_enum_conversion
11836 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11839 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11844 << SignedEnum << TypeRange;
11846 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11853 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11854 ED->getNumNegativeBits())
11855 : ED->getNumPositiveBits();
11858 if (BitsNeeded > FieldWidth) {
11862 ? diag::warn_bitfield_too_small_for_enum
11863 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11864 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11868 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11876 llvm::APSInt
Value = Result.Val.getInt();
11878 unsigned OriginalWidth =
Value.getBitWidth();
11884 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11885 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11892 if (!
Value.isSigned() ||
Value.isNegative())
11893 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11894 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11895 OriginalWidth =
Value.getSignificantBits();
11897 if (OriginalWidth <= FieldWidth)
11901 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11905 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11906 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11910 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11912 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11913 ? diag::warn_impcast_single_bit_bitield_precision_constant
11914 : diag::warn_impcast_bitfield_precision_constant)
11915 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11916 <<
Init->getSourceRange();
11948 bool PruneControlFlow =
false) {
11955 if (
T.hasAddressSpace())
11957 if (PruneControlFlow) {
11971 bool PruneControlFlow =
false) {
11978 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
11983 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
11984 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
11989 llvm::APFloat
Value(0.0);
11995 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12000 diag::warn_impcast_float_integer, PruneWarnings);
12003 bool isExact =
false;
12006 T->hasUnsignedIntegerRepresentation());
12007 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12008 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12016 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12017 precision = (precision * 59 + 195) / 196;
12018 Value.toString(PrettySourceValue, precision);
12022 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12023 << PrettySourceValue);
12026 if (Result == llvm::APFloat::opOK && isExact) {
12027 if (IsLiteral)
return;
12028 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12034 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12037 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12038 : diag::warn_impcast_float_to_integer_out_of_range,
12041 unsigned DiagID = 0;
12044 DiagID = diag::warn_impcast_literal_float_to_integer;
12045 }
else if (IntegerValue == 0) {
12046 if (
Value.isZero()) {
12048 diag::warn_impcast_float_integer, PruneWarnings);
12051 DiagID = diag::warn_impcast_float_to_integer_zero;
12053 if (IntegerValue.isUnsigned()) {
12054 if (!IntegerValue.isMaxValue()) {
12056 diag::warn_impcast_float_integer, PruneWarnings);
12059 if (!IntegerValue.isMaxSignedValue() &&
12060 !IntegerValue.isMinSignedValue()) {
12062 diag::warn_impcast_float_integer, PruneWarnings);
12066 DiagID = diag::warn_impcast_float_to_integer;
12071 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12073 IntegerValue.toString(PrettyTargetValue);
12075 if (PruneWarnings) {
12078 << E->
getType() <<
T.getUnqualifiedType()
12079 << PrettySourceValue << PrettyTargetValue
12083 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12092 "Must be compound assignment operation");
12103 ->getComputationResultType()
12110 if (ResultBT->isInteger())
12112 E->
getExprLoc(), diag::warn_impcast_float_integer);
12114 if (!ResultBT->isFloatingPoint())
12123 diag::warn_impcast_float_result_precision);
12128 if (!Range.Width)
return "0";
12130 llvm::APSInt ValueInRange =
Value;
12131 ValueInRange.setIsSigned(!Range.NonNegative);
12132 ValueInRange = ValueInRange.trunc(Range.Width);
12133 return toString(ValueInRange, 10);
12143 const Type *Source =
12145 if (
Target->isDependentType())
12148 const auto *FloatCandidateBT =
12149 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12150 const Type *BoolCandidateType = ToBool ?
Target : Source;
12153 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12158 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12164 S, TheCall->
getArg(I - 1),
false));
12166 S, TheCall->
getArg(I + 1),
false));
12171 diag::warn_impcast_floating_point_to_bool);
12186 if (!IsGNUNullExpr && !HasNullPtrType)
12190 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12191 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12194 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12207 if (IsGNUNullExpr && Loc.
isMacroID()) {
12210 if (MacroName ==
"NULL")
12218 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12232 const char FirstLiteralCharacter =
12234 if (FirstLiteralCharacter ==
'0')
12240 if (CC.
isValid() &&
T->isCharType()) {
12241 const char FirstContextCharacter =
12243 if (FirstContextCharacter ==
'{')
12251 const auto *IL = dyn_cast<IntegerLiteral>(E);
12253 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12254 if (UO->getOpcode() == UO_Minus)
12255 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12266 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12270 if (Opc == BO_Shl) {
12273 if (LHS && LHS->getValue() == 0)
12274 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12276 RHS->getValue().isNonNegative() &&
12278 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12279 << (Result.Val.getInt() != 0);
12281 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12288 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12293 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12294 (RHS->getValue() == 0 || RHS->getValue() == 1))
12297 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12298 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12306 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12311 llvm::APSInt
Value(32);
12312 Value = Result.Val.getInt();
12313 bool IsASCII =
Value <= 0x7F;
12314 bool IsBMP =
Value <= 0xD7FF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12315 bool ConversionPreservesSemantics =
12316 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12318 if (!ConversionPreservesSemantics) {
12319 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12320 const llvm::APSInt &
Value) {
12321 if (
T->isChar8Type())
12322 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12323 if (
T->isChar16Type())
12324 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12325 assert(
T->isChar32Type());
12326 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12329 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12338 LosesPrecision ? diag::warn_impcast_unicode_precision
12339 : diag::warn_impcast_unicode_char_type);
12353 From = MaybePointee;
12360 if (FromFn->getCFIUncheckedCalleeAttr() &&
12361 !ToFn->getCFIUncheckedCalleeAttr())
12363 if (!FromFn->getCFIUncheckedCalleeAttr() &&
12364 ToFn->getCFIUncheckedCalleeAttr())
12372 From =
Context.getCanonicalType(From);
12373 To =
Context.getCanonicalType(To);
12374 return ::AdjustingCFIUncheckedCallee(From, To) ==
Discarding;
12378 From =
Context.getCanonicalType(From);
12379 To =
Context.getCanonicalType(To);
12380 return ::AdjustingCFIUncheckedCallee(From, To) ==
Adding;
12384 bool *ICContext,
bool IsListInit) {
12389 if (Source ==
Target)
return;
12390 if (
Target->isDependentType())
return;
12400 if (Source->isAtomicType())
12404 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12410 diag::warn_impcast_string_literal_to_bool);
12416 diag::warn_impcast_objective_c_literal_to_bool);
12418 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12428 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12431 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12433 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12442 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12444 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12449 if (
Target->isSveVLSBuiltinType() &&
12456 if (
Target->isRVVVLSBuiltinType() &&
12466 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12473 diag::warn_hlsl_impcast_vector_truncation);
12485 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12486 Target = VecTy->getElementType().getTypePtr();
12496 ? diag::err_impcast_complex_scalar
12497 : diag::warn_impcast_complex_scalar);
12504 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12510 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12513 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12515 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12557 else if (Order < 0) {
12567 if (TargetBT && TargetBT->
isInteger()) {
12594 diag::warn_impcast_floating_point_to_bool);
12602 if (Source->isFixedPointType()) {
12603 if (
Target->isUnsaturatedFixedPointType()) {
12607 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12608 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12609 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12612 PDiag(diag::warn_impcast_fixed_point_range)
12613 <<
Value.toString() <<
T
12619 }
else if (
Target->isIntegerType()) {
12623 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12626 llvm::APSInt IntResult = FXResult.convertToInt(
12627 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12632 PDiag(diag::warn_impcast_fixed_point_range)
12633 << FXResult.toString() <<
T
12640 }
else if (
Target->isUnsaturatedFixedPointType()) {
12641 if (Source->isIntegerType()) {
12648 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12653 PDiag(diag::warn_impcast_fixed_point_range)
12674 unsigned int SourcePrecision =
SourceRange->Width;
12678 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12681 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12682 SourcePrecision > TargetPrecision) {
12684 if (std::optional<llvm::APSInt> SourceInt =
12689 llvm::APFloat TargetFloatValue(
12691 llvm::APFloat::opStatus ConversionStatus =
12692 TargetFloatValue.convertFromAPInt(
12694 llvm::APFloat::rmNearestTiesToEven);
12696 if (ConversionStatus != llvm::APFloat::opOK) {
12698 SourceInt->toString(PrettySourceValue, 10);
12700 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12704 PDiag(diag::warn_impcast_integer_float_precision_constant)
12705 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12711 diag::warn_impcast_integer_float_precision);
12720 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12725 if (
Target->isBooleanType())
12729 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12733 if (!Source->isIntegerType() || !
Target->isIntegerType())
12738 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12741 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
12744 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12749 if (!LikelySourceRange)
12752 IntRange SourceTypeRange =
12753 IntRange::forTargetOfCanonicalType(
Context, Source);
12754 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12756 if (LikelySourceRange->Width > TargetRange.Width) {
12762 llvm::APSInt
Value(32);
12772 PDiag(diag::warn_impcast_integer_precision_constant)
12773 << PrettySourceValue << PrettyTargetValue
12783 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12784 if (UO->getOpcode() == UO_Minus)
12786 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12789 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
12793 diag::warn_impcast_integer_precision);
12796 if (TargetRange.Width > SourceTypeRange.Width) {
12797 if (
auto *UO = dyn_cast<UnaryOperator>(E))
12798 if (UO->getOpcode() == UO_Minus)
12799 if (Source->isUnsignedIntegerType()) {
12800 if (
Target->isUnsignedIntegerType())
12802 diag::warn_impcast_high_order_zero_bits);
12803 if (
Target->isSignedIntegerType())
12805 diag::warn_impcast_nonnegative_result);
12809 if (TargetRange.Width == LikelySourceRange->Width &&
12810 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12811 Source->isSignedIntegerType()) {
12825 PDiag(diag::warn_impcast_integer_precision_constant)
12826 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12836 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12837 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12838 LikelySourceRange->Width == TargetRange.Width))) {
12842 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12844 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
12848 unsigned DiagID = diag::warn_impcast_integer_sign;
12856 DiagID = diag::warn_impcast_integer_sign_conditional;
12873 Source =
Context.getCanonicalType(SourceType).getTypePtr();
12875 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
12876 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
12877 if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
12878 TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
12879 SourceEnum != TargetEnum) {
12884 diag::warn_impcast_different_enum_types);
12898 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
12911 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
12912 TrueExpr = BCO->getCommon();
12914 bool Suspicious =
false;
12918 if (
T->isBooleanType())
12923 if (!Suspicious)
return;
12926 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12933 Suspicious =
false;
12938 E->
getType(), CC, &Suspicious);
12955struct AnalyzeImplicitConversionsWorkItem {
12964 bool ExtraCheckForImplicitConversion,
12967 WorkList.push_back({E, CC,
false});
12969 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
12976 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
12978 Expr *OrigE = Item.E;
12997 Expr *SourceExpr = E;
13002 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13003 if (
auto *Src = OVE->getSourceExpr())
13006 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13007 if (UO->getOpcode() == UO_Not &&
13008 UO->getSubExpr()->isKnownToHaveBooleanValue())
13009 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13013 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13014 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13015 BO->getLHS()->isKnownToHaveBooleanValue() &&
13016 BO->getRHS()->isKnownToHaveBooleanValue() &&
13017 BO->getLHS()->HasSideEffects(S.
Context) &&
13018 BO->getRHS()->HasSideEffects(S.
Context)) {
13029 if (SR.str() ==
"&" || SR.str() ==
"|") {
13031 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13032 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13035 BO->getOperatorLoc(),
13036 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13037 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13039 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13057 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13063 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13078 for (
auto *SE : POE->semantics())
13079 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13080 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13084 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13085 E = CE->getSubExpr();
13091 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13092 if (InitListE->getNumInits() == 1) {
13093 E = InitListE->getInit(0);
13100 WorkList.push_back({E, CC, IsListInit});
13104 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13105 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13109 if (OutArgE->isInOut())
13110 WorkList.push_back(
13111 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13112 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13118 if (BO->isComparisonOp())
13122 if (BO->getOpcode() == BO_Assign)
13125 if (BO->isAssignmentOp())
13141 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13143 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13147 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13148 if (ChildExpr == CSE->getOperand())
13154 if (IsLogicalAndOperator &&
13159 WorkList.push_back({ChildExpr, CC, IsListInit});
13173 if (
U->getOpcode() == UO_LNot) {
13175 }
else if (
U->getOpcode() != UO_AddrOf) {
13176 if (
U->getSubExpr()->getType()->isAtomicType())
13177 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13178 diag::warn_atomic_implicit_seq_cst);
13189 WorkList.push_back({OrigE, CC, IsListInit});
13190 while (!WorkList.empty())
13202 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13205 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13206 if (!M->getMemberDecl()->getType()->isReferenceType())
13208 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13209 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13211 FD =
Call->getDirectCallee();
13220 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13234 if (
SM.isMacroBodyExpansion(Loc))
13236 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13260 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13261 : diag::warn_this_bool_conversion;
13266 bool IsAddressOf =
false;
13268 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13269 if (UO->getOpcode() != UO_AddrOf)
13271 IsAddressOf =
true;
13272 E = UO->getSubExpr();
13276 unsigned DiagID = IsCompare
13277 ? diag::warn_address_of_reference_null_compare
13278 : diag::warn_address_of_reference_bool_conversion;
13286 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13289 llvm::raw_string_ostream S(Str);
13291 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13292 : diag::warn_cast_nonnull_to_bool;
13295 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13300 if (
auto *Callee =
Call->getDirectCallee()) {
13301 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13302 ComplainAboutNonnullParamOrCall(A);
13311 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13312 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13313 MRecordDecl && MRecordDecl->isLambda()) {
13316 << MRecordDecl->getSourceRange() << Range << IsEqual;
13326 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13327 D = M->getMemberDecl();
13335 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13338 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13339 ComplainAboutNonnullParamOrCall(A);
13343 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13347 auto ParamIter = llvm::find(FD->
parameters(), PV);
13349 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13353 ComplainAboutNonnullParamOrCall(
NonNull);
13358 if (ArgNo.getASTIndex() == ParamNo) {
13359 ComplainAboutNonnullParamOrCall(
NonNull);
13369 const bool IsArray =
T->isArrayType();
13370 const bool IsFunction =
T->isFunctionType();
13373 if (IsAddressOf && IsFunction) {
13378 if (!IsAddressOf && !IsFunction && !IsArray)
13383 llvm::raw_string_ostream S(Str);
13386 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13387 : diag::warn_impcast_pointer_to_bool;
13394 DiagType = AddressOf;
13395 else if (IsFunction)
13396 DiagType = FunctionPointer;
13398 DiagType = ArrayPointer;
13400 llvm_unreachable(
"Could not determine diagnostic.");
13402 << Range << IsEqual;
13415 if (ReturnType.
isNull())
13453 CheckArrayAccess(E);
13463void Sema::CheckForIntOverflow (
const Expr *E) {
13465 SmallVector<const Expr *, 2> Exprs(1, E);
13468 const Expr *OriginalE = Exprs.pop_back_val();
13476 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13477 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13480 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13481 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13482 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13484 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13485 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13486 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13487 Exprs.push_back(Temporary->getSubExpr());
13488 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13489 Exprs.push_back(Array->getIdx());
13490 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13491 Exprs.push_back(Compound->getInitializer());
13492 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13493 New &&
New->isArray()) {
13494 if (
auto ArraySize =
New->getArraySize())
13495 Exprs.push_back(*ArraySize);
13496 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13497 Exprs.push_back(MTE->getSubExpr());
13498 }
while (!Exprs.empty());
13506 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13513 class SequenceTree {
13515 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13516 unsigned Parent : 31;
13517 LLVM_PREFERRED_TYPE(
bool)
13518 unsigned Merged : 1;
13520 SmallVector<Value, 8> Values;
13526 friend class SequenceTree;
13530 explicit Seq(
unsigned N) : Index(N) {}
13533 Seq() : Index(0) {}
13536 SequenceTree() { Values.push_back(
Value(0)); }
13537 Seq root()
const {
return Seq(0); }
13542 Seq allocate(
Seq Parent) {
13543 Values.push_back(
Value(Parent.Index));
13544 return Seq(Values.size() - 1);
13548 void merge(
Seq S) {
13549 Values[S.Index].Merged =
true;
13555 bool isUnsequenced(
Seq Cur,
Seq Old) {
13556 unsigned C = representative(Cur.Index);
13557 unsigned Target = representative(Old.Index);
13561 C = Values[
C].Parent;
13568 unsigned representative(
unsigned K) {
13569 if (Values[K].Merged)
13571 return Values[K].Parent = representative(Values[K].Parent);
13577 using Object =
const NamedDecl *;
13591 UK_ModAsSideEffect,
13593 UK_Count = UK_ModAsSideEffect + 1
13599 const Expr *UsageExpr =
nullptr;
13600 SequenceTree::Seq
Seq;
13606 Usage Uses[UK_Count];
13609 bool Diagnosed =
false;
13613 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13621 UsageInfoMap UsageMap;
13624 SequenceTree::Seq Region;
13628 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13632 SmallVectorImpl<const Expr *> &WorkList;
13639 struct SequencedSubexpression {
13640 SequencedSubexpression(SequenceChecker &
Self)
13641 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13642 Self.ModAsSideEffect = &ModAsSideEffect;
13645 ~SequencedSubexpression() {
13646 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13650 UsageInfo &UI =
Self.UsageMap[M.first];
13651 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13652 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13653 SideEffectUsage = M.second;
13655 Self.ModAsSideEffect = OldModAsSideEffect;
13658 SequenceChecker &
Self;
13659 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13660 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13667 class EvaluationTracker {
13669 EvaluationTracker(SequenceChecker &
Self)
13671 Self.EvalTracker =
this;
13674 ~EvaluationTracker() {
13675 Self.EvalTracker = Prev;
13677 Prev->EvalOK &= EvalOK;
13680 bool evaluate(
const Expr *E,
bool &
Result) {
13685 Self.SemaRef.isConstantEvaluatedContext());
13690 SequenceChecker &
Self;
13691 EvaluationTracker *Prev;
13692 bool EvalOK =
true;
13693 } *EvalTracker =
nullptr;
13697 Object getObject(
const Expr *E,
bool Mod)
const {
13699 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13700 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13701 return getObject(UO->getSubExpr(), Mod);
13702 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13703 if (BO->getOpcode() == BO_Comma)
13704 return getObject(BO->getRHS(), Mod);
13705 if (Mod && BO->isAssignmentOp())
13706 return getObject(BO->getLHS(), Mod);
13707 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13710 return ME->getMemberDecl();
13711 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13720 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13722 Usage &U = UI.Uses[UK];
13723 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
13727 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13728 ModAsSideEffect->push_back(std::make_pair(O, U));
13730 U.UsageExpr = UsageExpr;
13740 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13741 UsageKind OtherKind,
bool IsModMod) {
13745 const Usage &U = UI.Uses[OtherKind];
13746 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
13749 const Expr *Mod = U.UsageExpr;
13750 const Expr *ModOrUse = UsageExpr;
13751 if (OtherKind == UK_Use)
13752 std::swap(Mod, ModOrUse);
13756 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13757 : diag::warn_unsequenced_mod_use)
13758 << O << SourceRange(ModOrUse->
getExprLoc()));
13759 UI.Diagnosed =
true;
13788 void notePreUse(Object O,
const Expr *UseExpr) {
13789 UsageInfo &UI = UsageMap[O];
13791 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13794 void notePostUse(Object O,
const Expr *UseExpr) {
13795 UsageInfo &UI = UsageMap[O];
13796 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13798 addUsage(O, UI, UseExpr, UK_Use);
13801 void notePreMod(Object O,
const Expr *ModExpr) {
13802 UsageInfo &UI = UsageMap[O];
13804 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13805 checkUsage(O, UI, ModExpr, UK_Use,
false);
13808 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13809 UsageInfo &UI = UsageMap[O];
13810 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13812 addUsage(O, UI, ModExpr, UK);
13816 SequenceChecker(Sema &S,
const Expr *E,
13817 SmallVectorImpl<const Expr *> &WorkList)
13818 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
13822 (void)this->WorkList;
13825 void VisitStmt(
const Stmt *S) {
13829 void VisitExpr(
const Expr *E) {
13831 Base::VisitStmt(E);
13834 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
13835 for (
auto *Sub : CSE->
children()) {
13836 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13851 void VisitCastExpr(
const CastExpr *E) {
13863 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13864 const Expr *SequencedAfter) {
13865 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
13866 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
13867 SequenceTree::Seq OldRegion = Region;
13870 SequencedSubexpression SeqBefore(*
this);
13871 Region = BeforeRegion;
13872 Visit(SequencedBefore);
13875 Region = AfterRegion;
13876 Visit(SequencedAfter);
13878 Region = OldRegion;
13880 Tree.merge(BeforeRegion);
13881 Tree.merge(AfterRegion);
13884 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
13889 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13896 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13897 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13898 void VisitBinPtrMem(
const BinaryOperator *BO) {
13903 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13910 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13911 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13912 void VisitBinShlShr(
const BinaryOperator *BO) {
13916 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13923 void VisitBinComma(
const BinaryOperator *BO) {
13928 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13931 void VisitBinAssign(
const BinaryOperator *BO) {
13932 SequenceTree::Seq RHSRegion;
13933 SequenceTree::Seq LHSRegion;
13935 RHSRegion = Tree.allocate(Region);
13936 LHSRegion = Tree.allocate(Region);
13938 RHSRegion = Region;
13939 LHSRegion = Region;
13941 SequenceTree::Seq OldRegion = Region;
13957 SequencedSubexpression SeqBefore(*
this);
13958 Region = RHSRegion;
13962 Region = LHSRegion;
13966 notePostUse(O, BO);
13970 Region = LHSRegion;
13974 notePostUse(O, BO);
13976 Region = RHSRegion;
13984 Region = OldRegion;
13988 : UK_ModAsSideEffect);
13990 Tree.merge(RHSRegion);
13991 Tree.merge(LHSRegion);
13995 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
13996 VisitBinAssign(CAO);
13999 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14000 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14001 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14004 return VisitExpr(UO);
14012 : UK_ModAsSideEffect);
14015 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14016 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14017 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14020 return VisitExpr(UO);
14024 notePostMod(O, UO, UK_ModAsSideEffect);
14027 void VisitBinLOr(
const BinaryOperator *BO) {
14033 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14034 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14035 SequenceTree::Seq OldRegion = Region;
14037 EvaluationTracker Eval(*
this);
14039 SequencedSubexpression Sequenced(*
this);
14040 Region = LHSRegion;
14047 bool EvalResult =
false;
14048 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14049 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14050 if (ShouldVisitRHS) {
14051 Region = RHSRegion;
14055 Region = OldRegion;
14056 Tree.merge(LHSRegion);
14057 Tree.merge(RHSRegion);
14060 void VisitBinLAnd(
const BinaryOperator *BO) {
14066 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14067 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14068 SequenceTree::Seq OldRegion = Region;
14070 EvaluationTracker Eval(*
this);
14072 SequencedSubexpression Sequenced(*
this);
14073 Region = LHSRegion;
14079 bool EvalResult =
false;
14080 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14081 bool ShouldVisitRHS = !EvalOK || EvalResult;
14082 if (ShouldVisitRHS) {
14083 Region = RHSRegion;
14087 Region = OldRegion;
14088 Tree.merge(LHSRegion);
14089 Tree.merge(RHSRegion);
14092 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14097 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14113 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14114 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14115 SequenceTree::Seq OldRegion = Region;
14117 EvaluationTracker Eval(*
this);
14119 SequencedSubexpression Sequenced(*
this);
14120 Region = ConditionRegion;
14130 bool EvalResult =
false;
14131 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14132 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14133 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14134 if (ShouldVisitTrueExpr) {
14135 Region = TrueRegion;
14138 if (ShouldVisitFalseExpr) {
14139 Region = FalseRegion;
14143 Region = OldRegion;
14144 Tree.merge(ConditionRegion);
14145 Tree.merge(TrueRegion);
14146 Tree.merge(FalseRegion);
14149 void VisitCallExpr(
const CallExpr *CE) {
14161 SequencedSubexpression Sequenced(*
this);
14166 SequenceTree::Seq CalleeRegion;
14167 SequenceTree::Seq OtherRegion;
14168 if (SemaRef.getLangOpts().CPlusPlus17) {
14169 CalleeRegion = Tree.allocate(Region);
14170 OtherRegion = Tree.allocate(Region);
14172 CalleeRegion = Region;
14173 OtherRegion = Region;
14175 SequenceTree::Seq OldRegion = Region;
14178 Region = CalleeRegion;
14180 SequencedSubexpression Sequenced(*this);
14181 Visit(CE->getCallee());
14183 Visit(CE->getCallee());
14187 Region = OtherRegion;
14191 Region = OldRegion;
14193 Tree.merge(CalleeRegion);
14194 Tree.merge(OtherRegion);
14212 return VisitCallExpr(CXXOCE);
14223 case OO_MinusEqual:
14225 case OO_SlashEqual:
14226 case OO_PercentEqual:
14227 case OO_CaretEqual:
14230 case OO_LessLessEqual:
14231 case OO_GreaterGreaterEqual:
14232 SequencingKind = RHSBeforeLHS;
14236 case OO_GreaterGreater:
14242 SequencingKind = LHSBeforeRHS;
14246 SequencingKind = LHSBeforeRest;
14250 SequencingKind = NoSequencing;
14254 if (SequencingKind == NoSequencing)
14255 return VisitCallExpr(CXXOCE);
14258 SequencedSubexpression Sequenced(*
this);
14261 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14262 "Should only get there with C++17 and above!");
14263 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14264 "Should only get there with an overloaded binary operator"
14265 " or an overloaded call operator!");
14267 if (SequencingKind == LHSBeforeRest) {
14268 assert(CXXOCE->getOperator() == OO_Call &&
14269 "We should only have an overloaded call operator here!");
14278 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14279 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14280 SequenceTree::Seq OldRegion = Region;
14282 assert(CXXOCE->getNumArgs() >= 1 &&
14283 "An overloaded call operator must have at least one argument"
14284 " for the postfix-expression!");
14285 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14286 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14287 CXXOCE->getNumArgs() - 1);
14291 Region = PostfixExprRegion;
14292 SequencedSubexpression Sequenced(*this);
14293 Visit(PostfixExpr);
14297 Region = ArgsRegion;
14298 for (const Expr *Arg : Args)
14301 Region = OldRegion;
14302 Tree.merge(PostfixExprRegion);
14303 Tree.merge(ArgsRegion);
14305 assert(CXXOCE->getNumArgs() == 2 &&
14306 "Should only have two arguments here!");
14307 assert((SequencingKind == LHSBeforeRHS ||
14308 SequencingKind == RHSBeforeLHS) &&
14309 "Unexpected sequencing kind!");
14313 const Expr *E1 = CXXOCE->getArg(0);
14314 const Expr *E2 = CXXOCE->getArg(1);
14315 if (SequencingKind == RHSBeforeLHS)
14318 return VisitSequencedExpressions(E1, E2);
14325 SequencedSubexpression Sequenced(*
this);
14328 return VisitExpr(CCE);
14331 SequenceExpressionsInOrder(
14337 return VisitExpr(ILE);
14340 SequenceExpressionsInOrder(ILE->
inits());
14352 SequenceTree::Seq Parent = Region;
14353 for (
const Expr *E : ExpressionList) {
14356 Region = Tree.allocate(Parent);
14357 Elts.push_back(Region);
14363 for (
unsigned I = 0; I < Elts.size(); ++I)
14364 Tree.merge(Elts[I]);
14368SequenceChecker::UsageInfo::UsageInfo() =
default;
14372void Sema::CheckUnsequencedOperations(
const Expr *E) {
14373 SmallVector<const Expr *, 8> WorkList;
14374 WorkList.push_back(E);
14375 while (!WorkList.empty()) {
14376 const Expr *Item = WorkList.pop_back_val();
14377 SequenceChecker(*
this, Item, WorkList);
14382 bool IsConstexpr) {
14385 CheckImplicitConversions(E, CheckLoc);
14387 CheckUnsequencedOperations(E);
14389 CheckForIntOverflow(E);
14402 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14406 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14410 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14424 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14428 bool CheckParameterNames) {
14429 bool HasInvalidParm =
false;
14431 assert(Param &&
"null in a parameter list");
14440 if (!Param->isInvalidDecl() &&
14442 diag::err_typecheck_decl_incomplete_type) ||
14444 diag::err_abstract_type_in_decl,
14446 Param->setInvalidDecl();
14447 HasInvalidParm =
true;
14452 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14456 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14464 QualType PType = Param->getOriginalType();
14472 if (!Param->isInvalidDecl()) {
14473 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14474 if (!ClassDecl->isInvalidDecl() &&
14475 !ClassDecl->hasIrrelevantDestructor() &&
14476 !ClassDecl->isDependentContext() &&
14477 ClassDecl->isParamDestroyedInCallee()) {
14489 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14490 if (!Param->getType().isConstQualified())
14491 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14495 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14500 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14501 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14506 if (!Param->isInvalidDecl() &&
14507 Param->getOriginalType()->isWebAssemblyTableType()) {
14508 Param->setInvalidDecl();
14509 HasInvalidParm =
true;
14510 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14514 return HasInvalidParm;
14517std::optional<std::pair<
14526static std::pair<CharUnits, CharUnits>
14534 if (
Base->isVirtual()) {
14541 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14548 DerivedType =
Base->getType();
14551 return std::make_pair(BaseAlignment, Offset);
14555static std::optional<std::pair<CharUnits, CharUnits>>
14561 return std::nullopt;
14566 return std::nullopt;
14570 CharUnits Offset = EltSize * IdxRes->getExtValue();
14573 return std::make_pair(P->first, P->second + Offset);
14579 return std::make_pair(
14580 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14586std::optional<std::pair<
14594 case Stmt::CStyleCastExprClass:
14595 case Stmt::CXXStaticCastExprClass:
14596 case Stmt::ImplicitCastExprClass: {
14598 const Expr *From = CE->getSubExpr();
14599 switch (CE->getCastKind()) {
14604 case CK_UncheckedDerivedToBase:
14605 case CK_DerivedToBase: {
14615 case Stmt::ArraySubscriptExprClass: {
14620 case Stmt::DeclRefExprClass: {
14624 if (!VD->getType()->isReferenceType()) {
14626 if (VD->hasDependentAlignment())
14635 case Stmt::MemberExprClass: {
14637 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14641 std::optional<std::pair<CharUnits, CharUnits>> P;
14650 return std::make_pair(P->first,
14653 case Stmt::UnaryOperatorClass: {
14663 case Stmt::BinaryOperatorClass: {
14675 return std::nullopt;
14680std::optional<std::pair<
14689 case Stmt::CStyleCastExprClass:
14690 case Stmt::CXXStaticCastExprClass:
14691 case Stmt::ImplicitCastExprClass: {
14693 const Expr *From = CE->getSubExpr();
14694 switch (CE->getCastKind()) {
14699 case CK_ArrayToPointerDecay:
14701 case CK_UncheckedDerivedToBase:
14702 case CK_DerivedToBase: {
14712 case Stmt::CXXThisExprClass: {
14717 case Stmt::UnaryOperatorClass: {
14723 case Stmt::BinaryOperatorClass: {
14732 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14733 std::swap(LHS, RHS);
14743 return std::nullopt;
14748 std::optional<std::pair<CharUnits, CharUnits>> P =
14752 return P->first.alignmentAtOffset(P->second);
14770 if (!DestPtr)
return;
14776 if (DestAlign.
isOne())
return;
14780 if (!SrcPtr)
return;
14791 if (SrcAlign >= DestAlign)
return;
14796 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14800void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14802 bool AllowOnePastEnd,
bool IndexNegated) {
14811 const Type *EffectiveType =
14815 Context.getAsConstantArrayType(BaseExpr->
getType());
14818 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14820 const Type *BaseType =
14822 bool IsUnboundedArray =
14824 Context, StrictFlexArraysLevel,
14827 (!IsUnboundedArray && BaseType->isDependentType()))
14835 if (IndexNegated) {
14836 index.setIsUnsigned(
false);
14840 if (IsUnboundedArray) {
14843 if (
index.isUnsigned() || !
index.isNegative()) {
14845 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14847 if (
index.getBitWidth() < AddrBits)
14849 std::optional<CharUnits> ElemCharUnits =
14850 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14853 if (!ElemCharUnits || ElemCharUnits->isZero())
14855 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
14860 if (
index.getActiveBits() <= AddrBits) {
14862 llvm::APInt Product(
index);
14864 Product = Product.umul_ov(ElemBytes, Overflow);
14865 if (!Overflow && Product.getActiveBits() <= AddrBits)
14871 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14872 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14874 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14875 MaxElems = MaxElems.udiv(ElemBytes);
14878 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14879 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14885 <<
toString(index, 10,
true) << AddrBits
14886 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14889 << (
unsigned)MaxElems.getLimitedValue(~0U)
14892 const NamedDecl *ND =
nullptr;
14894 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14896 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14898 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14899 ND = ME->getMemberDecl();
14903 PDiag(diag::note_array_declared_here) << ND);
14908 if (index.isUnsigned() || !index.isNegative()) {
14918 llvm::APInt size = ArrayTy->
getSize();
14920 if (BaseType != EffectiveType) {
14928 if (!ptrarith_typesize)
14929 ptrarith_typesize =
Context.getCharWidth();
14931 if (ptrarith_typesize != array_typesize) {
14933 uint64_t ratio = array_typesize / ptrarith_typesize;
14937 if (ptrarith_typesize * ratio == array_typesize)
14938 size *= llvm::APInt(size.getBitWidth(), ratio);
14942 if (size.getBitWidth() > index.getBitWidth())
14943 index = index.zext(size.getBitWidth());
14944 else if (size.getBitWidth() < index.getBitWidth())
14945 size = size.zext(index.getBitWidth());
14951 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
14958 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
14960 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
14961 SourceLocation IndexLoc =
14963 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
14968 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
14969 : diag::warn_ptr_arith_exceeds_bounds;
14970 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
14971 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
14978 unsigned DiagID = diag::warn_array_index_precedes_bounds;
14980 DiagID = diag::warn_ptr_arith_precedes_bounds;
14981 if (index.isNegative()) index = -index;
14989 const NamedDecl *ND =
nullptr;
14991 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14993 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14995 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14996 ND = ME->getMemberDecl();
15000 PDiag(diag::note_array_declared_here) << ND);
15003void Sema::CheckArrayAccess(
const Expr *
expr) {
15004 int AllowOnePastEnd = 0;
15006 expr =
expr->IgnoreParenImpCasts();
15007 switch (
expr->getStmtClass()) {
15008 case Stmt::ArraySubscriptExprClass: {
15011 AllowOnePastEnd > 0);
15015 case Stmt::MemberExprClass: {
15019 case Stmt::ArraySectionExprClass: {
15025 nullptr, AllowOnePastEnd > 0);
15028 case Stmt::UnaryOperatorClass: {
15044 case Stmt::ConditionalOperatorClass: {
15046 if (
const Expr *lhs = cond->
getLHS())
15047 CheckArrayAccess(lhs);
15048 if (
const Expr *rhs = cond->
getRHS())
15049 CheckArrayAccess(rhs);
15052 case Stmt::CXXOperatorCallExprClass: {
15054 for (
const auto *Arg : OCE->arguments())
15055 CheckArrayAccess(Arg);
15065 Expr *RHS,
bool isProperty) {
15077 S.
Diag(Loc, diag::warn_arc_literal_assign)
15079 << (isProperty ? 0 : 1)
15087 Expr *RHS,
bool isProperty) {
15090 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15091 S.
Diag(Loc, diag::warn_arc_retained_assign)
15093 << (isProperty ? 0 : 1)
15097 RHS =
cast->getSubExpr();
15139 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15168 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15169 Diag(Loc, diag::warn_arc_retained_property_assign)
15173 RHS =
cast->getSubExpr();
15196 bool StmtLineInvalid;
15197 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15199 if (StmtLineInvalid)
15202 bool BodyLineInvalid;
15203 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15205 if (BodyLineInvalid)
15209 if (StmtLine != BodyLine)
15224 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15233 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15237 const Stmt *PossibleBody) {
15243 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15244 StmtLoc = FS->getRParenLoc();
15245 Body = FS->getBody();
15246 DiagID = diag::warn_empty_for_body;
15247 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15248 StmtLoc = WS->getRParenLoc();
15249 Body = WS->getBody();
15250 DiagID = diag::warn_empty_while_body;
15255 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15279 if (!ProbableTypo) {
15280 bool BodyColInvalid;
15281 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15283 if (BodyColInvalid)
15286 bool StmtColInvalid;
15289 if (StmtColInvalid)
15292 if (BodyCol > StmtCol)
15293 ProbableTypo =
true;
15296 if (ProbableTypo) {
15298 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15306 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15318 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15320 RHSExpr = CE->
getArg(0);
15321 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15322 CXXSCE && CXXSCE->isXValue())
15323 RHSExpr = CXXSCE->getSubExpr();
15327 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15328 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15331 if (LHSDeclRef && RHSDeclRef) {
15338 auto D =
Diag(OpLoc, diag::warn_self_move)
15354 const Expr *LHSBase = LHSExpr;
15355 const Expr *RHSBase = RHSExpr;
15356 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15357 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15358 if (!LHSME || !RHSME)
15361 while (LHSME && RHSME) {
15368 LHSME = dyn_cast<MemberExpr>(LHSBase);
15369 RHSME = dyn_cast<MemberExpr>(RHSBase);
15372 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15373 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15374 if (LHSDeclRef && RHSDeclRef) {
15381 Diag(OpLoc, diag::warn_self_move)
15388 Diag(OpLoc, diag::warn_self_move)
15412 bool AreUnionMembers =
false) {
15416 assert(((Field1Parent->isStructureOrClassType() &&
15417 Field2Parent->isStructureOrClassType()) ||
15418 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15419 "Can't evaluate layout compatibility between a struct field and a "
15421 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15422 (AreUnionMembers && Field1Parent->isUnionType())) &&
15423 "AreUnionMembers should be 'true' for union fields (only).");
15437 if (Bits1 != Bits2)
15441 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15442 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15445 if (!AreUnionMembers &&
15457 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15458 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15460 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15461 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15466 return isLayoutCompatible(C, F1, F2);
15477 for (
auto *Field1 : RD1->
fields()) {
15478 auto I = UnmatchedFields.begin();
15479 auto E = UnmatchedFields.end();
15481 for ( ; I != E; ++I) {
15483 bool Result = UnmatchedFields.erase(*I);
15493 return UnmatchedFields.empty();
15519 if (
C.hasSameType(T1, T2))
15528 if (TC1 == Type::Enum)
15530 if (TC1 == Type::Record) {
15549 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15580 const ValueDecl **VD, uint64_t *MagicValue,
15581 bool isConstantEvaluated) {
15589 case Stmt::UnaryOperatorClass: {
15598 case Stmt::DeclRefExprClass: {
15604 case Stmt::IntegerLiteralClass: {
15606 llvm::APInt MagicValueAPInt = IL->
getValue();
15607 if (MagicValueAPInt.getActiveBits() <= 64) {
15608 *MagicValue = MagicValueAPInt.getZExtValue();
15614 case Stmt::BinaryConditionalOperatorClass:
15615 case Stmt::ConditionalOperatorClass: {
15620 isConstantEvaluated)) {
15630 case Stmt::BinaryOperatorClass: {
15633 TypeExpr = BO->
getRHS();
15663 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15666 bool isConstantEvaluated) {
15667 FoundWrongKind =
false;
15672 uint64_t MagicValue;
15674 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15678 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15679 if (I->getArgumentKind() != ArgumentKind) {
15680 FoundWrongKind =
true;
15683 TypeInfo.Type = I->getMatchingCType();
15684 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15685 TypeInfo.MustBeNull = I->getMustBeNull();
15696 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15697 if (I == MagicValues->end())
15706 bool LayoutCompatible,
15708 if (!TypeTagForDatatypeMagicValues)
15709 TypeTagForDatatypeMagicValues.reset(
15710 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15713 (*TypeTagForDatatypeMagicValues)[Magic] =
15729 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15730 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15731 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15732 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15735void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15738 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
15739 bool IsPointerAttr = Attr->getIsPointer();
15742 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
15743 if (TypeTagIdxAST >= ExprArgs.size()) {
15744 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15745 << 0 << Attr->getTypeTagIdx().getSourceIndex();
15748 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15749 bool FoundWrongKind;
15752 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15754 if (FoundWrongKind)
15756 diag::warn_type_tag_for_datatype_wrong_kind)
15762 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
15763 if (ArgumentIdxAST >= ExprArgs.size()) {
15764 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15765 << 1 << Attr->getArgumentIdx().getSourceIndex();
15768 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15769 if (IsPointerAttr) {
15771 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15772 if (ICE->getType()->isVoidPointerType() &&
15773 ICE->getCastKind() == CK_BitCast)
15774 ArgumentExpr = ICE->getSubExpr();
15776 QualType ArgumentType = ArgumentExpr->
getType();
15782 if (TypeInfo.MustBeNull) {
15787 diag::warn_type_safety_null_pointer_required)
15795 QualType RequiredType = TypeInfo.Type;
15797 RequiredType =
Context.getPointerType(RequiredType);
15799 bool mismatch =
false;
15800 if (!TypeInfo.LayoutCompatible) {
15801 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
15822 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15823 << ArgumentType << ArgumentKind
15824 << TypeInfo.LayoutCompatible << RequiredType
15842 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15850 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
15856 auto &MisalignedMembersForExpr =
15858 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15859 if (MA != MisalignedMembersForExpr.end() &&
15860 (
T->isDependentType() ||
T->isIntegerType() ||
15861 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
15863 T->getPointeeType()) <= MA->Alignment))))
15864 MisalignedMembersForExpr.erase(MA);
15873 const auto *ME = dyn_cast<MemberExpr>(E);
15885 bool AnyIsPacked =
false;
15887 QualType BaseType = ME->getBase()->getType();
15888 if (BaseType->isDependentType())
15892 auto *RD = BaseType->castAsRecordDecl();
15897 auto *FD = dyn_cast<FieldDecl>(MD);
15903 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15904 ReverseMemberChain.push_back(FD);
15907 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15909 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15916 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15927 if (ExpectedAlignment.
isOne())
15932 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15933 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
15937 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
15941 if (DRE && !TopME->
isArrow()) {
15944 CompleteObjectAlignment =
15945 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
15949 if (Offset % ExpectedAlignment != 0 ||
15952 CompleteObjectAlignment < ExpectedAlignment) {
15963 for (
FieldDecl *FDI : ReverseMemberChain) {
15964 if (FDI->hasAttr<PackedAttr>() ||
15965 FDI->getParent()->hasAttr<PackedAttr>()) {
15967 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
15973 assert(FD &&
"We did not find a packed FieldDecl!");
15974 Action(E, FD->
getParent(), FD, Alignment);
15978void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
15979 using namespace std::placeholders;
15982 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16018bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16019 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16032 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16033 TheCall->
setType(VecTy0->getElementType());
16046 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16063 assert(!Args.empty() &&
"Should have at least one argument.");
16065 Expr *Arg0 = Args.front();
16068 auto EmitError = [&](
Expr *ArgI) {
16070 diag::err_typecheck_call_different_arg_types)
16071 << Arg0->
getType() << ArgI->getType();
16076 for (
Expr *ArgI : Args.drop_front())
16087 for (
Expr *ArgI : Args.drop_front()) {
16088 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16091 VecI->getElementType()) ||
16092 Vec0->getNumElements() != VecI->getNumElements()) {
16101std::optional<QualType>
16105 return std::nullopt;
16109 return std::nullopt;
16112 for (
int I = 0; I < 2; ++I) {
16116 return std::nullopt;
16117 Args[I] = Converted.
get();
16124 return std::nullopt;
16127 return std::nullopt;
16129 TheCall->
setArg(0, Args[0]);
16130 TheCall->
setArg(1, Args[1]);
16141 TheCall->
getArg(1), Loc) ||
16143 TheCall->
getArg(2), Loc))
16147 for (
int I = 0; I < 3; ++I) {
16152 Args[I] = Converted.
get();
16155 int ArgOrdinal = 1;
16156 for (
Expr *Arg : Args) {
16158 ArgTyRestr, ArgOrdinal++))
16165 for (
int I = 0; I < 3; ++I)
16166 TheCall->
setArg(I, Args[I]);
16172bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16184bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16193 diag::err_builtin_invalid_arg_type)
16194 << 1 << 2 << 1 << 1 << TyArg;
16208 Expr *Matrix = MatrixArg.
get();
16210 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16213 << 1 << 3 << 0 << 0
16220 QualType ResultType =
Context.getConstantMatrixType(
16221 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16224 TheCall->
setType(ResultType);
16227 TheCall->
setArg(0, Matrix);
16232static std::optional<unsigned>
16240 uint64_t
Dim =
Value->getZExtValue();
16259 unsigned PtrArgIdx = 0;
16260 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16261 Expr *RowsExpr = TheCall->
getArg(1);
16262 Expr *ColumnsExpr = TheCall->
getArg(2);
16263 Expr *StrideExpr = TheCall->
getArg(3);
16265 bool ArgError =
false;
16272 PtrExpr = PtrConv.
get();
16273 TheCall->
setArg(0, PtrExpr);
16280 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16281 QualType ElementTy;
16284 << PtrArgIdx + 1 << 0 << 5 << 0
16288 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16292 << PtrArgIdx + 1 << 0 << 5
16299 auto ApplyArgumentConversions = [
this](Expr *E) {
16308 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16310 RowsExpr = RowsConv.
get();
16311 TheCall->
setArg(1, RowsExpr);
16313 RowsExpr =
nullptr;
16315 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16317 ColumnsExpr = ColumnsConv.
get();
16318 TheCall->
setArg(2, ColumnsExpr);
16320 ColumnsExpr =
nullptr;
16331 std::optional<unsigned> MaybeRows;
16335 std::optional<unsigned> MaybeColumns;
16340 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16343 StrideExpr = StrideConv.
get();
16344 TheCall->
setArg(3, StrideExpr);
16347 if (std::optional<llvm::APSInt>
Value =
16350 if (Stride < *MaybeRows) {
16352 diag::err_builtin_matrix_stride_too_small);
16358 if (ArgError || !MaybeRows || !MaybeColumns)
16362 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16371 unsigned PtrArgIdx = 1;
16372 Expr *MatrixExpr = TheCall->
getArg(0);
16373 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16374 Expr *StrideExpr = TheCall->
getArg(2);
16376 bool ArgError =
false;
16382 MatrixExpr = MatrixConv.
get();
16383 TheCall->
setArg(0, MatrixExpr);
16390 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16393 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16401 PtrExpr = PtrConv.
get();
16402 TheCall->
setArg(1, PtrExpr);
16410 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16413 << PtrArgIdx + 1 << 0 << 5 << 0
16417 QualType ElementTy = PtrTy->getPointeeType();
16419 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16424 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16426 diag::err_builtin_matrix_pointer_arg_mismatch)
16427 << ElementTy << MatrixTy->getElementType();
16442 StrideExpr = StrideConv.
get();
16443 TheCall->
setArg(2, StrideExpr);
16448 if (std::optional<llvm::APSInt>
Value =
16451 if (Stride < MatrixTy->getNumRows()) {
16453 diag::err_builtin_matrix_stride_too_small);
16473 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16478 llvm::StringSet<> CalleeTCBs;
16479 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16480 CalleeTCBs.insert(A->getTCBName());
16481 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16482 CalleeTCBs.insert(A->getTCBName());
16486 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16487 StringRef CallerTCB = A->getTCBName();
16488 if (CalleeTCBs.count(CallerTCB) == 0) {
16489 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16490 << 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 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 CFIUncheckedCalleeChange AdjustingCFIUncheckedCallee(QualType From, QualType To)
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 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
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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
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
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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.
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.
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 constexpr unsigned getMaxElementsPerDimension()
Returns the maximum number of elements per dimension.
static constexpr bool isDimensionValid(size_t NumElements)
Returns true if NumElements is a valid matrix dimension.
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.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial 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 AddingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function without the cfi_unchecked_callee attribut...
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...
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
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 FomatStringIn...
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.
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.