83#include "llvm/ADT/APFloat.h"
84#include "llvm/ADT/APInt.h"
85#include "llvm/ADT/APSInt.h"
86#include "llvm/ADT/ArrayRef.h"
87#include "llvm/ADT/DenseMap.h"
88#include "llvm/ADT/FoldingSet.h"
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/STLForwardCompat.h"
91#include "llvm/ADT/SmallBitVector.h"
92#include "llvm/ADT/SmallPtrSet.h"
93#include "llvm/ADT/SmallString.h"
94#include "llvm/ADT/SmallVector.h"
95#include "llvm/ADT/StringExtras.h"
96#include "llvm/ADT/StringRef.h"
97#include "llvm/ADT/StringSet.h"
98#include "llvm/ADT/StringSwitch.h"
99#include "llvm/Support/AtomicOrdering.h"
100#include "llvm/Support/Compiler.h"
101#include "llvm/Support/ConvertUTF.h"
102#include "llvm/Support/ErrorHandling.h"
103#include "llvm/Support/Format.h"
104#include "llvm/Support/Locale.h"
105#include "llvm/Support/MathExtras.h"
106#include "llvm/Support/SaveAndRestore.h"
107#include "llvm/Support/raw_ostream.h"
108#include "llvm/TargetParser/RISCVTargetParser.h"
109#include "llvm/TargetParser/Triple.h"
122using namespace clang;
126 unsigned ByteNo)
const {
137 unsigned ArgCount =
Call->getNumArgs();
138 if (ArgCount >= MinArgCount)
141 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
142 << 0 << MinArgCount << ArgCount
143 << 0 <<
Call->getSourceRange();
147 unsigned ArgCount =
Call->getNumArgs();
148 if (ArgCount <= MaxArgCount)
150 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
151 << 0 << MaxArgCount << ArgCount
152 << 0 <<
Call->getSourceRange();
156 unsigned MaxArgCount) {
162 unsigned ArgCount =
Call->getNumArgs();
163 if (ArgCount == DesiredArgCount)
168 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
172 Call->getArg(ArgCount - 1)->getEndLoc());
174 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
175 << 0 << DesiredArgCount << ArgCount
180 bool HasError =
false;
182 for (
const Expr *Arg :
Call->arguments()) {
183 if (Arg->isValueDependent())
186 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
187 int DiagMsgKind = -1;
189 if (!ArgString.has_value())
191 else if (ArgString->find(
'$') != std::string::npos)
194 if (DiagMsgKind >= 0) {
195 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
196 << DiagMsgKind << Arg->getSourceRange();
205 if (
Value->isTypeDependent())
236 if (!Literal || !Literal->isOrdinary()) {
249 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
257 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
258 if (!Literal || !Literal->isWide()) {
259 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
260 << Arg->getSourceRange();
297 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
328 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
330 auto IsValidIntegerType = [](
QualType Ty) {
331 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
338 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
343 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
345 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
347 S.
Diag(Source->getExprLoc(),
348 diag::note_alignment_invalid_function_pointer);
353 if (!IsValidIntegerType(AlignOp->
getType())) {
364 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
365 llvm::APSInt MaxValue(
366 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
367 if (AlignValue < 1) {
368 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
371 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
376 if (!AlignValue.isPowerOf2()) {
377 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
380 if (AlignValue == 1) {
381 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
382 << IsBooleanAlignBuiltin;
410 std::pair<unsigned, const char *> Builtins[] = {
411 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
412 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
413 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
416 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
423 auto ValidCkdIntType = [](
QualType QT) {
426 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
427 return (BT->getKind() >= BuiltinType::Short &&
428 BT->getKind() <= BuiltinType::Int128) || (
429 BT->getKind() >= BuiltinType::UShort &&
430 BT->getKind() <= BuiltinType::UInt128) ||
431 BT->getKind() == BuiltinType::UChar ||
432 BT->getKind() == BuiltinType::SChar;
437 for (
unsigned I = 0; I < 2; ++I) {
443 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
462 !PtrTy->getPointeeType()->isIntegerType() ||
463 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
464 PtrTy->getPointeeType().isConstQualified()) {
466 diag::err_overflow_builtin_must_be_ptr_int)
474 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
475 for (
unsigned I = 0; I < 3; ++I) {
476 const auto Arg = TheCall->
getArg(I);
479 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
481 return S.
Diag(Arg->getBeginLoc(),
482 diag::err_overflow_builtin_bit_int_max_size)
491struct BuiltinDumpStructGenerator {
495 SmallVector<Expr *, 32> Actions;
496 DiagnosticErrorTrap ErrorTracker;
497 PrintingPolicy Policy;
499 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
500 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
501 Policy(S.Context.getPrintingPolicy()) {
503 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
506 Expr *makeOpaqueValueExpr(Expr *Inner) {
510 Actions.push_back(OVE);
514 Expr *getStringLiteral(llvm::StringRef Str) {
517 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
520 bool callPrintFunction(llvm::StringRef Format,
521 llvm::ArrayRef<Expr *> Exprs = {}) {
522 SmallVector<Expr *, 8> Args;
524 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
526 Args.push_back(getStringLiteral(Format));
527 llvm::append_range(Args, Exprs);
530 Sema::CodeSynthesisContext Ctx;
543 Actions.push_back(RealCall.
get());
549 Expr *getIndentString(
unsigned Depth) {
553 llvm::SmallString<32>
Indent;
555 return getStringLiteral(
Indent);
559 return getStringLiteral(
T.getAsString(Policy));
562 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
563 llvm::raw_svector_ostream
OS(Str);
567 if (
auto *BT =
T->
getAs<BuiltinType>()) {
568 switch (BT->getKind()) {
569 case BuiltinType::Bool:
572 case BuiltinType::Char_U:
573 case BuiltinType::UChar:
576 case BuiltinType::Char_S:
577 case BuiltinType::SChar:
585 analyze_printf::PrintfSpecifier
Specifier;
588 if (
Specifier.getConversionSpecifier().getKind() ==
589 analyze_printf::PrintfConversionSpecifier::sArg) {
595 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
615 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
616 Expr *IndentLit = getIndentString(Depth);
618 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
619 : callPrintFunction(
"%s", {TypeLit}))
622 return dumpRecordValue(RD, E, IndentLit, Depth);
626 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
635 Expr *RecordArg = makeOpaqueValueExpr(E);
638 if (callPrintFunction(
" {\n"))
642 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
643 for (
const auto &Base : CXXRD->bases()) {
651 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
657 Expr *FieldIndentArg = getIndentString(Depth + 1);
660 for (
auto *D : RD->
decls()) {
661 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
662 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
663 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
666 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
667 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
669 getStringLiteral(FD->getName())};
671 if (FD->isBitField()) {
675 FD->getBitWidthValue());
683 CXXScopeSpec(), Loc, IFD,
686 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
688 DeclarationNameInfo(FD->getDeclName(), Loc));
689 if (
Field.isInvalid())
692 auto *InnerRD = FD->getType()->getAsRecordDecl();
693 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
694 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
696 if (callPrintFunction(Format, Args) ||
697 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
701 if (appendFormatSpecifier(FD->getType(), Format)) {
703 Args.push_back(
Field.get());
713 Args.push_back(FieldAddr.
get());
716 if (callPrintFunction(Format, Args))
721 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
722 : callPrintFunction(
"}\n");
725 Expr *buildWrapper() {
728 TheCall->
setType(Wrapper->getType());
749 diag::err_expected_struct_pointer_argument)
758 diag::err_incomplete_type))
767 switch (BT ? BT->getKind() : BuiltinType::Void) {
768 case BuiltinType::Dependent:
769 case BuiltinType::Overload:
770 case BuiltinType::BoundMember:
771 case BuiltinType::PseudoObject:
772 case BuiltinType::UnknownAny:
773 case BuiltinType::BuiltinFn:
779 diag::err_expected_callable_argument)
785 BuiltinDumpStructGenerator Generator(S, TheCall);
791 Expr *PtrArg = PtrArgResult.
get();
795 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
798 return Generator.buildWrapper();
810 if (
Call->getStmtClass() != Stmt::CallExprClass) {
811 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
812 <<
Call->getSourceRange();
817 if (CE->getCallee()->getType()->isBlockPointerType()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
819 <<
Call->getSourceRange();
823 const Decl *TargetDecl = CE->getCalleeDecl();
824 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
825 if (FD->getBuiltinID()) {
826 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
827 <<
Call->getSourceRange();
832 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
833 <<
Call->getSourceRange();
841 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
855 BuiltinCall->
setType(CE->getType());
859 BuiltinCall->
setArg(1, ChainResult.
get());
866class ScanfDiagnosticFormatHandler
870 using ComputeSizeFunction =
871 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
875 using DiagnoseFunction =
876 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
878 ComputeSizeFunction ComputeSizeArgument;
879 DiagnoseFunction Diagnose;
882 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
883 DiagnoseFunction Diagnose)
884 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
886 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
887 const char *StartSpecifier,
888 unsigned specifierLen)
override {
892 unsigned NulByte = 0;
904 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
906 analyze_format_string::OptionalAmount::HowSpecified::Constant)
911 std::optional<llvm::APSInt> DestSizeAPS =
916 unsigned DestSize = DestSizeAPS->getZExtValue();
918 if (DestSize < SourceSize)
925class EstimateSizeFormatHandler
930 bool IsKernelCompatible =
true;
933 EstimateSizeFormatHandler(StringRef Format)
934 :
Size(std::
min(Format.find(0), Format.size()) +
937 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
938 const char *,
unsigned SpecifierLen,
939 const TargetInfo &)
override {
941 const size_t FieldWidth = computeFieldWidth(FS);
942 const size_t Precision = computePrecision(FS);
949 Size += std::max(FieldWidth, (
size_t)1);
961 Size += std::max(FieldWidth, Precision);
977 Size += std::max(FieldWidth, 1 +
978 (Precision ? 1 + Precision
988 (Precision ? 1 + Precision : 0) +
998 (Precision ? 1 + Precision : 0) +
1013 IsKernelCompatible =
false;
1014 Size += std::max(FieldWidth, 2 + Precision);
1061 Size += (Precision ? 0 : 1);
1068 assert(SpecifierLen <= Size &&
"no underflow");
1069 Size -= SpecifierLen;
1073 size_t getSizeLowerBound()
const {
return Size; }
1074 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1077 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1079 size_t FieldWidth = 0;
1085 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1086 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1087 size_t Precision = 0;
1134 StringRef &FormatStrRef,
size_t &StrLen,
1136 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1137 Format && (Format->isOrdinary() || Format->isUTF8())) {
1138 FormatStrRef = Format->getString();
1140 Context.getAsConstantArrayType(Format->getType());
1141 assert(
T &&
"String literal not of constant array type!");
1142 size_t TypeSize =
T->getZExtSize();
1144 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1152class FortifiedBufferChecker {
1154 FortifiedBufferChecker(Sema &S, FunctionDecl *FD, CallExpr *TheCall)
1155 : S(S), TheCall(TheCall), FD(FD),
1156 DABAttr(FD ? FD->getAttr<DiagnoseAsBuiltinAttr>() :
nullptr) {
1161 std::optional<unsigned> TranslateIndex(
unsigned Index) {
1168 unsigned DABIndices = DABAttr->argIndices_size();
1169 unsigned NewIndex = Index < DABIndices
1170 ? DABAttr->argIndices_begin()[Index]
1173 return std::nullopt;
1177 std::optional<llvm::APSInt>
1178 ComputeExplicitObjectSizeArgument(
unsigned Index) {
1179 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1181 return std::nullopt;
1182 unsigned NewIndex = *IndexOptional;
1184 Expr *SizeArg = TheCall->
getArg(NewIndex);
1186 return std::nullopt;
1188 assert(
Integer.isUnsigned() &&
1189 "size arg should be unsigned after implicit conversion to size_t");
1193 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1199 if (Index < FD->getNumParams()) {
1200 if (
const auto *POS =
1202 BOSType = POS->getType();
1205 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1207 return std::nullopt;
1208 unsigned NewIndex = *IndexOptional;
1211 return std::nullopt;
1213 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1214 if (std::optional<uint64_t> ObjSize =
1217 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1219 return std::nullopt;
1222 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1223 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1225 return std::nullopt;
1226 unsigned NewIndex = *IndexOptional;
1228 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1230 if (std::optional<uint64_t>
Result =
1233 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1235 return std::nullopt;
1238 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1240 unsigned getBuiltinID()
const {
1241 const FunctionDecl *UseDecl = FD;
1243 UseDecl = DABAttr->getFunction();
1244 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1251 unsigned ID = getBuiltinID();
1255 assert(Callee &&
"expected callee");
1256 return Callee->getName().str();
1259 StringRef Ref = Name;
1261 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1262 Ref.consume_front(
"__builtin_");
1263 assert(!Ref.empty() &&
"expected non-empty function name");
1268 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1272 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1273 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1278 std::optional<llvm::APSInt> CopyLen =
1279 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1280 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1282 if (!CopyLen || !SrcBufSize)
1286 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1290 S.
PDiag(diag::warn_stringop_overread)
1292 << SrcBufSize->getZExtValue());
1299 const DiagnoseAsBuiltinAttr *DABAttr;
1300 unsigned SizeTypeWidth;
1304void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1309 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1311 unsigned BuiltinID = Checker.getBuiltinID();
1315 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1317 std::optional<llvm::APSInt> SourceSize;
1318 std::optional<llvm::APSInt> DestinationSize;
1319 unsigned DiagID = 0;
1321 switch (BuiltinID) {
1324 case Builtin::BI__builtin_strcat:
1325 case Builtin::BIstrcat:
1326 case Builtin::BI__builtin_stpcpy:
1327 case Builtin::BIstpcpy:
1328 case Builtin::BI__builtin_strcpy:
1329 case Builtin::BIstrcpy: {
1330 DiagID = diag::warn_fortify_strlen_overflow;
1331 SourceSize = Checker.ComputeStrLenArgument(1);
1332 DestinationSize = Checker.ComputeSizeArgument(0);
1336 case Builtin::BI__builtin___strcat_chk:
1337 case Builtin::BI__builtin___stpcpy_chk:
1338 case Builtin::BI__builtin___strcpy_chk: {
1339 DiagID = diag::warn_fortify_strlen_overflow;
1340 SourceSize = Checker.ComputeStrLenArgument(1);
1341 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1345 case Builtin::BIscanf:
1346 case Builtin::BIfscanf:
1347 case Builtin::BIsscanf: {
1348 unsigned FormatIndex = 1;
1349 unsigned DataIndex = 2;
1350 if (BuiltinID == Builtin::BIscanf) {
1355 const auto *FormatExpr =
1358 StringRef FormatStrRef;
1363 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1364 unsigned SourceSize) {
1365 DiagID = diag::warn_fortify_scanf_overflow;
1366 unsigned Index = ArgIndex + DataIndex;
1367 std::string FunctionName = Checker.getFunctionName();
1369 PDiag(DiagID) << FunctionName << (Index + 1)
1370 << DestSize << SourceSize);
1373 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1374 return Checker.ComputeSizeArgument(Index + DataIndex);
1376 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1377 const char *FormatBytes = FormatStrRef.data();
1388 case Builtin::BIsprintf:
1389 case Builtin::BI__builtin___sprintf_chk: {
1390 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1393 StringRef FormatStrRef;
1396 EstimateSizeFormatHandler H(FormatStrRef);
1397 const char *FormatBytes = FormatStrRef.data();
1399 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1400 Context.getTargetInfo(),
false)) {
1401 DiagID = H.isKernelCompatible()
1402 ? diag::warn_format_overflow
1403 : diag::warn_format_overflow_non_kprintf;
1404 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1405 .extOrTrunc(SizeTypeWidth);
1406 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1407 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2);
1409 DestinationSize = Checker.ComputeSizeArgument(0);
1416 case Builtin::BI__builtin___memcpy_chk:
1417 case Builtin::BI__builtin___memmove_chk:
1418 case Builtin::BI__builtin___memset_chk:
1419 case Builtin::BI__builtin___strlcat_chk:
1420 case Builtin::BI__builtin___strlcpy_chk:
1421 case Builtin::BI__builtin___strncat_chk:
1422 case Builtin::BI__builtin___strncpy_chk:
1423 case Builtin::BI__builtin___stpncpy_chk:
1424 case Builtin::BI__builtin___memccpy_chk:
1425 case Builtin::BI__builtin___mempcpy_chk: {
1426 DiagID = diag::warn_builtin_chk_overflow;
1428 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1430 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1432 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1433 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1434 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1435 Checker.checkSourceOverread(1, 2);
1440 case Builtin::BI__builtin___snprintf_chk:
1441 case Builtin::BI__builtin___vsnprintf_chk: {
1442 DiagID = diag::warn_builtin_chk_overflow;
1443 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1444 DestinationSize = Checker.ComputeExplicitObjectSizeArgument(3);
1448 case Builtin::BIstrncat:
1449 case Builtin::BI__builtin_strncat:
1450 case Builtin::BIstrncpy:
1451 case Builtin::BI__builtin_strncpy:
1452 case Builtin::BIstpncpy:
1453 case Builtin::BI__builtin_stpncpy: {
1459 DiagID = diag::warn_fortify_source_size_mismatch;
1461 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1462 DestinationSize = Checker.ComputeSizeArgument(0);
1466 case Builtin::BIbzero:
1467 case Builtin::BI__builtin_bzero:
1468 case Builtin::BImemcpy:
1469 case Builtin::BI__builtin_memcpy:
1470 case Builtin::BImemmove:
1471 case Builtin::BI__builtin_memmove:
1472 case Builtin::BImemset:
1473 case Builtin::BI__builtin_memset:
1474 case Builtin::BImempcpy:
1475 case Builtin::BI__builtin_mempcpy: {
1476 DiagID = diag::warn_fortify_source_overflow;
1478 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1479 DestinationSize = Checker.ComputeSizeArgument(0);
1482 if (BuiltinID != Builtin::BImemset &&
1483 BuiltinID != Builtin::BI__builtin_memset &&
1484 BuiltinID != Builtin::BIbzero &&
1485 BuiltinID != Builtin::BI__builtin_bzero) {
1486 Checker.checkSourceOverread(1, 2);
1490 case Builtin::BIbcopy:
1491 case Builtin::BI__builtin_bcopy: {
1492 DiagID = diag::warn_fortify_source_overflow;
1494 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1495 DestinationSize = Checker.ComputeSizeArgument(1);
1496 Checker.checkSourceOverread(0, 2);
1501 case Builtin::BImemchr:
1502 case Builtin::BI__builtin_memchr: {
1503 Checker.checkSourceOverread(0, 2);
1509 case Builtin::BImemcmp:
1510 case Builtin::BI__builtin_memcmp:
1511 case Builtin::BIbcmp:
1512 case Builtin::BI__builtin_bcmp: {
1513 Checker.checkSourceOverread(0, 2);
1514 Checker.checkSourceOverread(1, 2);
1517 case Builtin::BIsnprintf:
1518 case Builtin::BI__builtin_snprintf:
1519 case Builtin::BIvsnprintf:
1520 case Builtin::BI__builtin_vsnprintf: {
1521 DiagID = diag::warn_fortify_source_size_mismatch;
1522 SourceSize = Checker.ComputeExplicitObjectSizeArgument(1);
1524 StringRef FormatStrRef;
1528 EstimateSizeFormatHandler H(FormatStrRef);
1529 const char *FormatBytes = FormatStrRef.data();
1531 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1532 Context.getTargetInfo(),
false)) {
1533 llvm::APSInt FormatSize =
1534 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1535 .extOrTrunc(SizeTypeWidth);
1536 if (FormatSize > *SourceSize && *SourceSize != 0) {
1537 unsigned TruncationDiagID =
1538 H.isKernelCompatible() ? diag::warn_format_truncation
1539 : diag::warn_format_truncation_non_kprintf;
1540 SmallString<16> SpecifiedSizeStr;
1541 SmallString<16> FormatSizeStr;
1542 SourceSize->toString(SpecifiedSizeStr, 10);
1543 FormatSize.toString(FormatSizeStr, 10);
1545 PDiag(TruncationDiagID)
1546 << Checker.getFunctionName()
1547 << SpecifiedSizeStr << FormatSizeStr);
1551 DestinationSize = Checker.ComputeSizeArgument(0);
1555 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1559 if (!SourceSize || !DestinationSize ||
1560 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1563 std::string FunctionName = Checker.getFunctionName();
1565 SmallString<16> DestinationStr;
1566 SmallString<16> SourceStr;
1567 DestinationSize->toString(DestinationStr, 10);
1568 SourceSize->toString(SourceStr, 10);
1571 << FunctionName << DestinationStr << SourceStr);
1591 Expr *Arg = TheCall->
getArg(0);
1599 llvm::APInt RawValue =
R.Val.getInt();
1600 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1601 llvm::APInt
Extra = RawValue & ~Mask;
1604 SmallString<16> ExtraStr;
1605 Extra.toString(ExtraStr, 8,
false);
1622 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1625 << DRE->getDecl()->getIdentifier();
1637 "__builtin_alloca has invalid address space");
1663enum PointerAuthOpKind {
1679 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1710 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1713 llvm::raw_svector_ostream Str(
Value);
1722 Result = KeyValue->getZExtValue();
1741 bool IsAddrDiscArg =
false;
1746 IsAddrDiscArg =
true;
1755 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1756 <<
Result->getExtValue();
1758 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1764 IntVal =
Result->getZExtValue();
1768static std::pair<const ValueDecl *, CharUnits>
1775 const auto *BaseDecl =
1780 return {BaseDecl,
Result.Val.getLValueOffset()};
1784 bool RequireConstant =
false) {
1792 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1793 return OpKind != PAO_BlendInteger;
1795 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1796 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1797 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1806 }
else if (AllowsInteger(OpKind) &&
1813 <<
unsigned(OpKind == PAO_Discriminator ? 1
1814 : OpKind == PAO_BlendPointer ? 2
1815 : OpKind == PAO_BlendInteger ? 3
1816 : OpKind == PAO_BlendPC ? 4
1818 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1828 if (!RequireConstant) {
1830 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1833 ? diag::warn_ptrauth_sign_null_pointer
1834 : diag::warn_ptrauth_auth_null_pointer)
1844 if (OpKind == PAO_Sign) {
1862 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1867 assert(OpKind == PAO_Discriminator);
1873 if (
Call->getBuiltinCallee() ==
1874 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1889 assert(
Pointer->getType()->isPointerType());
1901 assert(
Integer->getType()->isIntegerType());
1907 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1920 Call->setType(
Call->getArgs()[0]->getType());
1951 PointerAuthOpKind OpKind,
1952 bool RequireConstant) {
1963 Call->setType(
Call->getArgs()[0]->getType());
1979 Call->setType(
Call->getArgs()[0]->getType());
2000 unsigned OldKey = 0;
2003 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2004 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2005 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2006 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2007 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2012 Call->setType(
Call->getArgs()[0]->getType());
2021 const Expr *AddendExpr =
Call->getArg(5);
2023 if (!AddendIsConstInt) {
2024 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2038 Call->setType(
Call->getArgs()[0]->getType());
2047 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2050 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2051 if (!Literal || Literal->getCharByteWidth() != 1) {
2067 Call->setArg(0, FirstValue.
get());
2073 if (!FirstArgRecord) {
2074 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2075 << 0 << FirstArgType;
2080 diag::err_get_vtable_pointer_requires_complete_type)) {
2085 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2086 << 1 << FirstArgRecord;
2090 Call->setType(ReturnType);
2115 auto DiagSelect = [&]() -> std::optional<unsigned> {
2122 return std::optional<unsigned>{};
2137 diag::err_incomplete_type))
2141 "Unhandled non-object pointer case");
2169 if (PT->getPointeeType()->isFunctionType()) {
2171 diag::err_builtin_is_within_lifetime_invalid_arg)
2177 if (PT->getPointeeType()->isVariableArrayType()) {
2179 << 1 <<
"__builtin_is_within_lifetime";
2184 diag::err_builtin_is_within_lifetime_invalid_arg)
2198 diag::err_builtin_trivially_relocate_invalid_arg_type)
2205 diag::err_incomplete_type))
2209 T->isIncompleteArrayType()) {
2211 diag::err_builtin_trivially_relocate_invalid_arg_type)
2212 << (
T.isConstQualified() ? 1 : 2);
2221 diag::err_builtin_trivially_relocate_invalid_arg_type)
2228 if (Size.isInvalid())
2232 if (Size.isInvalid())
2234 SizeExpr = Size.get();
2235 TheCall->
setArg(2, SizeExpr);
2245 llvm::Triple::ObjectFormatType CurObjFormat =
2247 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2260 llvm::Triple::ArchType CurArch =
2262 if (llvm::is_contained(SupportedArchs, CurArch))
2272bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2279 case llvm::Triple::arm:
2280 case llvm::Triple::armeb:
2281 case llvm::Triple::thumb:
2282 case llvm::Triple::thumbeb:
2284 case llvm::Triple::aarch64:
2285 case llvm::Triple::aarch64_32:
2286 case llvm::Triple::aarch64_be:
2288 case llvm::Triple::bpfeb:
2289 case llvm::Triple::bpfel:
2291 case llvm::Triple::dxil:
2293 case llvm::Triple::hexagon:
2295 case llvm::Triple::mips:
2296 case llvm::Triple::mipsel:
2297 case llvm::Triple::mips64:
2298 case llvm::Triple::mips64el:
2300 case llvm::Triple::spirv:
2301 case llvm::Triple::spirv32:
2302 case llvm::Triple::spirv64:
2303 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2306 case llvm::Triple::systemz:
2308 case llvm::Triple::x86:
2309 case llvm::Triple::x86_64:
2311 case llvm::Triple::ppc:
2312 case llvm::Triple::ppcle:
2313 case llvm::Triple::ppc64:
2314 case llvm::Triple::ppc64le:
2316 case llvm::Triple::amdgpu:
2318 case llvm::Triple::riscv32:
2319 case llvm::Triple::riscv64:
2320 case llvm::Triple::riscv32be:
2321 case llvm::Triple::riscv64be:
2323 case llvm::Triple::loongarch32:
2324 case llvm::Triple::loongarch64:
2327 case llvm::Triple::wasm32:
2328 case llvm::Triple::wasm64:
2330 case llvm::Triple::nvptx:
2331 case llvm::Triple::nvptx64:
2337 return T->isDependentType() ||
2338 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2353 switch (ArgTyRestr) {
2356 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2357 << ArgOrdinal << 2 << 1 << 1
2364 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2365 << ArgOrdinal << 5 << 0
2371 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2372 << ArgOrdinal << 5 << 1
2378 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2392 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2393 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2394 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2395 "Expecting __builtin_cpu_...");
2397 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2399 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2400 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2401 (!IsCPUSupports && TInfo->supportsCpuIs()));
2403 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2410 ? diag::err_builtin_aix_os_unsupported
2411 : diag::err_builtin_target_unsupported)
2417 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2455 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2456 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2457 BT->getNumBits() != 1) {
2459 << ArgTy << BT->getNumBits();
2535 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2538 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2547 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2548 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2568 TheCall->
setArg(0, Arg0);
2585 TheCall->
setArg(1, Arg1);
2591 << 2 << 1 << 4 << 0 << Arg1Ty;
2605 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2607 << (OnlyUnsigned ? 3 : 1)
2615 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2618 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2623 return emitError(S, Loc,
T);
2628 return emitError(S, Loc,
T);
2634 return emitError(S, Loc,
T);
2639 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2644 return emitError(S, Loc,
T);
2649 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2655 llvm_unreachable(
"conversion functions are permitted");
2674 TheCall->
setArg(0, Arg0);
2688 TheCall->
setArg(1, Arg1);
2699 unsigned Pos,
bool AllowConst,
2703 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2708 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2709 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2710 << Pos <<
"scalar pointer";
2719 diag::err_typecheck_convert_incompatible)
2728 bool TypeDependent =
false;
2729 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2757 Builtin::BI__builtin_masked_load))
2771 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2794 Builtin::BI__builtin_masked_store))
2802 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2813 << MaskTy << ValTy);
2817 PtrTy->getPointeeType().getUnqualifiedType()))
2819 diag::err_vec_builtin_incompatible_vector)
2848 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2861 << MaskTy << IdxTy);
2870 diag::err_vec_masked_load_store_ptr)
2899 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2914 << MaskTy << IdxTy);
2920 << MaskTy << ValTy);
2923 PtrTy->getPointeeType().getUnqualifiedType()))
2925 diag::err_vec_builtin_incompatible_vector)
2939 if (Args.size() == 0) {
2941 diag::err_typecheck_call_too_few_args_at_least)
2947 QualType FuncT = Args[0]->getType();
2950 if (Args.size() < 2) {
2952 diag::err_typecheck_call_too_few_args_at_least)
2958 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2959 QualType ObjectT = Args[1]->getType();
2961 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3010 tok::periodstar, ObjectArg.
get(), Args[0]);
3014 if (MPT->isMemberDataPointer())
3017 auto *MemCall =
new (S.
Context)
3041 return TyA->getElementType();
3048Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3053 unsigned ICEArguments = 0;
3055 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3060 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3062 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3067 if (ArgNo < TheCall->getNumArgs() &&
3070 ICEArguments &= ~(1 << ArgNo);
3074 switch (BuiltinID) {
3075 case Builtin::BI__builtin___get_unsafe_stack_start:
3076 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3078 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3079 <<
"__safestack_get_unsafe_stack_bottom";
3081 case Builtin::BI__builtin___get_unsafe_stack_top:
3083 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3084 <<
"__safestack_get_unsafe_stack_top";
3086 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3088 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3089 <<
"__safestack_get_unsafe_stack_ptr";
3091 case Builtin::BI__builtin_cpu_supports:
3092 case Builtin::BI__builtin_cpu_is:
3094 Context.getAuxTargetInfo(), BuiltinID))
3097 case Builtin::BI__builtin_cpu_init:
3098 if (!
Context.getTargetInfo().supportsCpuInit()) {
3104 case Builtin::BI__builtin___CFStringMakeConstantString:
3108 *
this, BuiltinID, TheCall,
3109 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3112 "Wrong # arguments to builtin CFStringMakeConstantString");
3113 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3116 case Builtin::BI__builtin_ms_va_start:
3117 case Builtin::BI__builtin_zos_va_start:
3118 case Builtin::BI__builtin_stdarg_start:
3119 case Builtin::BI__builtin_va_start:
3120 case Builtin::BI__builtin_c23_va_start:
3121 if (BuiltinVAStart(BuiltinID, TheCall))
3124 case Builtin::BI__va_start: {
3125 switch (
Context.getTargetInfo().getTriple().getArch()) {
3126 case llvm::Triple::aarch64:
3127 case llvm::Triple::arm:
3128 case llvm::Triple::thumb:
3129 if (BuiltinVAStartARMMicrosoft(TheCall))
3133 if (BuiltinVAStart(BuiltinID, TheCall))
3141 case Builtin::BI_interlockedbittestandset_acq:
3142 case Builtin::BI_interlockedbittestandset_rel:
3143 case Builtin::BI_interlockedbittestandset_nf:
3144 case Builtin::BI_interlockedbittestandreset_acq:
3145 case Builtin::BI_interlockedbittestandreset_rel:
3146 case Builtin::BI_interlockedbittestandreset_nf:
3149 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3154 case Builtin::BI_bittest64:
3155 case Builtin::BI_bittestandcomplement64:
3156 case Builtin::BI_bittestandreset64:
3157 case Builtin::BI_bittestandset64:
3158 case Builtin::BI_interlockedbittestandreset64:
3159 case Builtin::BI_interlockedbittestandset64:
3162 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3163 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3168 case Builtin::BI_interlockedbittestandreset64_acq:
3169 case Builtin::BI_interlockedbittestandreset64_rel:
3170 case Builtin::BI_interlockedbittestandreset64_nf:
3171 case Builtin::BI_interlockedbittestandset64_acq:
3172 case Builtin::BI_interlockedbittestandset64_rel:
3173 case Builtin::BI_interlockedbittestandset64_nf:
3178 case Builtin::BI__builtin_set_flt_rounds:
3181 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3182 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3183 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3184 llvm::Triple::ppc64le}))
3188 case Builtin::BI__builtin_isgreater:
3189 case Builtin::BI__builtin_isgreaterequal:
3190 case Builtin::BI__builtin_isless:
3191 case Builtin::BI__builtin_islessequal:
3192 case Builtin::BI__builtin_islessgreater:
3193 case Builtin::BI__builtin_isunordered:
3194 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3197 case Builtin::BI__builtin_fpclassify:
3198 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3201 case Builtin::BI__builtin_isfpclass:
3202 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3205 case Builtin::BI__builtin_isfinite:
3206 case Builtin::BI__builtin_isinf:
3207 case Builtin::BI__builtin_isinf_sign:
3208 case Builtin::BI__builtin_isnan:
3209 case Builtin::BI__builtin_issignaling:
3210 case Builtin::BI__builtin_isnormal:
3211 case Builtin::BI__builtin_issubnormal:
3212 case Builtin::BI__builtin_iszero:
3213 case Builtin::BI__builtin_signbit:
3214 case Builtin::BI__builtin_signbitf:
3215 case Builtin::BI__builtin_signbitl:
3216 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3219 case Builtin::BI__builtin_shufflevector:
3223 case Builtin::BI__builtin_masked_load:
3224 case Builtin::BI__builtin_masked_expand_load:
3226 case Builtin::BI__builtin_masked_store:
3227 case Builtin::BI__builtin_masked_compress_store:
3229 case Builtin::BI__builtin_masked_gather:
3231 case Builtin::BI__builtin_masked_scatter:
3233 case Builtin::BI__builtin_invoke:
3235 case Builtin::BI__builtin_prefetch:
3236 if (BuiltinPrefetch(TheCall))
3239 case Builtin::BI__builtin_alloca_with_align:
3240 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3241 if (BuiltinAllocaWithAlign(TheCall))
3244 case Builtin::BI__builtin_alloca:
3245 case Builtin::BI__builtin_alloca_uninitialized:
3252 case Builtin::BI__builtin_infer_alloc_token:
3256 case Builtin::BI__arithmetic_fence:
3257 if (BuiltinArithmeticFence(TheCall))
3260 case Builtin::BI__assume:
3261 case Builtin::BI__builtin_assume:
3262 if (BuiltinAssume(TheCall))
3265 case Builtin::BI__builtin_assume_aligned:
3266 if (BuiltinAssumeAligned(TheCall))
3269 case Builtin::BI__builtin_dynamic_object_size:
3270 case Builtin::BI__builtin_object_size:
3274 case Builtin::BI__builtin_longjmp:
3275 if (BuiltinLongjmp(TheCall))
3278 case Builtin::BI__builtin_setjmp:
3279 if (BuiltinSetjmp(TheCall))
3282 case Builtin::BI__builtin_complex:
3283 if (BuiltinComplex(TheCall))
3286 case Builtin::BI__builtin_classify_type:
3287 case Builtin::BI__builtin_constant_p: {
3296 case Builtin::BI__builtin_launder:
3298 case Builtin::BI__builtin_is_within_lifetime:
3300 case Builtin::BI__builtin_trivially_relocate:
3302 case Builtin::BI__builtin_clear_padding: {
3306 const Expr *PtrArg = TheCall->
getArg(0);
3307 const QualType PtrArgType = PtrArg->
getType();
3310 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3321 diag::err_typecheck_decl_incomplete_type))
3327 auto IsAddrOfDeclExpr = [&]() {
3329 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3330 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3334 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3335 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3339 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3340 if (!VarDecl || VarDecl->getType()->isReferenceType())
3345 QualType VarQType = VarDecl->getType();
3347 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3352 && !IsAddrOfDeclExpr()) {
3353 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3360 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3367 case Builtin::BI__sync_fetch_and_add:
3368 case Builtin::BI__sync_fetch_and_add_1:
3369 case Builtin::BI__sync_fetch_and_add_2:
3370 case Builtin::BI__sync_fetch_and_add_4:
3371 case Builtin::BI__sync_fetch_and_add_8:
3372 case Builtin::BI__sync_fetch_and_add_16:
3373 case Builtin::BI__sync_fetch_and_sub:
3374 case Builtin::BI__sync_fetch_and_sub_1:
3375 case Builtin::BI__sync_fetch_and_sub_2:
3376 case Builtin::BI__sync_fetch_and_sub_4:
3377 case Builtin::BI__sync_fetch_and_sub_8:
3378 case Builtin::BI__sync_fetch_and_sub_16:
3379 case Builtin::BI__sync_fetch_and_or:
3380 case Builtin::BI__sync_fetch_and_or_1:
3381 case Builtin::BI__sync_fetch_and_or_2:
3382 case Builtin::BI__sync_fetch_and_or_4:
3383 case Builtin::BI__sync_fetch_and_or_8:
3384 case Builtin::BI__sync_fetch_and_or_16:
3385 case Builtin::BI__sync_fetch_and_and:
3386 case Builtin::BI__sync_fetch_and_and_1:
3387 case Builtin::BI__sync_fetch_and_and_2:
3388 case Builtin::BI__sync_fetch_and_and_4:
3389 case Builtin::BI__sync_fetch_and_and_8:
3390 case Builtin::BI__sync_fetch_and_and_16:
3391 case Builtin::BI__sync_fetch_and_xor:
3392 case Builtin::BI__sync_fetch_and_xor_1:
3393 case Builtin::BI__sync_fetch_and_xor_2:
3394 case Builtin::BI__sync_fetch_and_xor_4:
3395 case Builtin::BI__sync_fetch_and_xor_8:
3396 case Builtin::BI__sync_fetch_and_xor_16:
3397 case Builtin::BI__sync_fetch_and_nand:
3398 case Builtin::BI__sync_fetch_and_nand_1:
3399 case Builtin::BI__sync_fetch_and_nand_2:
3400 case Builtin::BI__sync_fetch_and_nand_4:
3401 case Builtin::BI__sync_fetch_and_nand_8:
3402 case Builtin::BI__sync_fetch_and_nand_16:
3403 case Builtin::BI__sync_add_and_fetch:
3404 case Builtin::BI__sync_add_and_fetch_1:
3405 case Builtin::BI__sync_add_and_fetch_2:
3406 case Builtin::BI__sync_add_and_fetch_4:
3407 case Builtin::BI__sync_add_and_fetch_8:
3408 case Builtin::BI__sync_add_and_fetch_16:
3409 case Builtin::BI__sync_sub_and_fetch:
3410 case Builtin::BI__sync_sub_and_fetch_1:
3411 case Builtin::BI__sync_sub_and_fetch_2:
3412 case Builtin::BI__sync_sub_and_fetch_4:
3413 case Builtin::BI__sync_sub_and_fetch_8:
3414 case Builtin::BI__sync_sub_and_fetch_16:
3415 case Builtin::BI__sync_and_and_fetch:
3416 case Builtin::BI__sync_and_and_fetch_1:
3417 case Builtin::BI__sync_and_and_fetch_2:
3418 case Builtin::BI__sync_and_and_fetch_4:
3419 case Builtin::BI__sync_and_and_fetch_8:
3420 case Builtin::BI__sync_and_and_fetch_16:
3421 case Builtin::BI__sync_or_and_fetch:
3422 case Builtin::BI__sync_or_and_fetch_1:
3423 case Builtin::BI__sync_or_and_fetch_2:
3424 case Builtin::BI__sync_or_and_fetch_4:
3425 case Builtin::BI__sync_or_and_fetch_8:
3426 case Builtin::BI__sync_or_and_fetch_16:
3427 case Builtin::BI__sync_xor_and_fetch:
3428 case Builtin::BI__sync_xor_and_fetch_1:
3429 case Builtin::BI__sync_xor_and_fetch_2:
3430 case Builtin::BI__sync_xor_and_fetch_4:
3431 case Builtin::BI__sync_xor_and_fetch_8:
3432 case Builtin::BI__sync_xor_and_fetch_16:
3433 case Builtin::BI__sync_nand_and_fetch:
3434 case Builtin::BI__sync_nand_and_fetch_1:
3435 case Builtin::BI__sync_nand_and_fetch_2:
3436 case Builtin::BI__sync_nand_and_fetch_4:
3437 case Builtin::BI__sync_nand_and_fetch_8:
3438 case Builtin::BI__sync_nand_and_fetch_16:
3439 case Builtin::BI__sync_val_compare_and_swap:
3440 case Builtin::BI__sync_val_compare_and_swap_1:
3441 case Builtin::BI__sync_val_compare_and_swap_2:
3442 case Builtin::BI__sync_val_compare_and_swap_4:
3443 case Builtin::BI__sync_val_compare_and_swap_8:
3444 case Builtin::BI__sync_val_compare_and_swap_16:
3445 case Builtin::BI__sync_bool_compare_and_swap:
3446 case Builtin::BI__sync_bool_compare_and_swap_1:
3447 case Builtin::BI__sync_bool_compare_and_swap_2:
3448 case Builtin::BI__sync_bool_compare_and_swap_4:
3449 case Builtin::BI__sync_bool_compare_and_swap_8:
3450 case Builtin::BI__sync_bool_compare_and_swap_16:
3451 case Builtin::BI__sync_lock_test_and_set:
3452 case Builtin::BI__sync_lock_test_and_set_1:
3453 case Builtin::BI__sync_lock_test_and_set_2:
3454 case Builtin::BI__sync_lock_test_and_set_4:
3455 case Builtin::BI__sync_lock_test_and_set_8:
3456 case Builtin::BI__sync_lock_test_and_set_16:
3457 case Builtin::BI__sync_lock_release:
3458 case Builtin::BI__sync_lock_release_1:
3459 case Builtin::BI__sync_lock_release_2:
3460 case Builtin::BI__sync_lock_release_4:
3461 case Builtin::BI__sync_lock_release_8:
3462 case Builtin::BI__sync_lock_release_16:
3463 case Builtin::BI__sync_swap:
3464 case Builtin::BI__sync_swap_1:
3465 case Builtin::BI__sync_swap_2:
3466 case Builtin::BI__sync_swap_4:
3467 case Builtin::BI__sync_swap_8:
3468 case Builtin::BI__sync_swap_16:
3469 return BuiltinAtomicOverloaded(TheCallResult);
3470 case Builtin::BI__sync_synchronize:
3474 case Builtin::BI__builtin_nontemporal_load:
3475 case Builtin::BI__builtin_nontemporal_store:
3476 return BuiltinNontemporalOverloaded(TheCallResult);
3477 case Builtin::BI__builtin_memcpy_inline: {
3478 clang::Expr *SizeOp = TheCall->
getArg(2);
3490 case Builtin::BI__builtin_memset_inline: {
3491 clang::Expr *SizeOp = TheCall->
getArg(2);
3501#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3502 case Builtin::BI##ID: \
3503 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3504#include "clang/Basic/Builtins.inc"
3505 case Builtin::BI__annotation: {
3506 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3507 if (!TT.isOSWindows() && !TT.isUEFI()) {
3516 case Builtin::BI__builtin_annotation:
3520 case Builtin::BI__builtin_addressof:
3524 case Builtin::BI__builtin_function_start:
3528 case Builtin::BI__builtin_is_aligned:
3529 case Builtin::BI__builtin_align_up:
3530 case Builtin::BI__builtin_align_down:
3534 case Builtin::BI__builtin_add_overflow:
3535 case Builtin::BI__builtin_sub_overflow:
3536 case Builtin::BI__builtin_mul_overflow:
3540 case Builtin::BI__builtin_operator_new:
3541 case Builtin::BI__builtin_operator_delete: {
3542 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3544 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3547 case Builtin::BI__builtin_dump_struct:
3549 case Builtin::BI__builtin_expect_with_probability: {
3554 const Expr *ProbArg = TheCall->
getArg(2);
3555 SmallVector<PartialDiagnosticAt, 8> Notes;
3556 Expr::EvalResult Eval;
3560 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3567 bool LoseInfo =
false;
3568 Probability.convert(llvm::APFloat::IEEEdouble(),
3569 llvm::RoundingMode::Dynamic, &LoseInfo);
3570 if (!(Probability >= llvm::APFloat(0.0) &&
3571 Probability <= llvm::APFloat(1.0))) {
3578 case Builtin::BI__builtin_preserve_access_index:
3582 case Builtin::BI__builtin_call_with_static_chain:
3586 case Builtin::BI__exception_code:
3587 case Builtin::BI_exception_code:
3589 diag::err_seh___except_block))
3592 case Builtin::BI__exception_info:
3593 case Builtin::BI_exception_info:
3595 diag::err_seh___except_filter))
3598 case Builtin::BI__GetExceptionInfo:
3610 case Builtin::BIaddressof:
3611 case Builtin::BI__addressof:
3612 case Builtin::BIforward:
3613 case Builtin::BIforward_like:
3614 case Builtin::BImove:
3615 case Builtin::BImove_if_noexcept:
3616 case Builtin::BIas_const: {
3624 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3625 BuiltinID == Builtin::BI__addressof;
3627 (ReturnsPointer ?
Result->isAnyPointerType()
3628 :
Result->isReferenceType()) &&
3631 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3637 case Builtin::BI__builtin_ptrauth_strip:
3639 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3641 case Builtin::BI__builtin_ptrauth_sign_constant:
3644 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3647 case Builtin::BI__builtin_ptrauth_auth:
3650 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3652 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3654 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3656 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3658 case Builtin::BI__builtin_ptrauth_string_discriminator:
3661 case Builtin::BI__builtin_get_vtable_pointer:
3665 case Builtin::BIread_pipe:
3666 case Builtin::BIwrite_pipe:
3669 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3672 case Builtin::BIreserve_read_pipe:
3673 case Builtin::BIreserve_write_pipe:
3674 case Builtin::BIwork_group_reserve_read_pipe:
3675 case Builtin::BIwork_group_reserve_write_pipe:
3676 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3679 case Builtin::BIsub_group_reserve_read_pipe:
3680 case Builtin::BIsub_group_reserve_write_pipe:
3681 if (
OpenCL().checkSubgroupExt(TheCall) ||
3682 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3685 case Builtin::BIcommit_read_pipe:
3686 case Builtin::BIcommit_write_pipe:
3687 case Builtin::BIwork_group_commit_read_pipe:
3688 case Builtin::BIwork_group_commit_write_pipe:
3689 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3692 case Builtin::BIsub_group_commit_read_pipe:
3693 case Builtin::BIsub_group_commit_write_pipe:
3694 if (
OpenCL().checkSubgroupExt(TheCall) ||
3695 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3698 case Builtin::BIget_pipe_num_packets:
3699 case Builtin::BIget_pipe_max_packets:
3700 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3703 case Builtin::BIto_global:
3704 case Builtin::BIto_local:
3705 case Builtin::BIto_private:
3706 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3710 case Builtin::BIenqueue_kernel:
3711 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3714 case Builtin::BIget_kernel_work_group_size:
3715 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3716 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3719 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3720 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3721 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3724 case Builtin::BI__builtin_os_log_format:
3725 Cleanup.setExprNeedsCleanups(
true);
3727 case Builtin::BI__builtin_os_log_format_buffer_size:
3728 if (BuiltinOSLogFormat(TheCall))
3731 case Builtin::BI__builtin_frame_address:
3732 case Builtin::BI__builtin_return_address: {
3741 Result.Val.getInt() != 0)
3743 << ((BuiltinID == Builtin::BI__builtin_return_address)
3744 ?
"__builtin_return_address"
3745 :
"__builtin_frame_address")
3750 case Builtin::BI__builtin_nondeterministic_value: {
3751 if (BuiltinNonDeterministicValue(TheCall))
3758 case Builtin::BI__builtin_elementwise_abs:
3766 case Builtin::BI__builtin_elementwise_acos:
3767 case Builtin::BI__builtin_elementwise_asin:
3768 case Builtin::BI__builtin_elementwise_atan:
3769 case Builtin::BI__builtin_elementwise_ceil:
3770 case Builtin::BI__builtin_elementwise_cos:
3771 case Builtin::BI__builtin_elementwise_cosh:
3772 case Builtin::BI__builtin_elementwise_exp:
3773 case Builtin::BI__builtin_elementwise_exp2:
3774 case Builtin::BI__builtin_elementwise_exp10:
3775 case Builtin::BI__builtin_elementwise_floor:
3776 case Builtin::BI__builtin_elementwise_log:
3777 case Builtin::BI__builtin_elementwise_log2:
3778 case Builtin::BI__builtin_elementwise_log10:
3779 case Builtin::BI__builtin_elementwise_roundeven:
3780 case Builtin::BI__builtin_elementwise_round:
3781 case Builtin::BI__builtin_elementwise_rint:
3782 case Builtin::BI__builtin_elementwise_nearbyint:
3783 case Builtin::BI__builtin_elementwise_sin:
3784 case Builtin::BI__builtin_elementwise_sinh:
3785 case Builtin::BI__builtin_elementwise_sqrt:
3786 case Builtin::BI__builtin_elementwise_tan:
3787 case Builtin::BI__builtin_elementwise_tanh:
3788 case Builtin::BI__builtin_elementwise_trunc:
3789 case Builtin::BI__builtin_elementwise_canonicalize:
3794 case Builtin::BI__builtin_elementwise_fma:
3799 case Builtin::BI__builtin_elementwise_ldexp: {
3821 const auto *Vec0 = TyA->
getAs<VectorType>();
3822 const auto *Vec1 = TyExp->
getAs<VectorType>();
3823 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3825 if (Arg0Length != Arg1Length) {
3827 diag::err_typecheck_vector_lengths_not_equal)
3841 case Builtin::BI__builtin_elementwise_minnum:
3842 case Builtin::BI__builtin_elementwise_maxnum:
3843 case Builtin::BI__builtin_elementwise_minimum:
3844 case Builtin::BI__builtin_elementwise_maximum:
3845 case Builtin::BI__builtin_elementwise_minimumnum:
3846 case Builtin::BI__builtin_elementwise_maximumnum:
3847 case Builtin::BI__builtin_elementwise_atan2:
3848 case Builtin::BI__builtin_elementwise_fmod:
3849 case Builtin::BI__builtin_elementwise_pow:
3850 if (BuiltinElementwiseMath(TheCall,
3856 case Builtin::BI__builtin_elementwise_add_sat:
3857 case Builtin::BI__builtin_elementwise_sub_sat:
3858 case Builtin::BI__builtin_elementwise_clmul:
3859 case Builtin::BI__builtin_elementwise_pext:
3860 case Builtin::BI__builtin_elementwise_pdep:
3861 if (BuiltinElementwiseMath(TheCall,
3865 case Builtin::BI__builtin_elementwise_fshl:
3866 case Builtin::BI__builtin_elementwise_fshr:
3871 case Builtin::BI__builtin_elementwise_min:
3872 case Builtin::BI__builtin_elementwise_max: {
3873 if (BuiltinElementwiseMath(TheCall))
3875 Expr *Arg0 = TheCall->
getArg(0);
3876 Expr *Arg1 = TheCall->
getArg(1);
3877 QualType Ty0 = Arg0->
getType();
3878 QualType Ty1 = Arg1->
getType();
3879 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3880 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3883 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3884 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3885 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3888 case Builtin::BI__builtin_elementwise_popcount:
3889 case Builtin::BI__builtin_elementwise_bitreverse:
3894 case Builtin::BI__builtin_elementwise_copysign: {
3903 QualType MagnitudeTy = Magnitude.
get()->
getType();
3916 diag::err_typecheck_call_different_arg_types)
3917 << MagnitudeTy << SignTy;
3925 case Builtin::BI__builtin_elementwise_clzg:
3926 case Builtin::BI__builtin_elementwise_ctzg:
3934 }
else if (BuiltinElementwiseMath(
3938 case Builtin::BI__builtin_reduce_max:
3939 case Builtin::BI__builtin_reduce_min: {
3940 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3943 const Expr *Arg = TheCall->
getArg(0);
3948 ElTy = TyA->getElementType();
3952 if (ElTy.isNull()) {
3962 case Builtin::BI__builtin_reduce_maximum:
3963 case Builtin::BI__builtin_reduce_minimum: {
3964 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3967 const Expr *Arg = TheCall->
getArg(0);
3972 ElTy = TyA->getElementType();
3976 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3989 case Builtin::BI__builtin_reduce_add:
3990 case Builtin::BI__builtin_reduce_mul:
3991 case Builtin::BI__builtin_reduce_xor:
3992 case Builtin::BI__builtin_reduce_or:
3993 case Builtin::BI__builtin_reduce_and: {
3994 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3997 const Expr *Arg = TheCall->
getArg(0);
4011 case Builtin::BI__builtin_reduce_assoc_fadd:
4012 case Builtin::BI__builtin_reduce_in_order_fadd: {
4014 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4039 diag::err_builtin_invalid_arg_type)
4051 case Builtin::BI__builtin_matrix_transpose:
4052 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4054 case Builtin::BI__builtin_matrix_column_major_load:
4055 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4057 case Builtin::BI__builtin_matrix_column_major_store:
4058 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4060 case Builtin::BI__builtin_verbose_trap:
4065 case Builtin::BI__builtin_get_device_side_mangled_name: {
4066 auto Check = [](CallExpr *TheCall) {
4072 auto *D = DRE->getDecl();
4075 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4076 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4078 if (!Check(TheCall)) {
4080 diag::err_hip_invalid_args_builtin_mangled_name);
4085 case Builtin::BI__builtin_bswapg:
4089 case Builtin::BI__builtin_bitreverseg:
4093 case Builtin::BI__builtin_popcountg:
4097 case Builtin::BI__builtin_clzg:
4098 case Builtin::BI__builtin_ctzg:
4103 case Builtin::BI__builtin_stdc_rotate_left:
4104 case Builtin::BI__builtin_stdc_rotate_right:
4109 case Builtin::BI__builtin_stdc_memreverse8:
4110 case Builtin::BIstdc_memreverse8:
4111 case Builtin::BIstdc_memreverse8u8:
4112 case Builtin::BIstdc_memreverse8u16:
4113 case Builtin::BIstdc_memreverse8u32:
4114 case Builtin::BIstdc_memreverse8u64:
4115 if (
Context.getTargetInfo().getCharWidth() != 8) {
4122 case Builtin::BI__builtin_stdc_bit_floor:
4123 case Builtin::BI__builtin_stdc_bit_ceil:
4127 case Builtin::BI__builtin_stdc_has_single_bit:
4131 case Builtin::BI__builtin_stdc_leading_zeros:
4132 case Builtin::BI__builtin_stdc_leading_ones:
4133 case Builtin::BI__builtin_stdc_trailing_zeros:
4134 case Builtin::BI__builtin_stdc_trailing_ones:
4135 case Builtin::BI__builtin_stdc_first_leading_zero:
4136 case Builtin::BI__builtin_stdc_first_leading_one:
4137 case Builtin::BI__builtin_stdc_first_trailing_zero:
4138 case Builtin::BI__builtin_stdc_first_trailing_one:
4139 case Builtin::BI__builtin_stdc_count_zeros:
4140 case Builtin::BI__builtin_stdc_count_ones:
4141 case Builtin::BI__builtin_stdc_bit_width:
4146 case Builtin::BI__builtin_allow_runtime_check: {
4147 Expr *Arg = TheCall->
getArg(0);
4157 case Builtin::BI__builtin_allow_sanitize_check: {
4161 Expr *Arg = TheCall->
getArg(0);
4163 const StringLiteral *SanitizerName =
4165 if (!SanitizerName) {
4171 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4172 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4173 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4177 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4183 case Builtin::BI__builtin_counted_by_ref:
4184 if (BuiltinCountedByRef(TheCall))
4194 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4195 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4196 assert(
Context.getAuxTargetInfo() &&
4197 "Aux Target Builtin, but not an aux target?");
4199 if (CheckTSBuiltinFunctionCall(
4201 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4204 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4210 return TheCallResult;
4225 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4229 diag::err_argument_not_contiguous_bit_field)
4236 bool IsVariadic =
false;
4239 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4240 IsVariadic = BD->isVariadic();
4241 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4242 IsVariadic = OMD->isVariadic();
4249 bool HasImplicitThisParam,
bool IsVariadic,
4253 else if (IsVariadic)
4263 if (HasImplicitThisParam) {
4295 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4296 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4297 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4298 Expr = ILE->getInit(0);
4308 const Expr *ArgExpr,
4312 S.
PDiag(diag::warn_null_arg)
4318 if (
auto nullability =
type->getNullability())
4329 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4335 llvm::SmallBitVector NonNullArgs;
4341 for (
const auto *Arg : Args)
4348 unsigned IdxAST = Idx.getASTIndex();
4349 if (IdxAST >= Args.size())
4351 if (NonNullArgs.empty())
4352 NonNullArgs.resize(Args.size());
4353 NonNullArgs.set(IdxAST);
4362 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4367 unsigned ParamIndex = 0;
4369 I != E; ++I, ++ParamIndex) {
4372 if (NonNullArgs.empty())
4373 NonNullArgs.resize(Args.size());
4375 NonNullArgs.set(ParamIndex);
4382 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4387 type = blockType->getPointeeType();
4401 if (NonNullArgs.empty())
4402 NonNullArgs.resize(Args.size());
4404 NonNullArgs.set(Index);
4413 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4414 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4415 if (NonNullArgs[ArgIndex])
4421 StringRef ParamName,
QualType ArgTy,
4444 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4445 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4449 if (ArgAlign < ParamAlign)
4450 Diag(Loc, diag::warn_param_mismatched_alignment)
4452 << ParamName << (FDecl !=
nullptr) << FDecl;
4456 const Expr *ThisArg,
4458 if (!FD || Args.empty())
4460 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4461 if (Idx == LifetimeCaptureByAttr::Global ||
4462 Idx == LifetimeCaptureByAttr::Unknown)
4464 if (IsMemberFunction && Idx == 0)
4466 return Args[Idx - IsMemberFunction];
4468 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4473 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4474 for (
int CapturingParamIdx :
Attr->params()) {
4475 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4479 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4482 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4489 for (
const auto *A :
4491 HandleCaptureByAttr(A, I + IsMemberFunction);
4493 if (IsMemberFunction) {
4501 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4511 llvm::any_of(Args, [](
const Expr *E) {
4512 return E && E->isInstantiationDependent();
4517 llvm::SmallBitVector CheckedVarArgs;
4519 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4521 CheckedVarArgs.resize(Args.size());
4522 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4527 CheckedVarArgs.resize(Args.size());
4528 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4535 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4539 : isa_and_nonnull<FunctionDecl>(FDecl)
4541 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4545 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4547 if (
const Expr *Arg = Args[ArgIdx]) {
4548 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4555 if (FDecl || Proto) {
4560 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4561 CheckArgumentWithTypeTag(I, Args, Loc);
4567 if (!Proto && FDecl) {
4569 if (isa_and_nonnull<FunctionProtoType>(FT))
4575 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4577 bool IsScalableArg =
false;
4578 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4580 if (
const Expr *Arg = Args[ArgIdx]) {
4584 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4592 IsScalableArg =
true;
4594 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4603 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4604 llvm::StringMap<bool> CallerFeatureMap;
4605 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4606 if (!CallerFeatureMap.contains(
"sme"))
4607 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4608 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4609 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4618 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4620 (IsScalableArg || IsScalableRet)) {
4621 bool IsCalleeStreaming =
4623 bool IsCalleeStreamingCompatible =
4627 if (!IsCalleeStreamingCompatible &&
4631 unsigned VL = LO.VScaleMin * 128;
4632 unsigned SVL = LO.VScaleStreamingMin * 128;
4633 bool IsVLMismatch = VL && SVL && VL != SVL;
4635 auto EmitDiag = [&](
bool IsArg) {
4639 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4640 << IsArg << IsCalleeStreaming << SVL << VL;
4643 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4644 << IsArg << SVL << VL;
4646 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4663 bool CallerHasZAState =
false;
4664 bool CallerHasZT0State =
false;
4666 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4668 CallerHasZAState =
true;
4670 CallerHasZT0State =
true;
4674 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4676 CallerHasZT0State |=
4678 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4684 Diag(Loc, diag::err_sme_za_call_no_za_state);
4687 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4691 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4692 Diag(Loc, diag::note_sme_use_preserves_za);
4697 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4698 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4699 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4700 if (!Arg->isValueDependent()) {
4702 if (Arg->EvaluateAsInt(Align,
Context)) {
4703 const llvm::APSInt &I = Align.
Val.
getInt();
4704 if (!I.isPowerOf2())
4705 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4706 << Arg->getSourceRange();
4709 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4718 << diag::OffloadLang::SYCL;
4740 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4741 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4743 checkCall(FDecl, Proto,
nullptr, Args,
true,
4752 IsMemberOperatorCall;
4758 Expr *ImplicitThis =
nullptr;
4763 ImplicitThis = Args[0];
4766 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4777 ThisType =
Context.getPointerType(ThisType);
4783 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4801 CheckAbsoluteValueFunction(TheCall, FDecl);
4802 CheckMaxUnsignedZero(TheCall, FDecl);
4803 CheckInfNaNFunction(TheCall, FDecl);
4814 case Builtin::BIstrlcpy:
4815 case Builtin::BIstrlcat:
4816 CheckStrlcpycatArguments(TheCall, FnInfo);
4818 case Builtin::BIstrncat:
4819 CheckStrncatArguments(TheCall, FnInfo);
4821 case Builtin::BIfree:
4822 CheckFreeArguments(TheCall);
4825 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4834 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4835 Ty =
V->getType().getNonReferenceType();
4836 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4837 Ty = F->getType().getNonReferenceType();
4874 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4877 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4879 case AtomicExpr::AO__c11_atomic_init:
4880 case AtomicExpr::AO__opencl_atomic_init:
4881 llvm_unreachable(
"There is no ordering argument for an init");
4883 case AtomicExpr::AO__c11_atomic_load:
4884 case AtomicExpr::AO__opencl_atomic_load:
4885 case AtomicExpr::AO__hip_atomic_load:
4886 case AtomicExpr::AO__atomic_load_n:
4887 case AtomicExpr::AO__atomic_load:
4888 case AtomicExpr::AO__scoped_atomic_load_n:
4889 case AtomicExpr::AO__scoped_atomic_load:
4890 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4891 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4893 case AtomicExpr::AO__c11_atomic_store:
4894 case AtomicExpr::AO__opencl_atomic_store:
4895 case AtomicExpr::AO__hip_atomic_store:
4896 case AtomicExpr::AO__atomic_store:
4897 case AtomicExpr::AO__atomic_store_n:
4898 case AtomicExpr::AO__scoped_atomic_store:
4899 case AtomicExpr::AO__scoped_atomic_store_n:
4900 case AtomicExpr::AO__atomic_clear:
4901 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4902 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4903 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4933#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4934 case AtomicExpr::AO__hip_atomic_##hip: \
4935 OldName = "__hip_atomic_" #hip; \
4936 NewName = "__scoped_atomic_" #scoped; \
4949#undef HIP_ATOMIC_FIXABLE
4950 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4951 OldName =
"__hip_atomic_compare_exchange_weak";
4952 NewName =
"__scoped_atomic_compare_exchange";
4955 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4956 OldName =
"__hip_atomic_compare_exchange_strong";
4957 NewName =
"__scoped_atomic_compare_exchange";
4961 llvm_unreachable(
"unhandled HIP atomic op");
4964 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4965 << OldName << NewName;
4972 std::optional<llvm::APSInt> ScopeVal =
4977 StringRef ScopeName;
4978 switch (ScopeVal->getZExtValue()) {
4980 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4983 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4986 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4989 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4992 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4995 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5047 const unsigned NumForm = ClearByte + 1;
5048 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5049 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5057 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5058 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5059 "need to update code for modified forms");
5060 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5061 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5062 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5063 "need to update code for modified C11 atomics");
5064 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5065 Op <= AtomicExpr::AO__opencl_atomic_store;
5066 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5067 Op <= AtomicExpr::AO__hip_atomic_store;
5068 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5069 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5070 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5071 Op <= AtomicExpr::AO__c11_atomic_store) ||
5073 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5074 Op == AtomicExpr::AO__atomic_store_n ||
5075 Op == AtomicExpr::AO__atomic_exchange_n ||
5076 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5077 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5078 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5079 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5080 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5084 enum ArithOpExtraValueType {
5090 unsigned ArithAllows = AOEVT_None;
5093 case AtomicExpr::AO__c11_atomic_init:
5094 case AtomicExpr::AO__opencl_atomic_init:
5098 case AtomicExpr::AO__c11_atomic_load:
5099 case AtomicExpr::AO__opencl_atomic_load:
5100 case AtomicExpr::AO__hip_atomic_load:
5101 case AtomicExpr::AO__atomic_load_n:
5102 case AtomicExpr::AO__scoped_atomic_load_n:
5103 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5107 case AtomicExpr::AO__atomic_load:
5108 case AtomicExpr::AO__scoped_atomic_load:
5109 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5113 case AtomicExpr::AO__c11_atomic_store:
5114 case AtomicExpr::AO__opencl_atomic_store:
5115 case AtomicExpr::AO__hip_atomic_store:
5116 case AtomicExpr::AO__atomic_store:
5117 case AtomicExpr::AO__atomic_store_n:
5118 case AtomicExpr::AO__scoped_atomic_store:
5119 case AtomicExpr::AO__scoped_atomic_store_n:
5120 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5123 case AtomicExpr::AO__atomic_fetch_add:
5124 case AtomicExpr::AO__atomic_fetch_sub:
5125 case AtomicExpr::AO__atomic_add_fetch:
5126 case AtomicExpr::AO__atomic_sub_fetch:
5127 case AtomicExpr::AO__scoped_atomic_fetch_add:
5128 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5129 case AtomicExpr::AO__scoped_atomic_add_fetch:
5130 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5131 case AtomicExpr::AO__c11_atomic_fetch_add:
5132 case AtomicExpr::AO__c11_atomic_fetch_sub:
5133 case AtomicExpr::AO__opencl_atomic_fetch_add:
5134 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5135 case AtomicExpr::AO__hip_atomic_fetch_add:
5136 case AtomicExpr::AO__hip_atomic_fetch_sub:
5137 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5140 case AtomicExpr::AO__atomic_fetch_fminimum:
5141 case AtomicExpr::AO__atomic_fetch_fmaximum:
5142 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5143 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5144 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5145 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5146 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5147 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5148 ArithAllows = AOEVT_FP;
5151 case AtomicExpr::AO__atomic_fetch_max:
5152 case AtomicExpr::AO__atomic_fetch_min:
5153 case AtomicExpr::AO__atomic_max_fetch:
5154 case AtomicExpr::AO__atomic_min_fetch:
5155 case AtomicExpr::AO__scoped_atomic_fetch_max:
5156 case AtomicExpr::AO__scoped_atomic_fetch_min:
5157 case AtomicExpr::AO__scoped_atomic_max_fetch:
5158 case AtomicExpr::AO__scoped_atomic_min_fetch:
5159 case AtomicExpr::AO__c11_atomic_fetch_max:
5160 case AtomicExpr::AO__c11_atomic_fetch_min:
5161 case AtomicExpr::AO__opencl_atomic_fetch_max:
5162 case AtomicExpr::AO__opencl_atomic_fetch_min:
5163 case AtomicExpr::AO__hip_atomic_fetch_max:
5164 case AtomicExpr::AO__hip_atomic_fetch_min:
5165 ArithAllows = AOEVT_Int | AOEVT_FP;
5168 case AtomicExpr::AO__c11_atomic_fetch_and:
5169 case AtomicExpr::AO__c11_atomic_fetch_or:
5170 case AtomicExpr::AO__c11_atomic_fetch_xor:
5171 case AtomicExpr::AO__hip_atomic_fetch_and:
5172 case AtomicExpr::AO__hip_atomic_fetch_or:
5173 case AtomicExpr::AO__hip_atomic_fetch_xor:
5174 case AtomicExpr::AO__c11_atomic_fetch_nand:
5175 case AtomicExpr::AO__opencl_atomic_fetch_and:
5176 case AtomicExpr::AO__opencl_atomic_fetch_or:
5177 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5178 case AtomicExpr::AO__atomic_fetch_and:
5179 case AtomicExpr::AO__atomic_fetch_or:
5180 case AtomicExpr::AO__atomic_fetch_xor:
5181 case AtomicExpr::AO__atomic_fetch_nand:
5182 case AtomicExpr::AO__atomic_and_fetch:
5183 case AtomicExpr::AO__atomic_or_fetch:
5184 case AtomicExpr::AO__atomic_xor_fetch:
5185 case AtomicExpr::AO__atomic_nand_fetch:
5186 case AtomicExpr::AO__atomic_fetch_uinc:
5187 case AtomicExpr::AO__atomic_fetch_udec:
5188 case AtomicExpr::AO__scoped_atomic_fetch_and:
5189 case AtomicExpr::AO__scoped_atomic_fetch_or:
5190 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5191 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5192 case AtomicExpr::AO__scoped_atomic_and_fetch:
5193 case AtomicExpr::AO__scoped_atomic_or_fetch:
5194 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5195 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5196 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5197 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5201 case AtomicExpr::AO__c11_atomic_exchange:
5202 case AtomicExpr::AO__hip_atomic_exchange:
5203 case AtomicExpr::AO__opencl_atomic_exchange:
5204 case AtomicExpr::AO__atomic_exchange_n:
5205 case AtomicExpr::AO__scoped_atomic_exchange_n:
5206 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5210 case AtomicExpr::AO__atomic_exchange:
5211 case AtomicExpr::AO__scoped_atomic_exchange:
5212 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5216 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5217 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5218 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5219 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5220 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5221 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5225 case AtomicExpr::AO__atomic_compare_exchange:
5226 case AtomicExpr::AO__atomic_compare_exchange_n:
5227 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5228 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5229 ArithAllows = AOEVT_Pointer;
5233 case AtomicExpr::AO__atomic_test_and_set:
5234 Form = TestAndSetByte;
5237 case AtomicExpr::AO__atomic_clear:
5242 unsigned AdjustedNumArgs = NumArgs[Form];
5243 if ((IsOpenCL || IsHIP || IsScoped) &&
5244 Op != AtomicExpr::AO__opencl_atomic_init)
5247 if (Args.size() < AdjustedNumArgs) {
5248 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5249 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5252 }
else if (Args.size() > AdjustedNumArgs) {
5253 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5254 diag::err_typecheck_call_too_many_args)
5255 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5261 Expr *Ptr = Args[0];
5266 Ptr = ConvertedPtr.
get();
5269 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5279 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5285 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5291 }
else if (Form != Load && Form != LoadCopy) {
5293 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5299 if (Form != TestAndSetByte && Form != ClearByte) {
5302 diag::err_incomplete_type))
5305 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5306 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5316 pointerType->getPointeeType().getCVRQualifiers());
5326 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5336 auto IsAllowedValueType = [&](
QualType ValType,
5337 unsigned AllowedType) ->
bool {
5338 bool IsX87LongDouble =
5340 &
Context.getTargetInfo().getLongDoubleFormat() ==
5341 &llvm::APFloat::x87DoubleExtended();
5345 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5347 return AllowedType & AOEVT_Pointer;
5351 if (IsX87LongDouble)
5355 if (!IsAllowedValueType(ValType, ArithAllows)) {
5357 ArithAllows == AOEVT_FP
5358 ? diag::err_atomic_op_needs_atomic_fp
5359 : (ArithAllows & AOEVT_FP
5360 ? (ArithAllows & AOEVT_Pointer
5361 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5362 : diag::err_atomic_op_needs_atomic_int_or_fp)
5363 : (ArithAllows & AOEVT_Pointer
5364 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5365 : diag::err_atomic_op_needs_atomic_int));
5372 diag::err_incomplete_type)) {
5383 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5399 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5411 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5414 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5420 bool IsPassedByAddress =
false;
5421 if (!IsC11 && !IsHIP && !IsN) {
5423 IsPassedByAddress =
true;
5428 APIOrderedArgs.push_back(Args[0]);
5432 APIOrderedArgs.push_back(Args[1]);
5438 APIOrderedArgs.push_back(Args[2]);
5439 APIOrderedArgs.push_back(Args[1]);
5442 APIOrderedArgs.push_back(Args[2]);
5443 APIOrderedArgs.push_back(Args[3]);
5444 APIOrderedArgs.push_back(Args[1]);
5447 APIOrderedArgs.push_back(Args[2]);
5448 APIOrderedArgs.push_back(Args[4]);
5449 APIOrderedArgs.push_back(Args[1]);
5450 APIOrderedArgs.push_back(Args[3]);
5453 APIOrderedArgs.push_back(Args[2]);
5454 APIOrderedArgs.push_back(Args[4]);
5455 APIOrderedArgs.push_back(Args[5]);
5456 APIOrderedArgs.push_back(Args[1]);
5457 APIOrderedArgs.push_back(Args[3]);
5459 case TestAndSetByte:
5461 APIOrderedArgs.push_back(Args[1]);
5465 APIOrderedArgs.append(Args.begin(), Args.end());
5472 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5474 if (i < NumVals[Form] + 1) {
5487 assert(Form != Load);
5489 Ty =
Context.getPointerDiffType();
5492 else if (Form ==
Copy || Form == Xchg) {
5493 if (IsPassedByAddress) {
5500 Expr *ValArg = APIOrderedArgs[i];
5507 AS = PtrTy->getPointeeType().getAddressSpace();
5516 if (IsPassedByAddress)
5536 APIOrderedArgs[i] = Arg.
get();
5541 SubExprs.push_back(Ptr);
5545 SubExprs.push_back(APIOrderedArgs[1]);
5548 case TestAndSetByte:
5550 SubExprs.push_back(APIOrderedArgs[1]);
5556 SubExprs.push_back(APIOrderedArgs[2]);
5557 SubExprs.push_back(APIOrderedArgs[1]);
5561 SubExprs.push_back(APIOrderedArgs[3]);
5562 SubExprs.push_back(APIOrderedArgs[1]);
5563 SubExprs.push_back(APIOrderedArgs[2]);
5566 SubExprs.push_back(APIOrderedArgs[3]);
5567 SubExprs.push_back(APIOrderedArgs[1]);
5568 SubExprs.push_back(APIOrderedArgs[4]);
5569 SubExprs.push_back(APIOrderedArgs[2]);
5572 SubExprs.push_back(APIOrderedArgs[4]);
5573 SubExprs.push_back(APIOrderedArgs[1]);
5574 SubExprs.push_back(APIOrderedArgs[5]);
5575 SubExprs.push_back(APIOrderedArgs[2]);
5576 SubExprs.push_back(APIOrderedArgs[3]);
5581 if (SubExprs.size() >= 2 && Form !=
Init) {
5582 std::optional<llvm::APSInt>
Success =
5583 SubExprs[1]->getIntegerConstantExpr(
Context);
5585 Diag(SubExprs[1]->getBeginLoc(),
5586 diag::warn_atomic_op_has_invalid_memory_order)
5587 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5588 << SubExprs[1]->getSourceRange();
5590 if (SubExprs.size() >= 5) {
5591 if (std::optional<llvm::APSInt>
Failure =
5592 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5593 if (!llvm::is_contained(
5594 {llvm::AtomicOrderingCABI::relaxed,
5595 llvm::AtomicOrderingCABI::consume,
5596 llvm::AtomicOrderingCABI::acquire,
5597 llvm::AtomicOrderingCABI::seq_cst},
5598 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5599 Diag(SubExprs[3]->getBeginLoc(),
5600 diag::warn_atomic_op_has_invalid_memory_order)
5601 << 2 << SubExprs[3]->getSourceRange();
5608 auto *
Scope = Args[Args.size() - 1];
5609 if (std::optional<llvm::APSInt>
Result =
5611 if (!ScopeModel->isValid(
Result->getZExtValue()))
5612 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5613 <<
Scope->getSourceRange();
5615 SubExprs.push_back(
Scope);
5624 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5625 Op == AtomicExpr::AO__c11_atomic_store ||
5626 Op == AtomicExpr::AO__opencl_atomic_load ||
5627 Op == AtomicExpr::AO__hip_atomic_load ||
5628 Op == AtomicExpr::AO__opencl_atomic_store ||
5629 Op == AtomicExpr::AO__hip_atomic_store) &&
5630 Context.AtomicUsesUnsupportedLibcall(AE))
5632 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5633 Op == AtomicExpr::AO__opencl_atomic_load ||
5634 Op == AtomicExpr::AO__hip_atomic_load)
5639 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5655 assert(Fn &&
"builtin call without direct callee!");
5671 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5678 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5680 <<
Callee->getSourceRange();
5689 Expr *FirstArg = TheCall->
getArg(0);
5693 FirstArg = FirstArgResult.
get();
5694 TheCall->
setArg(0, FirstArg);
5706 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5713 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5743 QualType ResultType = ValType;
5748#define BUILTIN_ROW(x) \
5749 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5750 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5752 static const unsigned BuiltinIndices[][5] = {
5777 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5778 case 1: SizeIndex = 0;
break;
5779 case 2: SizeIndex = 1;
break;
5780 case 4: SizeIndex = 2;
break;
5781 case 8: SizeIndex = 3;
break;
5782 case 16: SizeIndex = 4;
break;
5794 unsigned BuiltinIndex, NumFixed = 1;
5795 bool WarnAboutSemanticsChange =
false;
5796 switch (BuiltinID) {
5797 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5798 case Builtin::BI__sync_fetch_and_add:
5799 case Builtin::BI__sync_fetch_and_add_1:
5800 case Builtin::BI__sync_fetch_and_add_2:
5801 case Builtin::BI__sync_fetch_and_add_4:
5802 case Builtin::BI__sync_fetch_and_add_8:
5803 case Builtin::BI__sync_fetch_and_add_16:
5807 case Builtin::BI__sync_fetch_and_sub:
5808 case Builtin::BI__sync_fetch_and_sub_1:
5809 case Builtin::BI__sync_fetch_and_sub_2:
5810 case Builtin::BI__sync_fetch_and_sub_4:
5811 case Builtin::BI__sync_fetch_and_sub_8:
5812 case Builtin::BI__sync_fetch_and_sub_16:
5816 case Builtin::BI__sync_fetch_and_or:
5817 case Builtin::BI__sync_fetch_and_or_1:
5818 case Builtin::BI__sync_fetch_and_or_2:
5819 case Builtin::BI__sync_fetch_and_or_4:
5820 case Builtin::BI__sync_fetch_and_or_8:
5821 case Builtin::BI__sync_fetch_and_or_16:
5825 case Builtin::BI__sync_fetch_and_and:
5826 case Builtin::BI__sync_fetch_and_and_1:
5827 case Builtin::BI__sync_fetch_and_and_2:
5828 case Builtin::BI__sync_fetch_and_and_4:
5829 case Builtin::BI__sync_fetch_and_and_8:
5830 case Builtin::BI__sync_fetch_and_and_16:
5834 case Builtin::BI__sync_fetch_and_xor:
5835 case Builtin::BI__sync_fetch_and_xor_1:
5836 case Builtin::BI__sync_fetch_and_xor_2:
5837 case Builtin::BI__sync_fetch_and_xor_4:
5838 case Builtin::BI__sync_fetch_and_xor_8:
5839 case Builtin::BI__sync_fetch_and_xor_16:
5843 case Builtin::BI__sync_fetch_and_nand:
5844 case Builtin::BI__sync_fetch_and_nand_1:
5845 case Builtin::BI__sync_fetch_and_nand_2:
5846 case Builtin::BI__sync_fetch_and_nand_4:
5847 case Builtin::BI__sync_fetch_and_nand_8:
5848 case Builtin::BI__sync_fetch_and_nand_16:
5850 WarnAboutSemanticsChange =
true;
5853 case Builtin::BI__sync_add_and_fetch:
5854 case Builtin::BI__sync_add_and_fetch_1:
5855 case Builtin::BI__sync_add_and_fetch_2:
5856 case Builtin::BI__sync_add_and_fetch_4:
5857 case Builtin::BI__sync_add_and_fetch_8:
5858 case Builtin::BI__sync_add_and_fetch_16:
5862 case Builtin::BI__sync_sub_and_fetch:
5863 case Builtin::BI__sync_sub_and_fetch_1:
5864 case Builtin::BI__sync_sub_and_fetch_2:
5865 case Builtin::BI__sync_sub_and_fetch_4:
5866 case Builtin::BI__sync_sub_and_fetch_8:
5867 case Builtin::BI__sync_sub_and_fetch_16:
5871 case Builtin::BI__sync_and_and_fetch:
5872 case Builtin::BI__sync_and_and_fetch_1:
5873 case Builtin::BI__sync_and_and_fetch_2:
5874 case Builtin::BI__sync_and_and_fetch_4:
5875 case Builtin::BI__sync_and_and_fetch_8:
5876 case Builtin::BI__sync_and_and_fetch_16:
5880 case Builtin::BI__sync_or_and_fetch:
5881 case Builtin::BI__sync_or_and_fetch_1:
5882 case Builtin::BI__sync_or_and_fetch_2:
5883 case Builtin::BI__sync_or_and_fetch_4:
5884 case Builtin::BI__sync_or_and_fetch_8:
5885 case Builtin::BI__sync_or_and_fetch_16:
5889 case Builtin::BI__sync_xor_and_fetch:
5890 case Builtin::BI__sync_xor_and_fetch_1:
5891 case Builtin::BI__sync_xor_and_fetch_2:
5892 case Builtin::BI__sync_xor_and_fetch_4:
5893 case Builtin::BI__sync_xor_and_fetch_8:
5894 case Builtin::BI__sync_xor_and_fetch_16:
5898 case Builtin::BI__sync_nand_and_fetch:
5899 case Builtin::BI__sync_nand_and_fetch_1:
5900 case Builtin::BI__sync_nand_and_fetch_2:
5901 case Builtin::BI__sync_nand_and_fetch_4:
5902 case Builtin::BI__sync_nand_and_fetch_8:
5903 case Builtin::BI__sync_nand_and_fetch_16:
5905 WarnAboutSemanticsChange =
true;
5908 case Builtin::BI__sync_val_compare_and_swap:
5909 case Builtin::BI__sync_val_compare_and_swap_1:
5910 case Builtin::BI__sync_val_compare_and_swap_2:
5911 case Builtin::BI__sync_val_compare_and_swap_4:
5912 case Builtin::BI__sync_val_compare_and_swap_8:
5913 case Builtin::BI__sync_val_compare_and_swap_16:
5918 case Builtin::BI__sync_bool_compare_and_swap:
5919 case Builtin::BI__sync_bool_compare_and_swap_1:
5920 case Builtin::BI__sync_bool_compare_and_swap_2:
5921 case Builtin::BI__sync_bool_compare_and_swap_4:
5922 case Builtin::BI__sync_bool_compare_and_swap_8:
5923 case Builtin::BI__sync_bool_compare_and_swap_16:
5929 case Builtin::BI__sync_lock_test_and_set:
5930 case Builtin::BI__sync_lock_test_and_set_1:
5931 case Builtin::BI__sync_lock_test_and_set_2:
5932 case Builtin::BI__sync_lock_test_and_set_4:
5933 case Builtin::BI__sync_lock_test_and_set_8:
5934 case Builtin::BI__sync_lock_test_and_set_16:
5938 case Builtin::BI__sync_lock_release:
5939 case Builtin::BI__sync_lock_release_1:
5940 case Builtin::BI__sync_lock_release_2:
5941 case Builtin::BI__sync_lock_release_4:
5942 case Builtin::BI__sync_lock_release_8:
5943 case Builtin::BI__sync_lock_release_16:
5949 case Builtin::BI__sync_swap:
5950 case Builtin::BI__sync_swap_1:
5951 case Builtin::BI__sync_swap_2:
5952 case Builtin::BI__sync_swap_4:
5953 case Builtin::BI__sync_swap_8:
5954 case Builtin::BI__sync_swap_16:
5962 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5963 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5964 <<
Callee->getSourceRange();
5968 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5969 <<
Callee->getSourceRange();
5971 if (WarnAboutSemanticsChange) {
5972 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5973 <<
Callee->getSourceRange();
5978 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5979 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5980 FunctionDecl *NewBuiltinDecl;
5981 if (NewBuiltinID == BuiltinID)
5982 NewBuiltinDecl = FDecl;
5985 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5988 assert(Res.getFoundDecl());
5989 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5990 if (!NewBuiltinDecl)
5997 for (
unsigned i = 0; i != NumFixed; ++i) {
6026 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6028 CK_BuiltinFnToFnPtr);
6039 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6040 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6041 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6045 return TheCallResult;
6049 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6054 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6055 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6056 "Unexpected nontemporal load/store builtin!");
6057 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6058 unsigned numArgs = isStore ? 2 : 1;
6068 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6074 PointerArg = PointerArgResult.
get();
6075 TheCall->
setArg(numArgs - 1, PointerArg);
6079 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6092 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6099 return TheCallResult;
6111 return TheCallResult;
6118 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6120 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6121 Literal = ObjcLiteral->getString();
6125 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6132 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6133 InitializedEntity Entity =
6143 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6144 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6145 TT.getArch() == llvm::Triple::aarch64_32);
6146 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6147 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6148 if (IsX64 || IsAArch64) {
6155 return S.
Diag(Fn->getBeginLoc(),
6156 diag::err_ms_va_start_used_in_sysv_function);
6163 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6164 return S.
Diag(Fn->getBeginLoc(),
6165 diag::err_va_start_used_in_wrong_abi_function)
6166 << !IsWindowsOrUEFI;
6172 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6180 bool IsVariadic =
false;
6183 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6184 IsVariadic =
Block->isVariadic();
6185 Params =
Block->parameters();
6186 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6189 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6190 IsVariadic = MD->isVariadic();
6192 Params = MD->parameters();
6195 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6199 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6204 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6209 *LastParam = Params.empty() ?
nullptr : Params.back();
6214bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6219 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6243 ParmVarDecl *LastParam;
6254 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6256 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6261 if (std::optional<llvm::APSInt> Val =
6263 Val &&
LangOpts.C23 && *Val == 0 &&
6264 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6265 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6272 SourceLocation ParamLoc;
6273 bool IsCRegister =
false;
6274 bool SecondArgIsLastNonVariadicArgument =
false;
6275 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6276 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6277 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6280 ParamLoc = PV->getLocation();
6286 if (!SecondArgIsLastNonVariadicArgument)
6288 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6289 else if (IsCRegister ||
Type->isReferenceType() ||
6290 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6293 if (!Context.isPromotableIntegerType(Type))
6295 const auto *ED = Type->getAsEnumDecl();
6298 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6300 unsigned Reason = 0;
6301 if (
Type->isReferenceType()) Reason = 1;
6302 else if (IsCRegister) Reason = 2;
6303 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6304 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6311 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6331 if (
Call->getNumArgs() < 3)
6333 diag::err_typecheck_call_too_few_args_at_least)
6334 << 0 << 3 <<
Call->getNumArgs()
6350 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6353 const QualType &ConstCharPtrTy =
6355 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6357 << Arg1->
getType() << ConstCharPtrTy << 1
6360 << 2 << Arg1->
getType() << ConstCharPtrTy;
6362 const QualType SizeTy =
Context.getSizeType();
6367 << Arg2->
getType() << SizeTy << 1
6370 << 3 << Arg2->
getType() << SizeTy;
6375bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6379 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6407 diag::err_typecheck_call_invalid_ordered_compare)
6415bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6416 unsigned BuiltinID) {
6421 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6422 BuiltinID == Builtin::BI__builtin_isinf ||
6423 BuiltinID == Builtin::BI__builtin_isinf_sign))
6427 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6428 BuiltinID == Builtin::BI__builtin_isunordered))
6432 bool IsFPClass = NumArgs == 2;
6435 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6439 for (
unsigned i = 0; i < FPArgNo; ++i) {
6440 Expr *Arg = TheCall->
getArg(i);
6453 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6462 OrigArg = Res.
get();
6464 TheCall->
setArg(FPArgNo, OrigArg);
6466 QualType VectorResultTy;
6467 QualType ElementTy = OrigArg->
getType();
6472 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6478 diag::err_typecheck_call_invalid_unary_fp)
6490 if (!VectorResultTy.
isNull())
6491 ResultTy = VectorResultTy;
6500bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6505 for (
unsigned I = 0; I != 2; ++I) {
6506 Expr *Arg = TheCall->
getArg(I);
6516 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6531 Expr *Real = TheCall->
getArg(0);
6532 Expr *Imag = TheCall->
getArg(1);
6535 diag::err_typecheck_call_different_arg_types)
6550 diag::err_typecheck_call_too_few_args_at_least)
6551 << 0 << 2 << NumArgs
6558 unsigned NumElements = 0;
6573 unsigned NumResElements = NumArgs - 2;
6582 diag::err_vec_builtin_incompatible_vector)
6587 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6589 diag::err_vec_builtin_incompatible_vector)
6594 }
else if (NumElements != NumResElements) {
6597 ?
Context.getExtVectorType(EltType, NumResElements)
6598 :
Context.getVectorType(EltType, NumResElements,
6603 for (
unsigned I = 2; I != NumArgs; ++I) {
6611 diag::err_shufflevector_nonconstant_argument)
6617 else if (
Result->getActiveBits() > 64 ||
6618 Result->getZExtValue() >= NumElements * 2)
6620 diag::err_shufflevector_argument_too_large)
6645 diag::err_convertvector_non_vector)
6648 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6650 <<
"__builtin_convertvector");
6655 if (SrcElts != DstElts)
6657 diag::err_convertvector_incompatible_vector)
6665bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6670 diag::err_typecheck_call_too_many_args_at_most)
6671 << 0 << 3 << NumArgs << 0
6676 for (
unsigned i = 1; i != NumArgs; ++i)
6683bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6684 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6685 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6695 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6705bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6706 Expr *Arg = TheCall->
getArg(0);
6717bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6719 Expr *Arg = TheCall->
getArg(1);
6723 if (
const auto *UE =
6725 if (UE->getKind() == UETT_AlignOf ||
6726 UE->getKind() == UETT_PreferredAlignOf)
6732 if (!
Result.isPowerOf2())
6733 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6740 if (
Result > std::numeric_limits<int32_t>::max())
6748bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6753 Expr *FirstArg = TheCall->
getArg(0);
6759 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6763 TheCall->
setArg(0, FirstArgResult.
get());
6767 Expr *SecondArg = TheCall->
getArg(1);
6775 if (!
Result.isPowerOf2())
6776 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6788 Expr *ThirdArg = TheCall->
getArg(2);
6791 TheCall->
setArg(2, ThirdArg);
6797bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6798 unsigned BuiltinID =
6800 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6803 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6804 if (NumArgs < NumRequiredArgs) {
6805 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6806 << 0 << NumRequiredArgs << NumArgs
6809 if (NumArgs >= NumRequiredArgs + 0x100) {
6811 diag::err_typecheck_call_too_many_args_at_most)
6812 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6823 if (Arg.isInvalid())
6825 TheCall->
setArg(i, Arg.get());
6830 unsigned FormatIdx = i;
6840 unsigned FirstDataArg = i;
6841 while (i < NumArgs) {
6859 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6861 bool Success = CheckFormatArguments(
6864 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6888 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6897 int High,
bool RangeIsError) {
6911 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6919 PDiag(diag::warn_argument_invalid_range)
6962 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6967 if (
Value.isNegative())
6978 if ((
Value & 0xFF) != 0)
7003 Result.setIsUnsigned(
true);
7008 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7028 Result.setIsUnsigned(
true);
7036 diag::err_argument_not_shifted_byte_or_xxff)
7040bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7041 if (!Context.getTargetInfo().hasSjLjLowering())
7042 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7053 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7059bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7060 if (!Context.getTargetInfo().hasSjLjLowering())
7061 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7066bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7081 diag::err_builtin_counted_by_ref_invalid_arg)
7086 diag::err_builtin_counted_by_ref_has_side_effects)
7089 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7091 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7096 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7103 QualType MemberTy = ME->getMemberDecl()->getType();
7106 diag::err_builtin_counted_by_ref_invalid_arg)
7110 diag::err_builtin_counted_by_ref_invalid_arg)
7120bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7122 const CallExpr *CE =
7131 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7136 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7141 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7145 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7149 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7159class UncoveredArgHandler {
7160 enum {
Unknown = -1, AllCovered = -2 };
7162 signed FirstUncoveredArg =
Unknown;
7163 SmallVector<const Expr *, 4> DiagnosticExprs;
7166 UncoveredArgHandler() =
default;
7168 bool hasUncoveredArg()
const {
7169 return (FirstUncoveredArg >= 0);
7172 unsigned getUncoveredArg()
const {
7173 assert(hasUncoveredArg() &&
"no uncovered argument");
7174 return FirstUncoveredArg;
7177 void setAllCovered() {
7180 DiagnosticExprs.clear();
7181 FirstUncoveredArg = AllCovered;
7184 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7185 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7188 if (FirstUncoveredArg == AllCovered)
7193 if (NewFirstUncoveredArg == FirstUncoveredArg)
7194 DiagnosticExprs.push_back(StrExpr);
7195 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7196 DiagnosticExprs.clear();
7197 DiagnosticExprs.push_back(StrExpr);
7198 FirstUncoveredArg = NewFirstUncoveredArg;
7202 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7205enum StringLiteralCheckType {
7207 SLCT_UncheckedLiteral,
7215 bool AddendIsRight) {
7216 unsigned BitWidth = Offset.getBitWidth();
7217 unsigned AddendBitWidth = Addend.getBitWidth();
7219 if (Addend.isUnsigned()) {
7220 Addend = Addend.zext(++AddendBitWidth);
7221 Addend.setIsSigned(
true);
7224 if (AddendBitWidth > BitWidth) {
7225 Offset = Offset.sext(AddendBitWidth);
7226 BitWidth = AddendBitWidth;
7227 }
else if (BitWidth > AddendBitWidth) {
7228 Addend = Addend.sext(BitWidth);
7232 llvm::APSInt ResOffset = Offset;
7233 if (BinOpKind == BO_Add)
7234 ResOffset = Offset.sadd_ov(Addend, Ov);
7236 assert(AddendIsRight && BinOpKind == BO_Sub &&
7237 "operator must be add or sub with addend on the right");
7238 ResOffset = Offset.ssub_ov(Addend, Ov);
7244 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7245 "index (intermediate) result too big");
7246 Offset = Offset.sext(2 * BitWidth);
7247 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7251 Offset = std::move(ResOffset);
7259class FormatStringLiteral {
7260 const StringLiteral *FExpr;
7264 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7265 : FExpr(fexpr), Offset(Offset) {}
7267 const StringLiteral *getFormatString()
const {
return FExpr; }
7269 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7271 unsigned getByteLength()
const {
7272 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7275 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7282 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7283 bool isWide()
const {
return FExpr->
isWide(); }
7284 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7285 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7286 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7287 bool isPascal()
const {
return FExpr->
isPascal(); }
7289 SourceLocation getLocationOfByte(
7290 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7291 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7292 unsigned *StartTokenByteOffset =
nullptr)
const {
7294 StartToken, StartTokenByteOffset);
7297 SourceLocation getBeginLoc() const LLVM_READONLY {
7301 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7307 Sema &S,
const FormatStringLiteral *FExpr,
7312 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7313 bool IgnoreStringsWithoutSpecifiers);
7322static StringLiteralCheckType
7328 llvm::SmallBitVector &CheckedVarArgs,
7329 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7330 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7331 bool IgnoreStringsWithoutSpecifiers =
false) {
7333 return SLCT_NotALiteral;
7335 assert(Offset.isSigned() &&
"invalid offset");
7338 return SLCT_NotALiteral;
7347 return SLCT_UncheckedLiteral;
7350 case Stmt::InitListExprClass:
7354 format_idx, firstDataArg,
Type, CallType,
7355 false, CheckedVarArgs,
7356 UncoveredArg, Offset, CallerFormatParamIdx,
7357 IgnoreStringsWithoutSpecifiers);
7359 return SLCT_NotALiteral;
7360 case Stmt::BinaryConditionalOperatorClass:
7361 case Stmt::ConditionalOperatorClass: {
7370 bool CheckLeft =
true, CheckRight =
true;
7373 if (
C->getCond()->EvaluateAsBooleanCondition(
7385 StringLiteralCheckType Left;
7387 Left = SLCT_UncheckedLiteral;
7390 Args, APK, format_idx, firstDataArg,
Type,
7391 CallType, InFunctionCall, CheckedVarArgs,
7392 UncoveredArg, Offset, CallerFormatParamIdx,
7393 IgnoreStringsWithoutSpecifiers);
7394 if (Left == SLCT_NotALiteral || !CheckRight) {
7400 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7401 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7402 UncoveredArg, Offset, CallerFormatParamIdx,
7403 IgnoreStringsWithoutSpecifiers);
7405 return (CheckLeft && Left < Right) ? Left : Right;
7408 case Stmt::ImplicitCastExprClass:
7412 case Stmt::OpaqueValueExprClass:
7417 return SLCT_NotALiteral;
7419 case Stmt::PredefinedExprClass:
7423 return SLCT_UncheckedLiteral;
7425 case Stmt::DeclRefExprClass: {
7431 bool isConstant =
false;
7435 isConstant = AT->getElementType().isConstant(S.
Context);
7437 isConstant =
T.isConstant(S.
Context) &&
7438 PT->getPointeeType().isConstant(S.
Context);
7439 }
else if (
T->isObjCObjectPointerType()) {
7442 isConstant =
T.isConstant(S.
Context);
7446 if (
const Expr *
Init = VD->getAnyInitializer()) {
7449 if (InitList->isStringLiteralInit())
7450 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7453 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7454 firstDataArg,
Type, CallType,
false,
7455 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7506 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7507 if (CallerFormatParamIdx)
7508 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7509 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7510 for (
const auto *PVFormatMatches :
7511 D->specific_attrs<FormatMatchesAttr>()) {
7516 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7520 S.
Diag(Args[format_idx]->getBeginLoc(),
7521 diag::warn_format_string_type_incompatible)
7522 << PVFormatMatches->getType()->getName()
7524 if (!InFunctionCall) {
7525 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7526 diag::note_format_string_defined);
7528 return SLCT_UncheckedLiteral;
7531 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7532 Args, APK, format_idx, firstDataArg,
Type, CallType,
7533 false, CheckedVarArgs, UncoveredArg,
7534 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7538 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7541 PVFormat->getFirstArg(), &CallerFSI))
7543 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7547 S.
Diag(Args[format_idx]->getBeginLoc(),
7548 diag::warn_format_string_type_incompatible)
7549 << PVFormat->getType()->getName()
7551 if (!InFunctionCall) {
7554 return SLCT_UncheckedLiteral;
7567 return SLCT_UncheckedLiteral;
7575 return SLCT_NotALiteral;
7578 case Stmt::CallExprClass:
7579 case Stmt::CXXMemberCallExprClass: {
7583 StringLiteralCheckType CommonResult;
7584 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7585 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7587 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7588 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7589 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7596 return CommonResult;
7598 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7600 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7601 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7604 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7605 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7606 UncoveredArg, Offset, CallerFormatParamIdx,
7607 IgnoreStringsWithoutSpecifiers);
7613 format_idx, firstDataArg,
Type, CallType,
7614 false, CheckedVarArgs,
7615 UncoveredArg, Offset, CallerFormatParamIdx,
7616 IgnoreStringsWithoutSpecifiers);
7617 return SLCT_NotALiteral;
7619 case Stmt::ObjCMessageExprClass: {
7621 if (
const auto *MD = ME->getMethodDecl()) {
7622 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7631 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7633 MD->getSelector().isKeywordSelector(
7634 {
"localizedStringForKey",
"value",
"table"})) {
7635 IgnoreStringsWithoutSpecifiers =
true;
7638 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7640 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7641 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7642 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7646 return SLCT_NotALiteral;
7648 case Stmt::ObjCStringLiteralClass:
7649 case Stmt::StringLiteralClass: {
7658 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7661 return SLCT_NotALiteral;
7663 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7665 format_idx, firstDataArg,
Type, InFunctionCall,
7666 CallType, CheckedVarArgs, UncoveredArg,
7667 IgnoreStringsWithoutSpecifiers);
7668 return SLCT_CheckedLiteral;
7671 return SLCT_NotALiteral;
7673 case Stmt::BinaryOperatorClass: {
7687 if (LIsInt != RIsInt) {
7691 if (BinOpKind == BO_Add) {
7704 return SLCT_NotALiteral;
7706 case Stmt::UnaryOperatorClass: {
7708 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7709 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7711 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7721 return SLCT_NotALiteral;
7725 return SLCT_NotALiteral;
7736 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7737 if (isa_and_nonnull<StringLiteral>(LVE))
7758 return "freebsd_kprintf";
7767 return llvm::StringSwitch<FormatStringType>(Flavor)
7769 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7774 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7790bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7794 llvm::SmallBitVector &CheckedVarArgs) {
7795 FormatStringInfo FSI;
7799 return CheckFormatArguments(
7800 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7805bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7809 llvm::SmallBitVector &CheckedVarArgs) {
7810 FormatStringInfo FSI;
7814 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7815 Format->getFormatString(), FSI.FormatIdx,
7817 CallType, Loc, Range, CheckedVarArgs);
7825 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7838 unsigned CallerArgumentIndexOffset =
7841 unsigned FirstArgumentIndex = -1;
7851 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7852 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7856 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7857 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7859 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7862 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7863 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7866 FirstArgumentIndex =
7867 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7873 ? (NumCallerParams + CallerArgumentIndexOffset)
7878 if (!ReferenceFormatString)
7884 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7886 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7888 std::string
Attr, Fixit;
7889 llvm::raw_string_ostream AttrOS(
Attr);
7891 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7892 << FirstArgumentIndex <<
")";
7894 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7896 AttrOS.write_escaped(ReferenceFormatString->
getString());
7900 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7911 llvm::raw_string_ostream IS(Fixit);
7919 if (LO.C23 || LO.CPlusPlus11)
7920 IS <<
"[[gnu::" <<
Attr <<
"]]";
7921 else if (LO.ObjC || LO.GNUMode)
7922 IS <<
"__attribute__((" <<
Attr <<
"))";
7936 Caller->
addAttr(FormatAttr::CreateImplicit(
7938 FormatStringIndex, FirstArgumentIndex));
7940 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7942 FormatStringIndex, ReferenceFormatString));
7946 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7958 unsigned format_idx,
unsigned firstDataArg,
7962 llvm::SmallBitVector &CheckedVarArgs) {
7964 if (format_idx >= Args.size()) {
7965 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7969 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7983 UncoveredArgHandler UncoveredArg;
7984 std::optional<unsigned> CallerParamIdx;
7986 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7987 firstDataArg,
Type, CallType,
7988 true, CheckedVarArgs, UncoveredArg,
7989 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7992 if (UncoveredArg.hasUncoveredArg()) {
7993 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7994 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7995 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7998 if (CT != SLCT_NotALiteral)
8000 return CT == SLCT_CheckedLiteral;
8006 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8012 this, Args, APK, ReferenceFormatString, format_idx,
8013 firstDataArg,
Type, *CallerParamIdx, Loc))
8023 if (Args.size() == firstDataArg) {
8024 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8032 Diag(FormatLoc, diag::note_format_security_fixit)
8036 Diag(FormatLoc, diag::note_format_security_fixit)
8041 Diag(FormatLoc, diag::warn_format_nonliteral)
8052 const FormatStringLiteral *FExpr;
8053 const Expr *OrigFormatExpr;
8055 const unsigned FirstDataArg;
8056 const unsigned NumDataArgs;
8059 ArrayRef<const Expr *> Args;
8061 llvm::SmallBitVector CoveredArgs;
8062 bool usesPositionalArgs =
false;
8063 bool atFirstArg =
true;
8064 bool inFunctionCall;
8066 llvm::SmallBitVector &CheckedVarArgs;
8067 UncoveredArgHandler &UncoveredArg;
8070 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8072 unsigned firstDataArg,
unsigned numDataArgs,
8074 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8076 llvm::SmallBitVector &CheckedVarArgs,
8077 UncoveredArgHandler &UncoveredArg)
8078 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8079 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8080 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8081 inFunctionCall(inFunctionCall), CallType(callType),
8082 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8083 CoveredArgs.resize(numDataArgs);
8084 CoveredArgs.reset();
8087 bool HasFormatArguments()
const {
8092 void DoneProcessing();
8094 void HandleIncompleteSpecifier(
const char *startSpecifier,
8095 unsigned specifierLen)
override;
8097 void HandleInvalidLengthModifier(
8098 const analyze_format_string::FormatSpecifier &FS,
8099 const analyze_format_string::ConversionSpecifier &CS,
8100 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8102 void HandleNonStandardLengthModifier(
8103 const analyze_format_string::FormatSpecifier &FS,
8104 const char *startSpecifier,
unsigned specifierLen);
8106 void HandleNonStandardConversionSpecifier(
8107 const analyze_format_string::ConversionSpecifier &CS,
8108 const char *startSpecifier,
unsigned specifierLen);
8110 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8112 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8115 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8117 void HandleNullChar(
const char *nullCharacter)
override;
8119 template <
typename Range>
8121 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8122 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8123 bool IsStringLocation, Range StringRange,
8124 ArrayRef<FixItHint> Fixit = {});
8127 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8128 const char *startSpec,
8129 unsigned specifierLen,
8130 const char *csStart,
unsigned csLen);
8132 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8133 const char *startSpec,
8134 unsigned specifierLen);
8136 SourceRange getFormatStringRange();
8137 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8138 unsigned specifierLen);
8139 SourceLocation getLocationOfByte(
const char *x);
8141 const Expr *getDataArg(
unsigned i)
const;
8143 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8144 const analyze_format_string::ConversionSpecifier &CS,
8145 const char *startSpecifier,
unsigned specifierLen,
8148 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8149 const Expr *E,
const char *startSpecifier,
8150 unsigned specifierLen);
8152 template <
typename Range>
8153 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8154 bool IsStringLocation, Range StringRange,
8155 ArrayRef<FixItHint> Fixit = {});
8160SourceRange CheckFormatHandler::getFormatStringRange() {
8165CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8166 unsigned specifierLen) {
8168 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8176SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8181void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8182 unsigned specifierLen) {
8183 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8184 getLocationOfByte(startSpecifier),
8186 getSpecifierRange(startSpecifier, specifierLen));
8189bool CheckFormatHandler::CheckUnsupportedType(
8191 const char *StartSpecifier,
unsigned SpecifierLen) {
8195 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8198 getSpecifierRange(StartSpecifier, SpecifierLen));
8202void CheckFormatHandler::HandleInvalidLengthModifier(
8205 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8217 getSpecifierRange(startSpecifier, specifierLen));
8219 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8220 << FixedLM->toString()
8225 if (DiagID == diag::warn_format_nonsensical_length)
8231 getSpecifierRange(startSpecifier, specifierLen), Hint);
8235void CheckFormatHandler::HandleNonStandardLengthModifier(
8237 const char *startSpecifier,
unsigned specifierLen) {
8246 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8250 getSpecifierRange(startSpecifier, specifierLen));
8252 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8253 << FixedLM->toString()
8257 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8261 getSpecifierRange(startSpecifier, specifierLen));
8265void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8267 const char *startSpecifier,
unsigned specifierLen) {
8273 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8277 getSpecifierRange(startSpecifier, specifierLen));
8280 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8281 << FixedCS->toString()
8284 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8288 getSpecifierRange(startSpecifier, specifierLen));
8292void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8294 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8295 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8296 getLocationOfByte(startPos),
8298 getSpecifierRange(startPos, posLen));
8301void CheckFormatHandler::HandleInvalidPosition(
8302 const char *startSpecifier,
unsigned specifierLen,
8305 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8306 EmitFormatDiagnostic(
8307 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8308 getLocationOfByte(startSpecifier),
true,
8309 getSpecifierRange(startSpecifier, specifierLen));
8312void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8316 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8317 getLocationOfByte(startPos),
8319 getSpecifierRange(startPos, posLen));
8322void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8325 EmitFormatDiagnostic(
8326 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8327 getLocationOfByte(nullCharacter),
true,
8328 getFormatStringRange());
8334const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8335 return Args[FirstDataArg + i];
8338void CheckFormatHandler::DoneProcessing() {
8341 if (HasFormatArguments()) {
8344 signed notCoveredArg = CoveredArgs.find_first();
8345 if (notCoveredArg >= 0) {
8346 assert((
unsigned)notCoveredArg < NumDataArgs);
8347 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8349 UncoveredArg.setAllCovered();
8354void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8355 const Expr *ArgExpr) {
8356 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8367 for (
auto E : DiagnosticExprs)
8370 CheckFormatHandler::EmitFormatDiagnostic(
8371 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8375bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8377 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8378 bool keepGoing =
true;
8379 if (argIndex < NumDataArgs) {
8382 CoveredArgs.set(argIndex);
8397 std::string CodePointStr;
8398 if (!llvm::sys::locale::isPrint(*csStart)) {
8399 llvm::UTF32 CodePoint;
8400 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8401 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8402 llvm::ConversionResult
Result =
8403 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8405 if (
Result != llvm::conversionOK) {
8406 unsigned char FirstChar = *csStart;
8407 CodePoint = (llvm::UTF32)FirstChar;
8410 llvm::raw_string_ostream
OS(CodePointStr);
8411 if (CodePoint < 256)
8412 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8413 else if (CodePoint <= 0xFFFF)
8414 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8416 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8420 EmitFormatDiagnostic(
8421 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8422 true, getSpecifierRange(startSpec, specifierLen));
8427void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8428 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8429 EmitFormatDiagnostic(
8430 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8431 true, getSpecifierRange(startSpec, specifierLen));
8434bool CheckFormatHandler::CheckNumArgs(
8437 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8439 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8442 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8443 << (argIndex + 1) << NumDataArgs)
8444 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8445 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8447 getSpecifierRange(startSpecifier, specifierLen));
8451 UncoveredArg.setAllCovered();
8457template <
typename Range>
8460 bool IsStringLocation,
8463 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8464 IsStringLocation, StringRange, FixIt);
8494template <
typename Range>
8495void CheckFormatHandler::EmitFormatDiagnostic(
8496 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8499 if (InFunctionCall) {
8504 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8508 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8509 diag::note_format_string_defined);
8511 Note << StringRange;
8520class CheckPrintfHandler :
public CheckFormatHandler {
8522 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8524 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8526 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8528 llvm::SmallBitVector &CheckedVarArgs,
8529 UncoveredArgHandler &UncoveredArg)
8530 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8531 numDataArgs, beg, APK, Args, formatIdx,
8532 inFunctionCall, CallType, CheckedVarArgs,
8535 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8538 bool allowsObjCArg()
const {
8539 return FSType == FormatStringType::NSString ||
8540 FSType == FormatStringType::OSLog ||
8541 FSType == FormatStringType::OSTrace;
8544 bool HandleInvalidPrintfConversionSpecifier(
8545 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8546 unsigned specifierLen)
override;
8548 void handleInvalidMaskType(StringRef MaskType)
override;
8550 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8551 const char *startSpecifier,
unsigned specifierLen,
8552 const TargetInfo &
Target)
override;
8553 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8554 const char *StartSpecifier,
unsigned SpecifierLen,
8557 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8558 unsigned k,
const char *startSpecifier,
8559 unsigned specifierLen);
8560 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8561 const analyze_printf::OptionalAmount &Amt,
8562 unsigned type,
const char *startSpecifier,
8563 unsigned specifierLen);
8564 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8565 const analyze_printf::OptionalFlag &flag,
8566 const char *startSpecifier,
unsigned specifierLen);
8567 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8568 const analyze_printf::OptionalFlag &ignoredFlag,
8569 const analyze_printf::OptionalFlag &flag,
8570 const char *startSpecifier,
unsigned specifierLen);
8571 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8573 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8574 unsigned flagLen)
override;
8576 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8577 unsigned flagLen)
override;
8580 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8581 const char *flagsEnd,
8582 const char *conversionPosition)
override;
8587class EquatableFormatArgument {
8589 enum SpecifierSensitivity :
unsigned {
8596 enum FormatArgumentRole :
unsigned {
8604 analyze_format_string::ArgType ArgType;
8605 analyze_format_string::LengthModifier LengthMod;
8606 StringRef SpecifierLetter;
8607 CharSourceRange
Range;
8608 SourceLocation ElementLoc;
8609 FormatArgumentRole
Role : 2;
8610 SpecifierSensitivity Sensitivity : 2;
8611 unsigned Position : 14;
8612 unsigned ModifierFor : 14;
8614 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8615 bool InFunctionCall)
const;
8618 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8619 analyze_format_string::LengthModifier LengthMod,
8620 StringRef SpecifierLetter,
8621 analyze_format_string::ArgType ArgType,
8622 FormatArgumentRole
Role,
8623 SpecifierSensitivity Sensitivity,
unsigned Position,
8624 unsigned ModifierFor)
8625 : ArgType(ArgType), LengthMod(LengthMod),
8626 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8627 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8628 ModifierFor(ModifierFor) {}
8630 unsigned getPosition()
const {
return Position; }
8631 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8633 analyze_format_string::LengthModifier getLengthModifier()
const {
8636 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8638 std::string buildFormatSpecifier()
const {
8640 llvm::raw_string_ostream(result)
8641 << getLengthModifier().
toString() << SpecifierLetter;
8645 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8646 const Expr *FmtExpr,
bool InFunctionCall)
const;
8650class DecomposePrintfHandler :
public CheckPrintfHandler {
8651 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8654 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8655 const Expr *origFormatExpr,
8657 unsigned numDataArgs,
bool isObjC,
const char *beg,
8659 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8661 llvm::SmallBitVector &CheckedVarArgs,
8662 UncoveredArgHandler &UncoveredArg,
8663 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8664 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8665 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8666 inFunctionCall, CallType, CheckedVarArgs,
8668 Specs(Specs), HadError(
false) {}
8672 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8674 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8676 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8677 const char *startSpecifier,
8678 unsigned specifierLen,
8679 const TargetInfo &
Target)
override;
8684bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8686 unsigned specifierLen) {
8690 return HandleInvalidConversionSpecifier(
8695void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8696 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8704 return T->isRecordType() ||
T->isComplexType();
8707bool CheckPrintfHandler::HandleAmount(
8709 const char *startSpecifier,
unsigned specifierLen) {
8711 if (HasFormatArguments()) {
8713 if (argIndex >= NumDataArgs) {
8714 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8718 getSpecifierRange(startSpecifier, specifierLen));
8728 CoveredArgs.set(argIndex);
8729 const Expr *Arg = getDataArg(argIndex);
8740 ? diag::err_printf_asterisk_wrong_type
8741 : diag::warn_printf_asterisk_wrong_type;
8742 EmitFormatDiagnostic(S.
PDiag(DiagID)
8747 getSpecifierRange(startSpecifier, specifierLen));
8757void CheckPrintfHandler::HandleInvalidAmount(
8760 const char *startSpecifier,
unsigned specifierLen) {
8770 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8774 getSpecifierRange(startSpecifier, specifierLen), fixit);
8779 const char *startSpecifier,
8780 unsigned specifierLen) {
8784 EmitFormatDiagnostic(
8785 S.
PDiag(diag::warn_printf_nonsensical_flag)
8789 getSpecifierRange(startSpecifier, specifierLen),
8793void CheckPrintfHandler::HandleIgnoredFlag(
8797 unsigned specifierLen) {
8799 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8803 getSpecifierRange(startSpecifier, specifierLen),
8805 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8808void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8811 EmitFormatDiagnostic(
8812 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
8813 true, getSpecifierRange(startFlag, flagLen));
8816void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8819 auto Range = getSpecifierRange(startFlag, flagLen);
8820 StringRef flag(startFlag, flagLen);
8821 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8822 getLocationOfByte(startFlag),
8827void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8828 const char *flagsStart,
const char *flagsEnd,
8829 const char *conversionPosition) {
8831 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8832 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8833 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8834 getLocationOfByte(conversionPosition),
8840 const Expr *FmtExpr,
8841 bool InFunctionCall)
const {
8842 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8843 ElementLoc,
true, Range);
8846bool EquatableFormatArgument::VerifyCompatible(
8847 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8848 bool InFunctionCall)
const {
8853 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8854 FmtExpr, InFunctionCall);
8855 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8859 if (
Role != FAR_Data) {
8860 if (ModifierFor !=
Other.ModifierFor) {
8863 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8864 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8865 FmtExpr, InFunctionCall);
8866 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8872 bool HadError =
false;
8873 if (Sensitivity !=
Other.Sensitivity) {
8876 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8877 << Sensitivity <<
Other.Sensitivity,
8878 FmtExpr, InFunctionCall);
8879 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8880 << 0 <<
Other.Range;
8883 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8887 case MK::MatchPromotion:
8891 case MK::NoMatchTypeConfusion:
8892 case MK::NoMatchPromotionTypeConfusion:
8894 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8895 << buildFormatSpecifier()
8896 <<
Other.buildFormatSpecifier(),
8897 FmtExpr, InFunctionCall);
8898 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8899 << 0 <<
Other.Range;
8902 case MK::NoMatchPedantic:
8904 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8905 << buildFormatSpecifier()
8906 <<
Other.buildFormatSpecifier(),
8907 FmtExpr, InFunctionCall);
8908 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8909 << 0 <<
Other.Range;
8912 case MK::NoMatchSignedness:
8914 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8915 << buildFormatSpecifier()
8916 <<
Other.buildFormatSpecifier(),
8917 FmtExpr, InFunctionCall);
8918 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8919 << 0 <<
Other.Range;
8925bool DecomposePrintfHandler::GetSpecifiers(
8926 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8929 StringRef
Data = FSL->getString();
8930 const char *Str =
Data.data();
8931 llvm::SmallBitVector BV;
8932 UncoveredArgHandler UA;
8933 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8934 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8946 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8947 const EquatableFormatArgument &B) {
8948 return A.getPosition() < B.getPosition();
8953bool DecomposePrintfHandler::HandlePrintfSpecifier(
8956 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8971 const unsigned Unset = ~0;
8972 unsigned FieldWidthIndex = Unset;
8973 unsigned PrecisionIndex = Unset;
8977 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8978 FieldWidthIndex = Specs.size();
8980 getSpecifierRange(startSpecifier, specifierLen),
8981 getLocationOfByte(FieldWidth.getStart()),
8983 FieldWidth.getArgType(S.
Context),
8984 EquatableFormatArgument::FAR_FieldWidth,
8985 EquatableFormatArgument::SS_None,
8986 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
8992 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8993 PrecisionIndex = Specs.size();
8995 getSpecifierRange(startSpecifier, specifierLen),
8996 getLocationOfByte(Precision.getStart()),
8998 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8999 EquatableFormatArgument::SS_None,
9000 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9006 unsigned SpecIndex =
9008 if (FieldWidthIndex != Unset)
9009 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9010 if (PrecisionIndex != Unset)
9011 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9013 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9015 Sensitivity = EquatableFormatArgument::SS_Private;
9017 Sensitivity = EquatableFormatArgument::SS_Public;
9019 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9021 Sensitivity = EquatableFormatArgument::SS_None;
9024 getSpecifierRange(startSpecifier, specifierLen),
9027 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9032 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9037 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9038 SpecIndex + 1, SpecIndex);
9046template<
typename MemberKind>
9057 R.suppressDiagnostics();
9064 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9079 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9081 if ((*MI)->getMinRequiredArguments() == 0)
9089bool CheckPrintfHandler::checkForCStrMembers(
9096 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9099 if (
Method->getMinRequiredArguments() == 0 &&
9112bool CheckPrintfHandler::HandlePrintfSpecifier(
9125 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9126 startSpecifier, specifierLen);
9138 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9143 if (!CS.consumesDataArgument()) {
9151 if (argIndex < NumDataArgs) {
9155 CoveredArgs.set(argIndex);
9162 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9165 if (HasFormatArguments()) {
9167 CoveredArgs.set(argIndex + 1);
9170 const Expr *Ex = getDataArg(argIndex);
9174 : ArgType::CPointerTy;
9176 EmitFormatDiagnostic(
9177 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9181 getSpecifierRange(startSpecifier, specifierLen));
9184 Ex = getDataArg(argIndex + 1);
9187 EmitFormatDiagnostic(
9188 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9192 getSpecifierRange(startSpecifier, specifierLen));
9199 if (!allowsObjCArg() && CS.isObjCArg()) {
9200 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9207 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9214 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9215 getLocationOfByte(CS.getStart()),
9217 getSpecifierRange(startSpecifier, specifierLen));
9227 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9234 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9238 getSpecifierRange(startSpecifier, specifierLen));
9241 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9245 getSpecifierRange(startSpecifier, specifierLen));
9249 const llvm::Triple &Triple =
Target.getTriple();
9251 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9252 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9253 getLocationOfByte(CS.getStart()),
9255 getSpecifierRange(startSpecifier, specifierLen));
9261 startSpecifier, specifierLen);
9267 startSpecifier, specifierLen);
9273 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9274 getLocationOfByte(startSpecifier),
9276 getSpecifierRange(startSpecifier, specifierLen));
9285 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9287 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9296 startSpecifier, specifierLen);
9299 startSpecifier, specifierLen);
9304 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9305 diag::warn_format_nonsensical_length);
9307 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9309 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9310 diag::warn_format_non_standard_conversion_spec);
9313 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9316 if (!HasFormatArguments())
9319 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9322 const Expr *Arg = getDataArg(argIndex);
9326 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9338 case Stmt::ArraySubscriptExprClass:
9339 case Stmt::CallExprClass:
9340 case Stmt::CharacterLiteralClass:
9341 case Stmt::CXXBoolLiteralExprClass:
9342 case Stmt::DeclRefExprClass:
9343 case Stmt::FloatingLiteralClass:
9344 case Stmt::IntegerLiteralClass:
9345 case Stmt::MemberExprClass:
9346 case Stmt::ObjCArrayLiteralClass:
9347 case Stmt::ObjCBoolLiteralExprClass:
9348 case Stmt::ObjCBoxedExprClass:
9349 case Stmt::ObjCDictionaryLiteralClass:
9350 case Stmt::ObjCEncodeExprClass:
9351 case Stmt::ObjCIvarRefExprClass:
9352 case Stmt::ObjCMessageExprClass:
9353 case Stmt::ObjCPropertyRefExprClass:
9354 case Stmt::ObjCStringLiteralClass:
9355 case Stmt::ObjCSubscriptRefExprClass:
9356 case Stmt::ParenExprClass:
9357 case Stmt::StringLiteralClass:
9358 case Stmt::UnaryOperatorClass:
9365static std::pair<QualType, StringRef>
9371 StringRef Name = UserTy->getDecl()->getName();
9372 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9373 .Case(
"CFIndex", Context.getNSIntegerType())
9374 .Case(
"NSInteger", Context.getNSIntegerType())
9375 .Case(
"NSUInteger", Context.getNSUIntegerType())
9376 .Case(
"SInt32", Context.IntTy)
9377 .Case(
"UInt32", Context.UnsignedIntTy)
9381 return std::make_pair(CastTy, Name);
9383 TyTy = UserTy->desugar();
9387 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9397 StringRef TrueName, FalseName;
9400 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9402 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9404 if (TrueTy == FalseTy)
9405 return std::make_pair(TrueTy, TrueName);
9406 else if (TrueTy.
isNull())
9407 return std::make_pair(FalseTy, FalseName);
9408 else if (FalseTy.
isNull())
9409 return std::make_pair(TrueTy, TrueName);
9412 return std::make_pair(
QualType(), StringRef());
9431 From = VecTy->getElementType();
9433 To = VecTy->getElementType();
9444 diag::warn_format_conversion_argument_type_mismatch_signedness,
9448 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9455bool CheckPrintfHandler::checkFormatExpr(
9457 unsigned SpecifierLen,
const Expr *E) {
9468 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9469 ExprTy = TET->getUnderlyingExpr()->getType();
9472 if (
const OverflowBehaviorType *OBT =
9474 ExprTy = OBT->getUnderlyingType();
9488 getSpecifierRange(StartSpecifier, SpecifierLen);
9490 llvm::raw_svector_ostream os(FSString);
9492 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9503 getSpecifierRange(StartSpecifier, SpecifierLen);
9504 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9509 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9517 if (
Match == ArgType::Match)
9521 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9530 E = ICE->getSubExpr();
9540 if (OrigMatch == ArgType::NoMatchSignedness &&
9541 ImplicitMatch != ArgType::NoMatchSignedness)
9548 if (ImplicitMatch == ArgType::Match)
9566 if (
Match == ArgType::MatchPromotion)
9570 if (
Match == ArgType::MatchPromotion) {
9574 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9575 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9579 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9580 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9581 Match = ImplicitMatch;
9582 assert(
Match != ArgType::MatchPromotion);
9585 bool IsEnum =
false;
9586 bool IsScopedEnum =
false;
9589 IntendedTy = ED->getIntegerType();
9590 if (!ED->isScoped()) {
9591 ExprTy = IntendedTy;
9596 IsScopedEnum =
true;
9603 if (isObjCContext() &&
9614 const llvm::APInt &
V = IL->getValue();
9624 if (TD->getUnderlyingType() == IntendedTy)
9634 bool ShouldNotPrintDirectly =
false;
9635 StringRef CastTyName;
9638 std::tie(CastTy, CastTyName) =
9644 if (!IsScopedEnum &&
9645 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9649 IntendedTy = CastTy;
9650 ShouldNotPrintDirectly =
true;
9655 PrintfSpecifier fixedFS = FS;
9662 llvm::raw_svector_ostream os(buf);
9665 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9667 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9673 llvm_unreachable(
"expected non-matching");
9675 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9678 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9681 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9684 Diag = diag::warn_format_conversion_argument_type_mismatch;
9705 llvm::raw_svector_ostream CastFix(CastBuf);
9706 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9708 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9714 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9719 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9741 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9747 Name = TypedefTy->getDecl()->getName();
9751 ? diag::warn_format_argument_needs_cast_pedantic
9752 : diag::warn_format_argument_needs_cast;
9753 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9764 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9765 : diag::warn_format_conversion_argument_type_mismatch;
9767 EmitFormatDiagnostic(
9775 getSpecifierRange(StartSpecifier, SpecifierLen);
9779 bool EmitTypeMismatch =
false;
9783 bool EmitOSLogError =
false;
9792 llvm_unreachable(
"expected non-matching");
9794 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9797 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9800 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9804 Diag = diag::warn_format_conversion_argument_type_mismatch;
9808 if (!EmitOSLogError)
9809 EmitFormatDiagnostic(
9818 EmitTypeMismatch =
true;
9822 EmitOSLogError =
true;
9824 EmitFormatDiagnostic(
9825 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9826 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9830 checkForCStrMembers(AT, E);
9836 EmitTypeMismatch =
true;
9838 EmitFormatDiagnostic(
9839 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9840 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9854 EmitFormatDiagnostic(
9855 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
9860 if (EmitTypeMismatch) {
9866 EmitFormatDiagnostic(
9867 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9873 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9874 "format string specifier index out of range");
9875 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9885class CheckScanfHandler :
public CheckFormatHandler {
9887 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
9889 unsigned firstDataArg,
unsigned numDataArgs,
9891 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9893 llvm::SmallBitVector &CheckedVarArgs,
9894 UncoveredArgHandler &UncoveredArg)
9895 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
9896 numDataArgs, beg, APK, Args, formatIdx,
9897 inFunctionCall, CallType, CheckedVarArgs,
9900 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9901 const char *startSpecifier,
9902 unsigned specifierLen)
override;
9905 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9906 const char *startSpecifier,
9907 unsigned specifierLen)
override;
9909 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9914void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9916 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9917 getLocationOfByte(end),
true,
9918 getSpecifierRange(start, end - start));
9921bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9923 unsigned specifierLen) {
9927 return HandleInvalidConversionSpecifier(
9932bool CheckScanfHandler::HandleScanfSpecifier(
9934 unsigned specifierLen) {
9947 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9948 startSpecifier, specifierLen);
9959 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9974 if (argIndex < NumDataArgs) {
9978 CoveredArgs.set(argIndex);
9984 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9985 diag::warn_format_nonsensical_length);
9987 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9989 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9990 diag::warn_format_non_standard_conversion_spec);
9993 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9996 if (!HasFormatArguments())
9999 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10003 const Expr *Ex = getDataArg(argIndex);
10013 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10024 ScanfSpecifier fixedFS = FS;
10029 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10031 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10032 : diag::warn_format_conversion_argument_type_mismatch;
10037 llvm::raw_svector_ostream os(buf);
10040 EmitFormatDiagnostic(
10045 getSpecifierRange(startSpecifier, specifierLen),
10047 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10054 getSpecifierRange(startSpecifier, specifierLen));
10064 const Expr *FmtExpr,
bool InFunctionCall) {
10065 bool HadError =
false;
10066 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10067 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10068 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10080 for (; FmtIter < FmtEnd; ++FmtIter) {
10084 if (FmtIter->getPosition() < RefIter->getPosition())
10088 if (FmtIter->getPosition() > RefIter->getPosition())
10092 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10096 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10097 return Arg.getPosition() != RefIter->getPosition();
10101 if (FmtIter < FmtEnd) {
10102 CheckFormatHandler::EmitFormatDiagnostic(
10103 S, InFunctionCall, FmtExpr,
10104 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10105 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10106 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10107 }
else if (RefIter < RefEnd) {
10108 CheckFormatHandler::EmitFormatDiagnostic(
10109 S, InFunctionCall, FmtExpr,
10110 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10113 << 1 << RefIter->getSourceRange();
10119 Sema &S,
const FormatStringLiteral *FExpr,
10124 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10125 bool IgnoreStringsWithoutSpecifiers) {
10127 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10128 CheckFormatHandler::EmitFormatDiagnostic(
10129 S, inFunctionCall, Args[format_idx],
10130 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10136 StringRef StrRef = FExpr->getString();
10137 const char *Str = StrRef.data();
10141 assert(
T &&
"String literal not of constant array type!");
10142 size_t TypeSize =
T->getZExtSize();
10143 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10144 const unsigned numDataArgs = Args.size() - firstDataArg;
10146 if (IgnoreStringsWithoutSpecifiers &&
10153 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10154 CheckFormatHandler::EmitFormatDiagnostic(
10155 S, inFunctionCall, Args[format_idx],
10156 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10157 FExpr->getBeginLoc(),
10163 if (StrLen == 0 && numDataArgs > 0) {
10164 CheckFormatHandler::EmitFormatDiagnostic(
10165 S, inFunctionCall, Args[format_idx],
10166 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10177 if (ReferenceFormatString ==
nullptr) {
10178 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10179 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10180 inFunctionCall, CallType, CheckedVarArgs,
10187 H.DoneProcessing();
10190 Type, ReferenceFormatString, FExpr->getFormatString(),
10191 inFunctionCall ?
nullptr : Args[format_idx]);
10194 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10195 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10196 CallType, CheckedVarArgs, UncoveredArg);
10200 H.DoneProcessing();
10216 FormatStringLiteral RefLit = AuthoritativeFormatString;
10217 FormatStringLiteral TestLit = TestedFormatString;
10219 bool DiagAtStringLiteral;
10220 if (FunctionCallArg) {
10221 Arg = FunctionCallArg;
10222 DiagAtStringLiteral =
false;
10224 Arg = TestedFormatString;
10225 DiagAtStringLiteral =
true;
10227 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10228 AuthoritativeFormatString,
Type,
10229 IsObjC,
true, RefArgs) &&
10230 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10231 DiagAtStringLiteral, FmtArgs)) {
10233 TestedFormatString, FmtArgs, Arg,
10234 DiagAtStringLiteral);
10247 FormatStringLiteral RefLit = Str;
10251 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10260 bool HadError =
false;
10261 auto Iter = Args.begin();
10262 auto End = Args.end();
10263 while (Iter != End) {
10264 const auto &FirstInGroup = *Iter;
10266 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10268 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10277 const char *Str = StrRef.data();
10280 assert(
T &&
"String literal not of constant array type!");
10281 size_t TypeSize =
T->getZExtSize();
10282 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10292 switch (AbsFunction) {
10296 case Builtin::BI__builtin_abs:
10297 return Builtin::BI__builtin_labs;
10298 case Builtin::BI__builtin_labs:
10299 return Builtin::BI__builtin_llabs;
10300 case Builtin::BI__builtin_llabs:
10303 case Builtin::BI__builtin_fabsf:
10304 return Builtin::BI__builtin_fabs;
10305 case Builtin::BI__builtin_fabs:
10306 return Builtin::BI__builtin_fabsl;
10307 case Builtin::BI__builtin_fabsl:
10310 case Builtin::BI__builtin_cabsf:
10311 return Builtin::BI__builtin_cabs;
10312 case Builtin::BI__builtin_cabs:
10313 return Builtin::BI__builtin_cabsl;
10314 case Builtin::BI__builtin_cabsl:
10317 case Builtin::BIabs:
10318 return Builtin::BIlabs;
10319 case Builtin::BIlabs:
10320 return Builtin::BIllabs;
10321 case Builtin::BIllabs:
10324 case Builtin::BIfabsf:
10325 return Builtin::BIfabs;
10326 case Builtin::BIfabs:
10327 return Builtin::BIfabsl;
10328 case Builtin::BIfabsl:
10331 case Builtin::BIcabsf:
10332 return Builtin::BIcabs;
10333 case Builtin::BIcabs:
10334 return Builtin::BIcabsl;
10335 case Builtin::BIcabsl:
10342 unsigned AbsType) {
10364 unsigned AbsFunctionKind) {
10365 unsigned BestKind = 0;
10366 uint64_t ArgSize = Context.getTypeSize(ArgType);
10367 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10370 if (Context.getTypeSize(ParamType) >= ArgSize) {
10373 else if (Context.hasSameType(ParamType, ArgType)) {
10389 if (
T->isIntegralOrEnumerationType())
10391 if (
T->isRealFloatingType())
10393 if (
T->isAnyComplexType())
10396 llvm_unreachable(
"Type not integer, floating, or complex");
10403 switch (ValueKind) {
10408 case Builtin::BI__builtin_fabsf:
10409 case Builtin::BI__builtin_fabs:
10410 case Builtin::BI__builtin_fabsl:
10411 case Builtin::BI__builtin_cabsf:
10412 case Builtin::BI__builtin_cabs:
10413 case Builtin::BI__builtin_cabsl:
10414 return Builtin::BI__builtin_abs;
10415 case Builtin::BIfabsf:
10416 case Builtin::BIfabs:
10417 case Builtin::BIfabsl:
10418 case Builtin::BIcabsf:
10419 case Builtin::BIcabs:
10420 case Builtin::BIcabsl:
10421 return Builtin::BIabs;
10427 case Builtin::BI__builtin_abs:
10428 case Builtin::BI__builtin_labs:
10429 case Builtin::BI__builtin_llabs:
10430 case Builtin::BI__builtin_cabsf:
10431 case Builtin::BI__builtin_cabs:
10432 case Builtin::BI__builtin_cabsl:
10433 return Builtin::BI__builtin_fabsf;
10434 case Builtin::BIabs:
10435 case Builtin::BIlabs:
10436 case Builtin::BIllabs:
10437 case Builtin::BIcabsf:
10438 case Builtin::BIcabs:
10439 case Builtin::BIcabsl:
10440 return Builtin::BIfabsf;
10446 case Builtin::BI__builtin_abs:
10447 case Builtin::BI__builtin_labs:
10448 case Builtin::BI__builtin_llabs:
10449 case Builtin::BI__builtin_fabsf:
10450 case Builtin::BI__builtin_fabs:
10451 case Builtin::BI__builtin_fabsl:
10452 return Builtin::BI__builtin_cabsf;
10453 case Builtin::BIabs:
10454 case Builtin::BIlabs:
10455 case Builtin::BIllabs:
10456 case Builtin::BIfabsf:
10457 case Builtin::BIfabs:
10458 case Builtin::BIfabsl:
10459 return Builtin::BIcabsf;
10462 llvm_unreachable(
"Unable to convert function");
10473 case Builtin::BI__builtin_abs:
10474 case Builtin::BI__builtin_fabs:
10475 case Builtin::BI__builtin_fabsf:
10476 case Builtin::BI__builtin_fabsl:
10477 case Builtin::BI__builtin_labs:
10478 case Builtin::BI__builtin_llabs:
10479 case Builtin::BI__builtin_cabs:
10480 case Builtin::BI__builtin_cabsf:
10481 case Builtin::BI__builtin_cabsl:
10482 case Builtin::BIabs:
10483 case Builtin::BIlabs:
10484 case Builtin::BIllabs:
10485 case Builtin::BIfabs:
10486 case Builtin::BIfabsf:
10487 case Builtin::BIfabsl:
10488 case Builtin::BIcabs:
10489 case Builtin::BIcabsf:
10490 case Builtin::BIcabsl:
10493 llvm_unreachable(
"Unknown Builtin type");
10499 unsigned AbsKind,
QualType ArgType) {
10500 bool EmitHeaderHint =
true;
10501 const char *HeaderName =
nullptr;
10502 std::string FunctionName;
10503 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10504 FunctionName =
"std::abs";
10505 if (ArgType->isIntegralOrEnumerationType()) {
10506 HeaderName =
"cstdlib";
10507 }
else if (ArgType->isRealFloatingType()) {
10508 HeaderName =
"cmath";
10510 llvm_unreachable(
"Invalid Type");
10516 R.suppressDiagnostics();
10519 for (
const auto *I : R) {
10522 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10524 FDecl = dyn_cast<FunctionDecl>(I);
10539 EmitHeaderHint =
false;
10551 R.suppressDiagnostics();
10554 if (R.isSingleResult()) {
10555 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10557 EmitHeaderHint =
false;
10561 }
else if (!R.empty()) {
10567 S.
Diag(Loc, diag::note_replace_abs_function)
10573 if (!EmitHeaderHint)
10576 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10580template <std::
size_t StrLen>
10582 const char (&Str)[StrLen]) {
10595 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10596 return llvm::is_contained(names, calleeName);
10601 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10602 "__builtin_nanf16",
"__builtin_nanf128"});
10604 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10605 "__builtin_inff16",
"__builtin_inff128"});
10607 llvm_unreachable(
"unknown MathCheck");
10611 if (FDecl->
getName() !=
"infinity")
10614 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10616 if (RDecl->
getName() !=
"numeric_limits")
10633 if (FPO.getNoHonorNaNs() &&
10636 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10637 << 1 << 0 <<
Call->getSourceRange();
10641 if (FPO.getNoHonorInfs() &&
10645 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10646 << 0 << 0 <<
Call->getSourceRange();
10650void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10652 if (
Call->getNumArgs() != 1)
10657 if (AbsKind == 0 && !IsStdAbs)
10660 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10661 QualType ParamType =
Call->getArg(0)->getType();
10666 std::string FunctionName =
10667 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10668 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10669 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10704 if (ArgValueKind == ParamValueKind) {
10705 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10709 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10710 << FDecl << ArgType << ParamType;
10712 if (NewAbsKind == 0)
10716 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10725 if (NewAbsKind == 0)
10728 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10729 << FDecl << ParamValueKind << ArgValueKind;
10732 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10738 if (!
Call || !FDecl)
return;
10742 if (
Call->getExprLoc().isMacroID())
return;
10745 if (
Call->getNumArgs() != 2)
return;
10748 if (!ArgList)
return;
10749 if (ArgList->size() != 1)
return;
10752 const auto& TA = ArgList->
get(0);
10754 QualType ArgType = TA.getAsType();
10758 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10759 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10760 if (!MTE)
return false;
10761 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10762 if (!
Num)
return false;
10763 if (
Num->getValue() != 0)
return false;
10767 const Expr *FirstArg =
Call->getArg(0);
10768 const Expr *SecondArg =
Call->getArg(1);
10769 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10770 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10773 if (IsFirstArgZero == IsSecondArgZero)
return;
10778 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10780 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10781 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10784 SourceRange RemovalRange;
10785 if (IsFirstArgZero) {
10786 RemovalRange = SourceRange(FirstRange.
getBegin(),
10793 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10808 const auto *Size = dyn_cast<BinaryOperator>(E);
10813 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10817 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10818 << SizeRange << FnName;
10819 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10824 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10835 bool &IsContained) {
10837 const Type *Ty =
T->getBaseElementTypeUnsafe();
10838 IsContained =
false;
10851 for (
auto *FD : RD->
fields()) {
10855 IsContained =
true;
10856 return ContainedRD;
10864 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10865 if (Unary->getKind() == UETT_SizeOf)
10874 if (!
SizeOf->isArgumentType())
10875 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10882 return SizeOf->getTypeOfArgument();
10888struct SearchNonTrivialToInitializeField
10891 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10893 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10896 SourceLocation SL) {
10897 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10898 asDerived().visitArray(PDIK, AT, SL);
10902 Super::visitWithKind(PDIK, FT, SL);
10905 void visitARCStrong(QualType FT, SourceLocation SL) {
10908 void visitARCWeak(QualType FT, SourceLocation SL) {
10911 void visitStruct(QualType FT, SourceLocation SL) {
10916 const ArrayType *AT, SourceLocation SL) {
10917 visit(getContext().getBaseElementType(AT), SL);
10919 void visitTrivial(QualType FT, SourceLocation SL) {}
10921 static void diag(QualType RT,
const Expr *E, Sema &S) {
10922 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10931struct SearchNonTrivialToCopyField
10933 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10935 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10938 SourceLocation SL) {
10939 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10940 asDerived().visitArray(PCK, AT, SL);
10944 Super::visitWithKind(PCK, FT, SL);
10947 void visitARCStrong(QualType FT, SourceLocation SL) {
10950 void visitARCWeak(QualType FT, SourceLocation SL) {
10953 void visitPtrAuth(QualType FT, SourceLocation SL) {
10956 void visitStruct(QualType FT, SourceLocation SL) {
10961 SourceLocation SL) {
10962 visit(getContext().getBaseElementType(AT), SL);
10965 SourceLocation SL) {}
10966 void visitTrivial(QualType FT, SourceLocation SL) {}
10967 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10969 static void diag(QualType RT,
const Expr *E, Sema &S) {
10970 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10985 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10986 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11010 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
11012 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
11013 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
11019 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11022 const Expr *SizeArg =
11023 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11025 auto isLiteralZero = [](
const Expr *E) {
11035 if (isLiteralZero(SizeArg) &&
11042 if (BId == Builtin::BIbzero ||
11045 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11046 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11047 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11048 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11049 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11057 if (BId == Builtin::BImemset &&
11061 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11062 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11067void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11074 unsigned ExpectedNumArgs =
11075 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11076 if (
Call->getNumArgs() < ExpectedNumArgs)
11079 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11080 BId == Builtin::BIstrndup ? 1 : 2);
11082 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11086 Call->getBeginLoc(),
Call->getRParenLoc()))
11098 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11099 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11102 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11106 QualType DestTy = Dest->
getType();
11107 QualType PointeeTy;
11108 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11120 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11126 if (SizeOfArgTy != QualType()) {
11128 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11130 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11131 << FnName << SizeOfArgTy << ArgIdx
11138 PointeeTy = DestTy;
11141 if (PointeeTy == QualType())
11146 if (
const CXXRecordDecl *ContainedRD =
11149 unsigned OperationType = 0;
11150 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11153 if (ArgIdx != 0 || IsCmp) {
11154 if (BId == Builtin::BImemcpy)
11156 else if(BId == Builtin::BImemmove)
11163 PDiag(diag::warn_dyn_class_memaccess)
11164 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11165 << IsContained << ContainedRD << OperationType
11166 <<
Call->getCallee()->getSourceRange());
11168 BId != Builtin::BImemset)
11171 PDiag(diag::warn_arc_object_memaccess)
11172 << ArgIdx << FnName << PointeeTy
11173 <<
Call->getCallee()->getSourceRange());
11180 bool NonTriviallyCopyableCXXRecord =
11184 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11187 PDiag(diag::warn_cstruct_memaccess)
11188 << ArgIdx << FnName << PointeeTy << 0);
11189 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11190 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11191 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11195 PDiag(diag::warn_cxxstruct_memaccess)
11196 << FnName << PointeeTy);
11197 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11200 PDiag(diag::warn_cstruct_memaccess)
11201 << ArgIdx << FnName << PointeeTy << 1);
11202 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11203 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11204 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11208 PDiag(diag::warn_cxxstruct_memaccess)
11209 << FnName << PointeeTy);
11218 PDiag(diag::note_bad_memaccess_silence)
11224bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11226 llvm::FoldingSetNodeID SizeOfArgID;
11232 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11235 QualType DestTy = Dest->
getType();
11236 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11242 if (SizeOfArgID == llvm::FoldingSetNodeID())
11245 llvm::FoldingSetNodeID DestID;
11247 if (DestID == SizeOfArgID) {
11250 unsigned ActionIdx = 0;
11251 StringRef ReadableName = FnName->
getName();
11253 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11254 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11263 SourceLocation SL = SizeOfArg->
getExprLoc();
11268 if (
SM.isMacroArgExpansion(SL)) {
11270 SL =
SM.getSpellingLoc(SL);
11271 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
11273 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
11278 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11279 << ReadableName << PointeeTy << DestTy << DSR
11282 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11283 << ActionIdx << SSR);
11319 if (CAT->getZExtSize() <= 1)
11327void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11331 unsigned NumArgs =
Call->getNumArgs();
11332 if ((NumArgs != 3) && (NumArgs != 4))
11337 const Expr *CompareWithSrc =
nullptr;
11340 Call->getBeginLoc(),
Call->getRParenLoc()))
11345 CompareWithSrc = Ex;
11348 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11349 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11350 SizeCall->getNumArgs() == 1)
11355 if (!CompareWithSrc)
11362 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11366 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11367 if (!CompareWithSrcDRE ||
11371 const Expr *OriginalSizeArg =
Call->getArg(2);
11372 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11379 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11383 SmallString<128> sizeString;
11384 llvm::raw_svector_ostream
OS(sizeString);
11389 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11396 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11397 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11398 return D1->getDecl() == D2->getDecl();
11403 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11412void Sema::CheckStrncatArguments(
const CallExpr *CE,
11427 unsigned PatternType = 0;
11435 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11436 if (BE->getOpcode() == BO_Sub) {
11437 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11438 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11449 if (PatternType == 0)
11458 if (
SM.isMacroArgExpansion(SL)) {
11459 SL =
SM.getSpellingLoc(SL);
11460 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11465 QualType DstTy = DstArg->
getType();
11468 if (!isKnownSizeArray) {
11469 if (PatternType == 1)
11470 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11472 Diag(SL, diag::warn_strncat_src_size) << SR;
11476 if (PatternType == 1)
11477 Diag(SL, diag::warn_strncat_large_size) << SR;
11479 Diag(SL, diag::warn_strncat_src_size) << SR;
11481 SmallString<128> sizeString;
11482 llvm::raw_svector_ostream
OS(sizeString);
11490 Diag(SL, diag::note_strncat_wrong_size)
11495void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11504void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11506 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11507 const Decl *D = Lvalue->getDecl();
11508 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11509 if (!DD->getType()->isReferenceType())
11510 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11514 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11515 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11516 Lvalue->getMemberDecl());
11519void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11521 const auto *Lambda = dyn_cast<LambdaExpr>(
11526 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11527 << CalleeName << 2 ;
11530void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11532 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11533 if (Var ==
nullptr)
11537 << CalleeName << 0 << Var;
11540void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11543 llvm::raw_svector_ostream
OS(SizeString);
11546 if (Kind == clang::CK_BitCast &&
11547 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11549 if (Kind == clang::CK_IntegralToPointer &&
11551 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11554 switch (
Cast->getCastKind()) {
11555 case clang::CK_BitCast:
11556 case clang::CK_IntegralToPointer:
11557 case clang::CK_FunctionToPointerDecay:
11566 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11567 << CalleeName << 0 <<
OS.str();
11571void Sema::CheckFreeArguments(
const CallExpr *E) {
11572 const std::string CalleeName =
11577 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11579 case UnaryOperator::Opcode::UO_AddrOf:
11580 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11581 case UnaryOperator::Opcode::UO_Plus:
11582 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11587 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11589 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11591 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11592 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11593 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11599 << CalleeName << 1 ;
11604 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11605 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11609Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11618 Diag(ReturnLoc, diag::warn_null_ret)
11628 if (Op == OO_New || Op == OO_Array_New) {
11629 const FunctionProtoType *Proto
11633 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11639 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11644 if (
Context.getTargetInfo().getTriple().isPPC64())
11656 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11657 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11658 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11659 return FPLiteral && FPCast;
11662 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11668 llvm::APFloat TargetC = FPLiteral->
getValue();
11669 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11670 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11674 Diag(Loc, diag::warn_float_compare_literal)
11675 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11688 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11689 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11690 if (DRL->getDecl() == DRR->getDecl())
11698 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11699 if (FLL->isExact())
11701 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11702 if (FLR->isExact())
11706 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11707 CL &&
CL->getBuiltinCallee())
11710 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11711 CR && CR->getBuiltinCallee())
11715 Diag(Loc, diag::warn_floatingpoint_eq)
11736 IntRange(
unsigned Width,
bool NonNegative)
11737 : Width(Width), NonNegative(NonNegative) {}
11740 unsigned valueBits()
const {
11741 return NonNegative ? Width : Width - 1;
11745 static IntRange forBoolType() {
11746 return IntRange(1,
true);
11750 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11751 return forValueOfCanonicalType(
C,
11756 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11759 if (
const auto *VT = dyn_cast<VectorType>(
T))
11760 T = VT->getElementType().getTypePtr();
11761 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11762 T = MT->getElementType().getTypePtr();
11763 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11764 T = CT->getElementType().getTypePtr();
11765 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11766 T = AT->getValueType().getTypePtr();
11767 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11768 T = OBT->getUnderlyingType().getTypePtr();
11770 if (!
C.getLangOpts().CPlusPlus) {
11773 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11778 if (
Enum->isFixed()) {
11779 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11780 !
Enum->getIntegerType()->isSignedIntegerType());
11783 unsigned NumPositive =
Enum->getNumPositiveBits();
11784 unsigned NumNegative =
Enum->getNumNegativeBits();
11786 if (NumNegative == 0)
11787 return IntRange(NumPositive,
true);
11789 return IntRange(std::max(NumPositive + 1, NumNegative),
11793 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11794 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11807 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11810 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11811 T = VT->getElementType().getTypePtr();
11812 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11813 T = MT->getElementType().getTypePtr();
11814 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11815 T = CT->getElementType().getTypePtr();
11816 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11817 T = AT->getValueType().getTypePtr();
11819 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11820 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11821 T = OBT->getUnderlyingType().getTypePtr();
11823 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11824 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11833 static IntRange
join(IntRange L, IntRange R) {
11834 bool Unsigned = L.NonNegative &&
R.NonNegative;
11835 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11836 L.NonNegative &&
R.NonNegative);
11840 static IntRange bit_and(IntRange L, IntRange R) {
11841 unsigned Bits = std::max(L.Width,
R.Width);
11842 bool NonNegative =
false;
11843 if (L.NonNegative) {
11844 Bits = std::min(Bits, L.Width);
11845 NonNegative =
true;
11847 if (
R.NonNegative) {
11848 Bits = std::min(Bits,
R.Width);
11849 NonNegative =
true;
11851 return IntRange(Bits, NonNegative);
11855 static IntRange sum(IntRange L, IntRange R) {
11856 bool Unsigned = L.NonNegative &&
R.NonNegative;
11857 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11862 static IntRange difference(IntRange L, IntRange R) {
11866 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11867 bool Unsigned = L.NonNegative &&
R.Width == 0;
11868 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11874 static IntRange product(IntRange L, IntRange R) {
11878 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11879 bool Unsigned = L.NonNegative &&
R.NonNegative;
11880 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11885 static IntRange rem(IntRange L, IntRange R) {
11889 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11897 if (value.isSigned() && value.isNegative())
11898 return IntRange(value.getSignificantBits(),
false);
11900 if (value.getBitWidth() > MaxWidth)
11901 value = value.trunc(MaxWidth);
11905 return IntRange(value.getActiveBits(),
true);
11909 if (result.
isInt())
11916 R = IntRange::join(R, El);
11924 return IntRange::join(R, I);
11939 Ty = AtomicRHS->getValueType();
11958 bool InConstantContext,
11959 bool Approximate) {
11970 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11971 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11975 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11977 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11978 CE->getCastKind() == CK_BooleanToSignedIntegral;
11981 if (!isIntegerCast)
11982 return OutputTypeRange;
11985 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11986 InConstantContext, Approximate);
11988 return std::nullopt;
11991 if (SubRange->Width >= OutputTypeRange.Width)
11992 return OutputTypeRange;
11996 return IntRange(SubRange->Width,
11997 SubRange->NonNegative || OutputTypeRange.NonNegative);
12000 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12003 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12005 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12006 InConstantContext, Approximate);
12011 Expr *TrueExpr = CO->getTrueExpr();
12013 return std::nullopt;
12015 std::optional<IntRange> L =
12018 return std::nullopt;
12020 Expr *FalseExpr = CO->getFalseExpr();
12022 return std::nullopt;
12024 std::optional<IntRange> R =
12027 return std::nullopt;
12029 return IntRange::join(*L, *R);
12032 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12033 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12035 switch (BO->getOpcode()) {
12037 llvm_unreachable(
"builtin <=> should have class type");
12048 return IntRange::forBoolType();
12077 Combine = IntRange::bit_and;
12085 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12086 if (I->getValue() == 1) {
12087 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12088 return IntRange(R.Width,
true);
12098 case BO_ShrAssign: {
12100 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12102 return std::nullopt;
12106 if (std::optional<llvm::APSInt> shift =
12107 BO->getRHS()->getIntegerConstantExpr(
C)) {
12108 if (shift->isNonNegative()) {
12109 if (shift->uge(L->Width))
12110 L->Width = (L->NonNegative ? 0 : 1);
12112 L->Width -= shift->getZExtValue();
12126 Combine = IntRange::sum;
12130 if (BO->getLHS()->getType()->isPointerType())
12133 Combine = IntRange::difference;
12138 Combine = IntRange::product;
12147 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12149 return std::nullopt;
12152 if (std::optional<llvm::APSInt> divisor =
12153 BO->getRHS()->getIntegerConstantExpr(
C)) {
12154 unsigned log2 = divisor->logBase2();
12155 if (
log2 >= L->Width)
12156 L->Width = (L->NonNegative ? 0 : 1);
12158 L->Width = std::min(L->Width -
log2, MaxWidth);
12166 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12168 return std::nullopt;
12170 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12174 Combine = IntRange::rem;
12186 unsigned opWidth =
C.getIntWidth(
T);
12188 InConstantContext, Approximate);
12190 return std::nullopt;
12193 InConstantContext, Approximate);
12195 return std::nullopt;
12197 IntRange
C = Combine(*L, *R);
12198 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12199 C.Width = std::min(
C.Width, MaxWidth);
12203 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12204 switch (UO->getOpcode()) {
12207 return IntRange::forBoolType();
12221 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12224 return std::nullopt;
12229 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12239 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12242 return std::nullopt;
12247 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12257 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12258 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
12262 return IntRange(BitField->getBitWidthValue(),
12263 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12266 return std::nullopt;
12272 bool InConstantContext,
12273 bool Approximate) {
12282 const llvm::fltSemantics &Src,
12283 const llvm::fltSemantics &Tgt) {
12284 llvm::APFloat truncated = value;
12287 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12288 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12290 return truncated.bitwiseIsEqual(value);
12299 const llvm::fltSemantics &Src,
12300 const llvm::fltSemantics &Tgt) {
12324 bool IsListInit =
false);
12339 return MacroName !=
"YES" && MacroName !=
"NO" &&
12340 MacroName !=
"true" && MacroName !=
"false";
12348 (!E->
getType()->isSignedIntegerType() ||
12363struct PromotedRange {
12365 llvm::APSInt PromotedMin;
12367 llvm::APSInt PromotedMax;
12369 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12371 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12372 else if (
R.Width >= BitWidth && !
Unsigned) {
12376 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12377 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12379 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12380 .extOrTrunc(BitWidth);
12381 PromotedMin.setIsUnsigned(
Unsigned);
12383 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12384 .extOrTrunc(BitWidth);
12385 PromotedMax.setIsUnsigned(
Unsigned);
12390 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12400 InRangeFlag = 0x40,
12403 Min =
LE | InRangeFlag,
12404 InRange = InRangeFlag,
12405 Max =
GE | InRangeFlag,
12408 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12413 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12414 Value.isUnsigned() == PromotedMin.isUnsigned());
12415 if (!isContiguous()) {
12416 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12417 if (
Value.isMinValue())
return Min;
12418 if (
Value.isMaxValue())
return Max;
12419 if (
Value >= PromotedMin)
return InRange;
12420 if (
Value <= PromotedMax)
return InRange;
12424 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12425 case -1:
return Less;
12426 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12428 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12429 case -1:
return InRange;
12430 case 0:
return Max;
12435 llvm_unreachable(
"impossible compare result");
12438 static std::optional<StringRef>
12440 if (Op == BO_Cmp) {
12442 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12444 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12445 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12446 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12447 return std::nullopt;
12454 }
else if (Op == BO_NE) {
12458 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12465 if (Op == BO_GE || Op == BO_LE)
12466 std::swap(TrueFlag, FalseFlag);
12469 return StringRef(
"true");
12471 return StringRef(
"false");
12472 return std::nullopt;
12479 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12480 if (ICE->getCastKind() != CK_IntegralCast &&
12481 ICE->getCastKind() != CK_NoOp)
12483 E = ICE->getSubExpr();
12492 enum ConstantValueKind {
12497 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12498 return BL->getValue() ? ConstantValueKind::LiteralTrue
12499 : ConstantValueKind::LiteralFalse;
12500 return ConstantValueKind::Miscellaneous;
12505 const llvm::APSInt &
Value,
12506 bool RhsConstant) {
12522 if (
Constant->getType()->isEnumeralType() &&
12528 if (!OtherValueRange)
12533 OtherT = AT->getValueType();
12534 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12538 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12544 bool OtherIsBooleanDespiteType =
12546 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12547 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12551 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12552 Value.isUnsigned());
12553 auto Cmp = OtherPromotedValueRange.compare(
Value);
12560 bool TautologicalTypeCompare =
false;
12562 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12563 Value.isUnsigned());
12564 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12567 TautologicalTypeCompare =
true;
12575 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12584 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12590 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12591 Other->getType()->isUnsignedIntegerOrEnumerationType())
12592 TautologicalTypeCompare =
true;
12597 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12598 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12602 llvm::raw_svector_ostream OS(PrettySourceValue);
12604 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12605 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12606 Constant->IgnoreParenImpCasts())) {
12607 OS << (BL->getValue() ?
"YES" :
"NO");
12612 if (!TautologicalTypeCompare) {
12614 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12620 if (IsObjCSignedCharBool) {
12622 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12623 << OS.str() << *
Result);
12630 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12634 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12635 : diag::warn_tautological_bool_compare)
12637 << OtherIsBooleanDespiteType << *
Result
12644 ? diag::warn_unsigned_enum_always_true_comparison
12645 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12646 : diag::warn_unsigned_always_true_comparison)
12647 : diag::warn_tautological_constant_compare;
12683 if (
T->isIntegralType(S.
Context)) {
12684 std::optional<llvm::APSInt> RHSValue =
12686 std::optional<llvm::APSInt> LHSValue =
12690 if (RHSValue && LHSValue)
12694 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12696 const bool RhsConstant = (
bool)RHSValue;
12697 Expr *Const = RhsConstant ? RHS : LHS;
12699 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12708 if (!
T->hasUnsignedIntegerRepresentation()) {
12722 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12724 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12730 Expr *signedOperand, *unsignedOperand;
12733 "unsigned comparison between two signed integer expressions?");
12734 signedOperand = LHS;
12735 unsignedOperand = RHS;
12737 signedOperand = RHS;
12738 unsignedOperand = LHS;
12744 std::optional<IntRange> signedRange =
12756 if (signedRange->NonNegative)
12768 if (!unsignedRange)
12773 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12775 if (unsignedRange->Width < comparisonWidth)
12780 S.
PDiag(diag::warn_mixed_sign_comparison)
12799 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12804 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12805 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12806 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12807 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12808 << BitfieldEnumDecl;
12815 Init->isValueDependent() ||
12816 Init->isTypeDependent())
12819 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12829 const PreferredTypeAttr *PTAttr =
nullptr;
12831 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12833 ED = PTAttr->getType()->getAsEnumDecl();
12841 bool SignedEnum = ED->getNumNegativeBits() > 0;
12848 unsigned DiagID = 0;
12849 if (SignedEnum && !SignedBitfield) {
12852 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12854 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12855 }
else if (SignedBitfield && !SignedEnum &&
12856 ED->getNumPositiveBits() == FieldWidth) {
12859 ? diag::warn_signed_bitfield_enum_conversion
12860 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12863 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12868 << SignedEnum << TypeRange;
12870 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12877 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12878 ED->getNumNegativeBits())
12879 : ED->getNumPositiveBits();
12882 if (BitsNeeded > FieldWidth) {
12886 ? diag::warn_bitfield_too_small_for_enum
12887 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12888 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12892 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12902 unsigned OriginalWidth =
Value.getBitWidth();
12908 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12909 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12916 if (!
Value.isSigned() ||
Value.isNegative())
12917 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12918 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12919 OriginalWidth =
Value.getSignificantBits();
12921 if (OriginalWidth <= FieldWidth)
12925 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12929 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12930 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12934 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12936 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12937 ? diag::warn_impcast_single_bit_bitield_precision_constant
12938 : diag::warn_impcast_bitfield_precision_constant)
12939 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12940 <<
Init->getSourceRange();
12977 bool PruneControlFlow =
false) {
12984 if (
T.hasAddressSpace())
12986 if (PruneControlFlow) {
13000 bool PruneControlFlow =
false) {
13007 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13012 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13013 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13018 llvm::APFloat
Value(0.0);
13024 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13029 diag::warn_impcast_float_integer, PruneWarnings);
13032 bool isExact =
false;
13035 T->hasUnsignedIntegerRepresentation());
13036 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13037 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13045 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13046 precision = (precision * 59 + 195) / 196;
13047 Value.toString(PrettySourceValue, precision);
13051 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13052 << PrettySourceValue);
13055 if (
Result == llvm::APFloat::opOK && isExact) {
13056 if (IsLiteral)
return;
13057 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13063 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13066 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13067 : diag::warn_impcast_float_to_integer_out_of_range,
13070 unsigned DiagID = 0;
13073 DiagID = diag::warn_impcast_literal_float_to_integer;
13074 }
else if (IntegerValue == 0) {
13075 if (
Value.isZero()) {
13077 diag::warn_impcast_float_integer, PruneWarnings);
13080 DiagID = diag::warn_impcast_float_to_integer_zero;
13082 if (IntegerValue.isUnsigned()) {
13083 if (!IntegerValue.isMaxValue()) {
13085 diag::warn_impcast_float_integer, PruneWarnings);
13088 if (!IntegerValue.isMaxSignedValue() &&
13089 !IntegerValue.isMinSignedValue()) {
13091 diag::warn_impcast_float_integer, PruneWarnings);
13095 DiagID = diag::warn_impcast_float_to_integer;
13100 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13102 IntegerValue.toString(PrettyTargetValue);
13104 if (PruneWarnings) {
13107 << E->
getType() <<
T.getUnqualifiedType()
13108 << PrettySourceValue << PrettyTargetValue
13112 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13121 "Must be compound assignment operation");
13132 ->getComputationResultType()
13139 if (ResultBT->isInteger())
13141 E->
getExprLoc(), diag::warn_impcast_float_integer);
13143 if (!ResultBT->isFloatingPoint())
13152 diag::warn_impcast_float_result_precision);
13157 if (!Range.Width)
return "0";
13159 llvm::APSInt ValueInRange =
Value;
13160 ValueInRange.setIsSigned(!Range.NonNegative);
13161 ValueInRange = ValueInRange.trunc(Range.Width);
13162 return toString(ValueInRange, 10);
13172 const Type *Source =
13174 if (
Target->isDependentType())
13177 const auto *FloatCandidateBT =
13178 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13179 const Type *BoolCandidateType = ToBool ?
Target : Source;
13182 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13187 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13193 S, TheCall->
getArg(I - 1),
false));
13195 S, TheCall->
getArg(I + 1),
false));
13200 diag::warn_impcast_floating_point_to_bool);
13215 if (!IsGNUNullExpr && !HasNullPtrType)
13219 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13220 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13223 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13236 if (IsGNUNullExpr && Loc.
isMacroID()) {
13239 if (MacroName ==
"NULL")
13247 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13261 const char FirstLiteralCharacter =
13263 if (FirstLiteralCharacter ==
'0')
13269 if (CC.
isValid() &&
T->isCharType()) {
13270 const char FirstContextCharacter =
13272 if (FirstContextCharacter ==
'{')
13280 const auto *IL = dyn_cast<IntegerLiteral>(E);
13282 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13283 if (UO->getOpcode() == UO_Minus)
13284 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13295 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13299 if (Opc == BO_Shl) {
13302 if (LHS && LHS->getValue() == 0)
13303 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13305 RHS->getValue().isNonNegative() &&
13307 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13308 << (
Result.Val.getInt() != 0);
13310 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13317 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13322 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13323 (RHS->getValue() == 0 || RHS->getValue() == 1))
13326 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13327 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13335 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13341 if (Source->isChar16Type() &&
Target->isChar32Type())
13347 llvm::APSInt
Value(32);
13349 bool IsASCII =
Value <= 0x7F;
13350 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13351 bool ConversionPreservesSemantics =
13352 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13354 if (!ConversionPreservesSemantics) {
13355 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13356 const llvm::APSInt &
Value) {
13357 if (
T->isChar8Type())
13358 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13359 if (
T->isChar16Type())
13360 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13361 assert(
T->isChar32Type());
13362 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13365 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13374 LosesPrecision ? diag::warn_impcast_unicode_precision
13375 : diag::warn_impcast_unicode_char_type);
13380 From =
Context.getCanonicalType(From);
13381 To =
Context.getCanonicalType(To);
13384 From = MaybePointee;
13391 if (FromFn->getCFIUncheckedCalleeAttr() &&
13392 !ToFn->getCFIUncheckedCalleeAttr())
13400 bool *ICContext,
bool IsListInit) {
13405 if (Source ==
Target)
return;
13406 if (
Target->isDependentType())
return;
13416 if (Source->isAtomicType())
13420 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13426 diag::warn_impcast_string_literal_to_bool);
13432 diag::warn_impcast_objective_c_literal_to_bool);
13434 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13446 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13449 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13451 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13460 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13462 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13473 diag::err_impcast_incompatible_type);
13478 ? diag::err_impcast_complex_scalar
13479 : diag::warn_impcast_complex_scalar);
13488 if (
Target->isSveVLSBuiltinType() &&
13495 if (
Target->isRVVVLSBuiltinType() &&
13505 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13513 diag::warn_hlsl_impcast_vector_truncation);
13525 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13526 Target = VecTy->getElementType().getTypePtr();
13530 if (
Target->isScalarType())
13531 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13539 diag::warn_hlsl_impcast_matrix_truncation);
13545 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13546 Target = MatTy->getElementType().getTypePtr();
13548 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13554 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13557 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13559 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13601 else if (Order < 0) {
13611 if (TargetBT && TargetBT->
isInteger()) {
13638 diag::warn_impcast_floating_point_to_bool);
13646 if (Source->isFixedPointType()) {
13647 if (
Target->isUnsaturatedFixedPointType()) {
13651 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13652 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13653 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13656 PDiag(diag::warn_impcast_fixed_point_range)
13657 <<
Value.toString() <<
T
13663 }
else if (
Target->isIntegerType()) {
13667 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13670 llvm::APSInt IntResult = FXResult.convertToInt(
13671 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13676 PDiag(diag::warn_impcast_fixed_point_range)
13677 << FXResult.toString() <<
T
13684 }
else if (
Target->isUnsaturatedFixedPointType()) {
13685 if (Source->isIntegerType()) {
13692 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13697 PDiag(diag::warn_impcast_fixed_point_range)
13718 unsigned int SourcePrecision =
SourceRange->Width;
13722 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13725 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13726 SourcePrecision > TargetPrecision) {
13728 if (std::optional<llvm::APSInt> SourceInt =
13733 llvm::APFloat TargetFloatValue(
13735 llvm::APFloat::opStatus ConversionStatus =
13736 TargetFloatValue.convertFromAPInt(
13738 llvm::APFloat::rmNearestTiesToEven);
13740 if (ConversionStatus != llvm::APFloat::opOK) {
13742 SourceInt->toString(PrettySourceValue, 10);
13744 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13748 PDiag(diag::warn_impcast_integer_float_precision_constant)
13749 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13755 diag::warn_impcast_integer_float_precision);
13764 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13769 if (
Target->isBooleanType())
13773 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13777 if (!Source->isIntegerType() || !
Target->isIntegerType())
13782 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13785 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13788 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13793 if (!LikelySourceRange)
13796 IntRange SourceTypeRange =
13797 IntRange::forTargetOfCanonicalType(
Context, Source);
13798 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13800 if (LikelySourceRange->Width > TargetRange.Width) {
13804 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13805 if (TargetOBT->isWrapKind()) {
13812 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13813 if (SourceOBT->isWrapKind()) {
13823 llvm::APSInt
Value(32);
13833 PDiag(diag::warn_impcast_integer_precision_constant)
13834 << PrettySourceValue << PrettyTargetValue
13844 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13845 if (UO->getOpcode() == UO_Minus)
13847 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13850 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13854 diag::warn_impcast_integer_precision);
13857 if (TargetRange.Width > SourceTypeRange.Width) {
13858 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13859 if (UO->getOpcode() == UO_Minus)
13860 if (Source->isUnsignedIntegerType()) {
13861 if (
Target->isUnsignedIntegerType())
13863 diag::warn_impcast_high_order_zero_bits);
13864 if (
Target->isSignedIntegerType())
13866 diag::warn_impcast_nonnegative_result);
13870 if (TargetRange.Width == LikelySourceRange->Width &&
13871 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13872 Source->isSignedIntegerType()) {
13886 PDiag(diag::warn_impcast_integer_precision_constant)
13887 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13897 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13898 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13899 LikelySourceRange->Width == TargetRange.Width))) {
13903 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13905 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13909 unsigned DiagID = diag::warn_impcast_integer_sign;
13917 DiagID = diag::warn_impcast_integer_sign_conditional;
13934 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13936 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13937 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13938 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13939 TargetEnum->getDecl()->hasNameForLinkage() &&
13940 SourceEnum != TargetEnum) {
13945 diag::warn_impcast_different_enum_types);
13959 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13972 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13973 TrueExpr = BCO->getCommon();
13975 bool Suspicious =
false;
13979 if (
T->isBooleanType())
13984 if (!Suspicious)
return;
13987 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13994 Suspicious =
false;
13999 E->
getType(), CC, &Suspicious);
14016struct AnalyzeImplicitConversionsWorkItem {
14025 bool ExtraCheckForImplicitConversion,
14028 WorkList.push_back({E, CC,
false});
14030 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14037 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14039 Expr *OrigE = Item.E;
14058 Expr *SourceExpr = E;
14063 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14064 if (
auto *Src = OVE->getSourceExpr())
14067 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14068 if (UO->getOpcode() == UO_Not &&
14069 UO->getSubExpr()->isKnownToHaveBooleanValue())
14070 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14074 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14075 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14076 BO->getLHS()->isKnownToHaveBooleanValue() &&
14077 BO->getRHS()->isKnownToHaveBooleanValue() &&
14078 BO->getLHS()->HasSideEffects(S.
Context) &&
14079 BO->getRHS()->HasSideEffects(S.
Context)) {
14090 if (SR.str() ==
"&" || SR.str() ==
"|") {
14092 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14093 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14096 BO->getOperatorLoc(),
14097 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14098 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14100 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14118 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14124 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14139 for (
auto *SE : POE->semantics())
14140 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14141 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14145 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14146 E = CE->getSubExpr();
14152 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14153 if (InitListE->getNumInits() == 1) {
14154 E = InitListE->getInit(0);
14161 WorkList.push_back({E, CC, IsListInit});
14165 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14166 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14170 if (OutArgE->isInOut())
14171 WorkList.push_back(
14172 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14173 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14179 if (BO->isComparisonOp())
14183 if (BO->getOpcode() == BO_Assign)
14186 if (BO->isAssignmentOp())
14202 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14204 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14208 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14209 if (ChildExpr == CSE->getOperand())
14215 if (IsLogicalAndOperator &&
14220 WorkList.push_back({ChildExpr, CC, IsListInit});
14234 if (
U->getOpcode() == UO_LNot) {
14236 }
else if (
U->getOpcode() != UO_AddrOf) {
14237 if (
U->getSubExpr()->getType()->isAtomicType())
14238 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14239 diag::warn_atomic_implicit_seq_cst);
14250 WorkList.push_back({OrigE, CC, IsListInit});
14251 while (!WorkList.empty())
14263 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14266 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14267 if (!M->getMemberDecl()->getType()->isReferenceType())
14269 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14270 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14272 FD =
Call->getDirectCallee();
14281 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14295 if (
SM.isMacroBodyExpansion(Loc))
14297 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14321 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14322 : diag::warn_this_bool_conversion;
14327 bool IsAddressOf =
false;
14329 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14330 if (UO->getOpcode() != UO_AddrOf)
14332 IsAddressOf =
true;
14333 E = UO->getSubExpr();
14337 unsigned DiagID = IsCompare
14338 ? diag::warn_address_of_reference_null_compare
14339 : diag::warn_address_of_reference_bool_conversion;
14347 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14350 llvm::raw_string_ostream S(Str);
14352 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14353 : diag::warn_cast_nonnull_to_bool;
14356 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14361 if (
auto *Callee =
Call->getDirectCallee()) {
14362 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14363 ComplainAboutNonnullParamOrCall(A);
14372 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14373 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14374 MRecordDecl && MRecordDecl->isLambda()) {
14377 << MRecordDecl->getSourceRange() << Range << IsEqual;
14387 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14388 D = M->getMemberDecl();
14396 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14399 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14400 ComplainAboutNonnullParamOrCall(A);
14404 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14408 auto ParamIter = llvm::find(FD->
parameters(), PV);
14410 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14414 ComplainAboutNonnullParamOrCall(
NonNull);
14419 if (ArgNo.getASTIndex() == ParamNo) {
14420 ComplainAboutNonnullParamOrCall(
NonNull);
14431 const bool IsFunctionReference =
14432 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14433 if (IsFunctionReference)
14434 T =
T->getPointeeType();
14435 const bool IsArray =
T->isArrayType();
14436 const bool IsFunction =
T->isFunctionType();
14439 if (IsAddressOf && IsFunction) {
14444 if (!IsAddressOf && !IsFunction && !IsArray)
14449 llvm::raw_string_ostream S(Str);
14452 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14453 : diag::warn_impcast_pointer_to_bool;
14460 DiagType = AddressOf;
14461 else if (IsFunction)
14462 DiagType = FunctionPointer;
14464 DiagType = ArrayPointer;
14466 llvm_unreachable(
"Could not determine diagnostic.");
14468 << Range << IsEqual;
14471 if (!IsFunction || IsFunctionReference)
14482 if (ReturnType.
isNull())
14513 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14514 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14516 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14517 Target->isUnsignedIntegerType()) {
14521 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14522 : diag::warn_impcast_overflow_behavior_pedantic;
14526 ? diag::warn_impcast_overflow_behavior_assignment
14527 : diag::warn_impcast_overflow_behavior;
14533 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14534 if (TargetOBT->isWrapKind()) {
14554 CheckArrayAccess(E);
14564void Sema::CheckForIntOverflow (
const Expr *E) {
14566 SmallVector<const Expr *, 2> Exprs(1, E);
14569 const Expr *OriginalE = Exprs.pop_back_val();
14578 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14579 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14582 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14583 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14584 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14586 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14587 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14588 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14589 Exprs.push_back(Temporary->getSubExpr());
14590 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14591 Exprs.push_back(
Array->getIdx());
14592 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14593 Exprs.push_back(Compound->getInitializer());
14594 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14595 New &&
New->isArray()) {
14596 if (
auto ArraySize =
New->getArraySize())
14597 Exprs.push_back(*ArraySize);
14598 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14599 Exprs.push_back(MTE->getSubExpr());
14600 }
while (!Exprs.empty());
14608 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14615 class SequenceTree {
14617 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14618 unsigned Parent : 31;
14619 LLVM_PREFERRED_TYPE(
bool)
14620 unsigned Merged : 1;
14622 SmallVector<Value, 8> Values;
14628 friend class SequenceTree;
14632 explicit Seq(
unsigned N) : Index(N) {}
14635 Seq() : Index(0) {}
14638 SequenceTree() { Values.push_back(
Value(0)); }
14639 Seq root()
const {
return Seq(0); }
14644 Seq allocate(
Seq Parent) {
14645 Values.push_back(
Value(Parent.Index));
14646 return Seq(Values.size() - 1);
14651 Values[S.Index].Merged =
true;
14657 bool isUnsequenced(
Seq Cur,
Seq Old) {
14658 unsigned C = representative(Cur.Index);
14659 unsigned Target = representative(Old.Index);
14663 C = Values[
C].Parent;
14670 unsigned representative(
unsigned K) {
14671 if (Values[K].Merged)
14673 return Values[K].Parent = representative(Values[K].Parent);
14679 using Object =
const NamedDecl *;
14693 UK_ModAsSideEffect,
14695 UK_Count = UK_ModAsSideEffect + 1
14701 const Expr *UsageExpr =
nullptr;
14702 SequenceTree::Seq
Seq;
14708 Usage Uses[UK_Count];
14711 bool Diagnosed =
false;
14715 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14723 UsageInfoMap UsageMap;
14726 SequenceTree::Seq Region;
14730 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14734 SmallVectorImpl<const Expr *> &WorkList;
14741 struct SequencedSubexpression {
14742 SequencedSubexpression(SequenceChecker &
Self)
14743 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14744 Self.ModAsSideEffect = &ModAsSideEffect;
14747 ~SequencedSubexpression() {
14748 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14752 UsageInfo &UI =
Self.UsageMap[M.first];
14753 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14754 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14755 SideEffectUsage = M.second;
14757 Self.ModAsSideEffect = OldModAsSideEffect;
14760 SequenceChecker &
Self;
14761 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14762 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14769 class EvaluationTracker {
14771 EvaluationTracker(SequenceChecker &
Self)
14773 Self.EvalTracker =
this;
14776 ~EvaluationTracker() {
14777 Self.EvalTracker = Prev;
14779 Prev->EvalOK &= EvalOK;
14782 bool evaluate(
const Expr *E,
bool &
Result) {
14787 Self.SemaRef.isConstantEvaluatedContext());
14792 SequenceChecker &
Self;
14793 EvaluationTracker *Prev;
14794 bool EvalOK =
true;
14795 } *EvalTracker =
nullptr;
14799 Object getObject(
const Expr *E,
bool Mod)
const {
14801 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14802 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14803 return getObject(UO->getSubExpr(), Mod);
14804 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14805 if (BO->getOpcode() == BO_Comma)
14806 return getObject(BO->getRHS(), Mod);
14807 if (Mod && BO->isAssignmentOp())
14808 return getObject(BO->getLHS(), Mod);
14809 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14812 return ME->getMemberDecl();
14813 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14822 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14824 Usage &U = UI.Uses[UK];
14825 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14829 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14830 ModAsSideEffect->push_back(std::make_pair(O, U));
14832 U.UsageExpr = UsageExpr;
14842 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14843 UsageKind OtherKind,
bool IsModMod) {
14847 const Usage &U = UI.Uses[OtherKind];
14848 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14851 const Expr *Mod = U.UsageExpr;
14852 const Expr *ModOrUse = UsageExpr;
14853 if (OtherKind == UK_Use)
14854 std::swap(Mod, ModOrUse);
14858 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14859 : diag::warn_unsequenced_mod_use)
14860 << O << SourceRange(ModOrUse->
getExprLoc()));
14861 UI.Diagnosed =
true;
14890 void notePreUse(
Object O,
const Expr *UseExpr) {
14891 UsageInfo &UI = UsageMap[O];
14893 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14896 void notePostUse(
Object O,
const Expr *UseExpr) {
14897 UsageInfo &UI = UsageMap[O];
14898 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14900 addUsage(O, UI, UseExpr, UK_Use);
14903 void notePreMod(
Object O,
const Expr *ModExpr) {
14904 UsageInfo &UI = UsageMap[O];
14906 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14907 checkUsage(O, UI, ModExpr, UK_Use,
false);
14910 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14911 UsageInfo &UI = UsageMap[O];
14912 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14914 addUsage(O, UI, ModExpr, UK);
14918 SequenceChecker(Sema &S,
const Expr *E,
14919 SmallVectorImpl<const Expr *> &WorkList)
14920 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14924 (void)this->WorkList;
14927 void VisitStmt(
const Stmt *S) {
14931 void VisitExpr(
const Expr *E) {
14933 Base::VisitStmt(E);
14936 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14937 for (
auto *Sub : CSE->
children()) {
14938 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14953 void VisitCastExpr(
const CastExpr *E) {
14965 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14966 const Expr *SequencedAfter) {
14967 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14968 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14969 SequenceTree::Seq OldRegion = Region;
14972 SequencedSubexpression SeqBefore(*
this);
14973 Region = BeforeRegion;
14974 Visit(SequencedBefore);
14977 Region = AfterRegion;
14978 Visit(SequencedAfter);
14980 Region = OldRegion;
14982 Tree.merge(BeforeRegion);
14983 Tree.merge(AfterRegion);
14986 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14991 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14998 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14999 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15000 void VisitBinPtrMem(
const BinaryOperator *BO) {
15005 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15012 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15013 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15014 void VisitBinShlShr(
const BinaryOperator *BO) {
15018 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15025 void VisitBinComma(
const BinaryOperator *BO) {
15030 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15033 void VisitBinAssign(
const BinaryOperator *BO) {
15034 SequenceTree::Seq RHSRegion;
15035 SequenceTree::Seq LHSRegion;
15037 RHSRegion = Tree.allocate(Region);
15038 LHSRegion = Tree.allocate(Region);
15040 RHSRegion = Region;
15041 LHSRegion = Region;
15043 SequenceTree::Seq OldRegion = Region;
15059 SequencedSubexpression SeqBefore(*
this);
15060 Region = RHSRegion;
15064 Region = LHSRegion;
15068 notePostUse(O, BO);
15072 Region = LHSRegion;
15076 notePostUse(O, BO);
15078 Region = RHSRegion;
15086 Region = OldRegion;
15090 : UK_ModAsSideEffect);
15092 Tree.merge(RHSRegion);
15093 Tree.merge(LHSRegion);
15097 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15098 VisitBinAssign(CAO);
15101 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15102 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15103 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15106 return VisitExpr(UO);
15114 : UK_ModAsSideEffect);
15117 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15118 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15119 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15122 return VisitExpr(UO);
15126 notePostMod(O, UO, UK_ModAsSideEffect);
15129 void VisitBinLOr(
const BinaryOperator *BO) {
15135 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15136 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15137 SequenceTree::Seq OldRegion = Region;
15139 EvaluationTracker Eval(*
this);
15141 SequencedSubexpression Sequenced(*
this);
15142 Region = LHSRegion;
15149 bool EvalResult =
false;
15150 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15151 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15152 if (ShouldVisitRHS) {
15153 Region = RHSRegion;
15157 Region = OldRegion;
15158 Tree.merge(LHSRegion);
15159 Tree.merge(RHSRegion);
15162 void VisitBinLAnd(
const BinaryOperator *BO) {
15168 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15169 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15170 SequenceTree::Seq OldRegion = Region;
15172 EvaluationTracker Eval(*
this);
15174 SequencedSubexpression Sequenced(*
this);
15175 Region = LHSRegion;
15181 bool EvalResult =
false;
15182 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15183 bool ShouldVisitRHS = !EvalOK || EvalResult;
15184 if (ShouldVisitRHS) {
15185 Region = RHSRegion;
15189 Region = OldRegion;
15190 Tree.merge(LHSRegion);
15191 Tree.merge(RHSRegion);
15194 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15199 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15215 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15216 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15217 SequenceTree::Seq OldRegion = Region;
15219 EvaluationTracker Eval(*
this);
15221 SequencedSubexpression Sequenced(*
this);
15222 Region = ConditionRegion;
15232 bool EvalResult =
false;
15233 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15234 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15235 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15236 if (ShouldVisitTrueExpr) {
15237 Region = TrueRegion;
15240 if (ShouldVisitFalseExpr) {
15241 Region = FalseRegion;
15245 Region = OldRegion;
15246 Tree.merge(ConditionRegion);
15247 Tree.merge(TrueRegion);
15248 Tree.merge(FalseRegion);
15251 void VisitCallExpr(
const CallExpr *CE) {
15263 SequencedSubexpression Sequenced(*
this);
15268 SequenceTree::Seq CalleeRegion;
15269 SequenceTree::Seq OtherRegion;
15270 if (SemaRef.getLangOpts().CPlusPlus17) {
15271 CalleeRegion = Tree.allocate(Region);
15272 OtherRegion = Tree.allocate(Region);
15274 CalleeRegion = Region;
15275 OtherRegion = Region;
15277 SequenceTree::Seq OldRegion = Region;
15280 Region = CalleeRegion;
15282 SequencedSubexpression Sequenced(*this);
15283 Visit(CE->getCallee());
15285 Visit(CE->getCallee());
15289 Region = OtherRegion;
15293 Region = OldRegion;
15295 Tree.merge(CalleeRegion);
15296 Tree.merge(OtherRegion);
15314 return VisitCallExpr(CXXOCE);
15325 case OO_MinusEqual:
15327 case OO_SlashEqual:
15328 case OO_PercentEqual:
15329 case OO_CaretEqual:
15332 case OO_LessLessEqual:
15333 case OO_GreaterGreaterEqual:
15334 SequencingKind = RHSBeforeLHS;
15338 case OO_GreaterGreater:
15344 SequencingKind = LHSBeforeRHS;
15348 SequencingKind = LHSBeforeRest;
15352 SequencingKind = NoSequencing;
15356 if (SequencingKind == NoSequencing)
15357 return VisitCallExpr(CXXOCE);
15360 SequencedSubexpression Sequenced(*
this);
15363 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15364 "Should only get there with C++17 and above!");
15365 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15366 "Should only get there with an overloaded binary operator"
15367 " or an overloaded call operator!");
15369 if (SequencingKind == LHSBeforeRest) {
15370 assert(CXXOCE->getOperator() == OO_Call &&
15371 "We should only have an overloaded call operator here!");
15380 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15381 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15382 SequenceTree::Seq OldRegion = Region;
15384 assert(CXXOCE->getNumArgs() >= 1 &&
15385 "An overloaded call operator must have at least one argument"
15386 " for the postfix-expression!");
15387 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15388 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15389 CXXOCE->getNumArgs() - 1);
15393 Region = PostfixExprRegion;
15394 SequencedSubexpression Sequenced(*this);
15395 Visit(PostfixExpr);
15399 Region = ArgsRegion;
15400 for (const Expr *Arg : Args)
15403 Region = OldRegion;
15404 Tree.merge(PostfixExprRegion);
15405 Tree.merge(ArgsRegion);
15407 assert(CXXOCE->getNumArgs() == 2 &&
15408 "Should only have two arguments here!");
15409 assert((SequencingKind == LHSBeforeRHS ||
15410 SequencingKind == RHSBeforeLHS) &&
15411 "Unexpected sequencing kind!");
15415 const Expr *E1 = CXXOCE->getArg(0);
15416 const Expr *E2 = CXXOCE->getArg(1);
15417 if (SequencingKind == RHSBeforeLHS)
15420 return VisitSequencedExpressions(E1, E2);
15427 SequencedSubexpression Sequenced(*
this);
15430 return VisitExpr(CCE);
15433 SequenceExpressionsInOrder(
15439 return VisitExpr(ILE);
15442 SequenceExpressionsInOrder(ILE->
inits());
15454 SequenceTree::Seq Parent = Region;
15455 for (
const Expr *E : ExpressionList) {
15458 Region = Tree.allocate(Parent);
15459 Elts.push_back(Region);
15465 for (
unsigned I = 0; I < Elts.size(); ++I)
15466 Tree.merge(Elts[I]);
15470SequenceChecker::UsageInfo::UsageInfo() =
default;
15474void Sema::CheckUnsequencedOperations(
const Expr *E) {
15475 SmallVector<const Expr *, 8> WorkList;
15476 WorkList.push_back(E);
15477 while (!WorkList.empty()) {
15478 const Expr *Item = WorkList.pop_back_val();
15479 SequenceChecker(*
this, Item, WorkList);
15484 bool IsConstexpr) {
15487 CheckImplicitConversions(E, CheckLoc);
15489 CheckUnsequencedOperations(E);
15491 CheckForIntOverflow(E);
15504 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15508 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15512 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15526 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15530 bool CheckParameterNames) {
15531 bool HasInvalidParm =
false;
15533 assert(Param &&
"null in a parameter list");
15542 if (!Param->isInvalidDecl() &&
15544 diag::err_typecheck_decl_incomplete_type) ||
15546 diag::err_abstract_type_in_decl,
15548 Param->setInvalidDecl();
15549 HasInvalidParm =
true;
15554 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15558 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15566 QualType PType = Param->getOriginalType();
15574 if (!Param->isInvalidDecl()) {
15575 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15576 if (!ClassDecl->isInvalidDecl() &&
15577 !ClassDecl->hasIrrelevantDestructor() &&
15578 !ClassDecl->isDependentContext() &&
15579 ClassDecl->isParamDestroyedInCallee()) {
15591 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15592 if (!Param->getType().isConstQualified())
15593 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15597 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15602 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15603 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15608 if (!Param->isInvalidDecl() &&
15609 Param->getOriginalType()->isWebAssemblyTableType()) {
15610 Param->setInvalidDecl();
15611 HasInvalidParm =
true;
15612 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15616 return HasInvalidParm;
15619std::optional<std::pair<
15628static std::pair<CharUnits, CharUnits>
15636 if (
Base->isVirtual()) {
15643 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15650 DerivedType =
Base->getType();
15653 return std::make_pair(BaseAlignment, Offset);
15657static std::optional<std::pair<CharUnits, CharUnits>>
15663 return std::nullopt;
15668 return std::nullopt;
15672 CharUnits Offset = EltSize * IdxRes->getExtValue();
15675 return std::make_pair(P->first, P->second + Offset);
15681 return std::make_pair(
15682 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15688std::optional<std::pair<
15696 case Stmt::CStyleCastExprClass:
15697 case Stmt::CXXStaticCastExprClass:
15698 case Stmt::ImplicitCastExprClass: {
15700 const Expr *From = CE->getSubExpr();
15701 switch (CE->getCastKind()) {
15706 case CK_UncheckedDerivedToBase:
15707 case CK_DerivedToBase: {
15717 case Stmt::ArraySubscriptExprClass: {
15722 case Stmt::DeclRefExprClass: {
15726 if (!VD->getType()->isReferenceType()) {
15728 if (VD->hasDependentAlignment())
15737 case Stmt::MemberExprClass: {
15739 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15743 std::optional<std::pair<CharUnits, CharUnits>> P;
15752 return std::make_pair(P->first,
15755 case Stmt::UnaryOperatorClass: {
15765 case Stmt::BinaryOperatorClass: {
15777 return std::nullopt;
15782std::optional<std::pair<
15791 case Stmt::CStyleCastExprClass:
15792 case Stmt::CXXStaticCastExprClass:
15793 case Stmt::ImplicitCastExprClass: {
15795 const Expr *From = CE->getSubExpr();
15796 switch (CE->getCastKind()) {
15801 case CK_ArrayToPointerDecay:
15803 case CK_UncheckedDerivedToBase:
15804 case CK_DerivedToBase: {
15814 case Stmt::CXXThisExprClass: {
15819 case Stmt::UnaryOperatorClass: {
15825 case Stmt::BinaryOperatorClass: {
15834 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15835 std::swap(LHS, RHS);
15845 return std::nullopt;
15850 std::optional<std::pair<CharUnits, CharUnits>> P =
15854 return P->first.alignmentAtOffset(P->second);
15872 if (!DestPtr)
return;
15878 if (DestAlign.
isOne())
return;
15882 if (!SrcPtr)
return;
15893 if (SrcAlign >= DestAlign)
return;
15898 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15902void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15904 bool AllowOnePastEnd,
bool IndexNegated) {
15913 const Type *EffectiveType =
15917 Context.getAsConstantArrayType(BaseExpr->
getType());
15920 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15922 const Type *BaseType =
15924 bool IsUnboundedArray =
15926 Context, StrictFlexArraysLevel,
15929 (!IsUnboundedArray && BaseType->isDependentType()))
15937 if (IndexNegated) {
15938 index.setIsUnsigned(
false);
15942 if (IsUnboundedArray) {
15945 if (
index.isUnsigned() || !
index.isNegative()) {
15947 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15949 if (
index.getBitWidth() < AddrBits)
15951 std::optional<CharUnits> ElemCharUnits =
15952 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15955 if (!ElemCharUnits || ElemCharUnits->isZero())
15957 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15962 if (
index.getActiveBits() <= AddrBits) {
15964 llvm::APInt Product(
index);
15966 Product = Product.umul_ov(ElemBytes, Overflow);
15967 if (!Overflow && Product.getActiveBits() <= AddrBits)
15973 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15974 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15976 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15977 MaxElems = MaxElems.udiv(ElemBytes);
15980 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15981 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15986 PDiag(DiagID) << index << AddrBits
15987 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15988 << ElemBytes << MaxElems
15989 << MaxElems.getZExtValue()
15992 const NamedDecl *ND =
nullptr;
15994 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15996 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15998 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15999 ND = ME->getMemberDecl();
16003 PDiag(diag::note_array_declared_here) << ND);
16008 if (index.isUnsigned() || !index.isNegative()) {
16018 llvm::APInt size = ArrayTy->
getSize();
16020 if (BaseType != EffectiveType) {
16028 if (!ptrarith_typesize)
16029 ptrarith_typesize =
Context.getCharWidth();
16031 if (ptrarith_typesize != array_typesize) {
16033 uint64_t ratio = array_typesize / ptrarith_typesize;
16037 if (ptrarith_typesize * ratio == array_typesize)
16038 size *= llvm::APInt(size.getBitWidth(), ratio);
16042 if (size.getBitWidth() > index.getBitWidth())
16043 index = index.zext(size.getBitWidth());
16044 else if (size.getBitWidth() < index.getBitWidth())
16045 size = size.zext(index.getBitWidth());
16051 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16058 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16060 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16061 SourceLocation IndexLoc =
16063 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16068 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16069 : diag::warn_ptr_arith_exceeds_bounds;
16070 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16071 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16075 << index << ArrayTy->
desugar() << CastMsg
16078 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16080 DiagID = diag::warn_ptr_arith_precedes_bounds;
16081 if (index.isNegative()) index = -index;
16088 const NamedDecl *ND =
nullptr;
16090 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16092 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16094 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16095 ND = ME->getMemberDecl();
16099 PDiag(diag::note_array_declared_here) << ND);
16102void Sema::CheckArrayAccess(
const Expr *
expr) {
16103 int AllowOnePastEnd = 0;
16105 expr =
expr->IgnoreParenImpCasts();
16106 switch (
expr->getStmtClass()) {
16107 case Stmt::ArraySubscriptExprClass: {
16110 AllowOnePastEnd > 0);
16114 case Stmt::MemberExprClass: {
16118 case Stmt::CXXMemberCallExprClass: {
16122 case Stmt::ArraySectionExprClass: {
16128 nullptr, AllowOnePastEnd > 0);
16131 case Stmt::UnaryOperatorClass: {
16147 case Stmt::ConditionalOperatorClass: {
16149 if (
const Expr *lhs = cond->
getLHS())
16150 CheckArrayAccess(lhs);
16151 if (
const Expr *rhs = cond->
getRHS())
16152 CheckArrayAccess(rhs);
16155 case Stmt::CXXOperatorCallExprClass: {
16157 for (
const auto *Arg : OCE->arguments())
16158 CheckArrayAccess(Arg);
16168 Expr *RHS,
bool isProperty) {
16180 S.
Diag(Loc, diag::warn_arc_literal_assign)
16182 << (isProperty ? 0 : 1)
16190 Expr *RHS,
bool isProperty) {
16193 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16194 S.
Diag(Loc, diag::warn_arc_retained_assign)
16196 << (isProperty ? 0 : 1)
16200 RHS =
cast->getSubExpr();
16242 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16271 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16272 Diag(Loc, diag::warn_arc_retained_property_assign)
16276 RHS =
cast->getSubExpr();
16299 bool StmtLineInvalid;
16300 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16302 if (StmtLineInvalid)
16305 bool BodyLineInvalid;
16306 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16308 if (BodyLineInvalid)
16312 if (StmtLine != BodyLine)
16327 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16336 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16340 const Stmt *PossibleBody) {
16346 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16347 StmtLoc = FS->getRParenLoc();
16348 Body = FS->getBody();
16349 DiagID = diag::warn_empty_for_body;
16350 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16351 StmtLoc = WS->getRParenLoc();
16352 Body = WS->getBody();
16353 DiagID = diag::warn_empty_while_body;
16358 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16382 if (!ProbableTypo) {
16383 bool BodyColInvalid;
16384 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16386 if (BodyColInvalid)
16389 bool StmtColInvalid;
16392 if (StmtColInvalid)
16395 if (BodyCol > StmtCol)
16396 ProbableTypo =
true;
16399 if (ProbableTypo) {
16401 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16409 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16421 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16423 RHSExpr = CE->
getArg(0);
16424 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16425 CXXSCE && CXXSCE->isXValue())
16426 RHSExpr = CXXSCE->getSubExpr();
16430 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16431 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16434 if (LHSDeclRef && RHSDeclRef) {
16441 auto D =
Diag(OpLoc, diag::warn_self_move)
16457 const Expr *LHSBase = LHSExpr;
16458 const Expr *RHSBase = RHSExpr;
16459 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16460 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16461 if (!LHSME || !RHSME)
16464 while (LHSME && RHSME) {
16471 LHSME = dyn_cast<MemberExpr>(LHSBase);
16472 RHSME = dyn_cast<MemberExpr>(RHSBase);
16475 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16476 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16477 if (LHSDeclRef && RHSDeclRef) {
16484 Diag(OpLoc, diag::warn_self_move)
16491 Diag(OpLoc, diag::warn_self_move)
16515 bool AreUnionMembers =
false) {
16519 assert(((Field1Parent->isStructureOrClassType() &&
16520 Field2Parent->isStructureOrClassType()) ||
16521 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16522 "Can't evaluate layout compatibility between a struct field and a "
16524 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16525 (AreUnionMembers && Field1Parent->isUnionType())) &&
16526 "AreUnionMembers should be 'true' for union fields (only).");
16540 if (Bits1 != Bits2)
16544 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16545 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16548 if (!AreUnionMembers &&
16560 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16561 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16563 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16564 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16569 return isLayoutCompatible(C, F1, F2);
16580 for (
auto *Field1 : RD1->
fields()) {
16581 auto I = UnmatchedFields.begin();
16582 auto E = UnmatchedFields.end();
16584 for ( ; I != E; ++I) {
16586 bool Result = UnmatchedFields.erase(*I);
16596 return UnmatchedFields.empty();
16622 if (
C.hasSameType(T1, T2))
16631 if (TC1 == Type::Enum)
16633 if (TC1 == Type::Record) {
16652 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16683 const ValueDecl **VD, uint64_t *MagicValue,
16684 bool isConstantEvaluated) {
16692 case Stmt::UnaryOperatorClass: {
16701 case Stmt::DeclRefExprClass: {
16707 case Stmt::IntegerLiteralClass: {
16709 llvm::APInt MagicValueAPInt = IL->
getValue();
16710 if (MagicValueAPInt.getActiveBits() <= 64) {
16711 *MagicValue = MagicValueAPInt.getZExtValue();
16717 case Stmt::BinaryConditionalOperatorClass:
16718 case Stmt::ConditionalOperatorClass: {
16723 isConstantEvaluated)) {
16733 case Stmt::BinaryOperatorClass: {
16736 TypeExpr = BO->
getRHS();
16766 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16769 bool isConstantEvaluated) {
16770 FoundWrongKind =
false;
16775 uint64_t MagicValue;
16777 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16781 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16782 if (I->getArgumentKind() != ArgumentKind) {
16783 FoundWrongKind =
true;
16786 TypeInfo.Type = I->getMatchingCType();
16787 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16788 TypeInfo.MustBeNull = I->getMustBeNull();
16799 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16800 if (I == MagicValues->end())
16809 bool LayoutCompatible,
16811 if (!TypeTagForDatatypeMagicValues)
16812 TypeTagForDatatypeMagicValues.reset(
16813 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16816 (*TypeTagForDatatypeMagicValues)[Magic] =
16832 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16833 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16834 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16835 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16838void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16841 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16842 bool IsPointerAttr = Attr->getIsPointer();
16845 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16846 if (TypeTagIdxAST >= ExprArgs.size()) {
16847 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16848 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16851 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16852 bool FoundWrongKind;
16855 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16857 if (FoundWrongKind)
16859 diag::warn_type_tag_for_datatype_wrong_kind)
16865 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16866 if (ArgumentIdxAST >= ExprArgs.size()) {
16867 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16868 << 1 << Attr->getArgumentIdx().getSourceIndex();
16871 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16872 if (IsPointerAttr) {
16874 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16875 if (ICE->getType()->isVoidPointerType() &&
16876 ICE->getCastKind() == CK_BitCast)
16877 ArgumentExpr = ICE->getSubExpr();
16879 QualType ArgumentType = ArgumentExpr->
getType();
16885 if (TypeInfo.MustBeNull) {
16890 diag::warn_type_safety_null_pointer_required)
16898 QualType RequiredType = TypeInfo.Type;
16900 RequiredType =
Context.getPointerType(RequiredType);
16902 bool mismatch =
false;
16903 if (!TypeInfo.LayoutCompatible) {
16904 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16925 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16926 << ArgumentType << ArgumentKind
16927 << TypeInfo.LayoutCompatible << RequiredType
16945 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16953 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16959 auto &MisalignedMembersForExpr =
16961 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16962 if (MA != MisalignedMembersForExpr.end() &&
16963 (
T->isDependentType() ||
T->isIntegerType() ||
16964 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16966 T->getPointeeType()) <= MA->Alignment))))
16967 MisalignedMembersForExpr.erase(MA);
16976 const auto *ME = dyn_cast<MemberExpr>(E);
16988 bool AnyIsPacked =
false;
16990 QualType BaseType = ME->getBase()->getType();
16991 if (BaseType->isDependentType())
16995 auto *RD = BaseType->castAsRecordDecl();
17000 auto *FD = dyn_cast<FieldDecl>(MD);
17006 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17007 ReverseMemberChain.push_back(FD);
17010 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17012 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17019 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17030 if (ExpectedAlignment.
isOne())
17035 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17036 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17040 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17044 if (DRE && !TopME->
isArrow()) {
17047 CompleteObjectAlignment =
17048 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17052 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17055 CompleteObjectAlignment < ExpectedAlignment) {
17066 for (
FieldDecl *FDI : ReverseMemberChain) {
17067 if (FDI->hasAttr<PackedAttr>() ||
17068 FDI->getParent()->hasAttr<PackedAttr>()) {
17070 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17076 assert(FD &&
"We did not find a packed FieldDecl!");
17077 Action(E, FD->
getParent(), FD, Alignment);
17081void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17082 using namespace std::placeholders;
17085 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17109bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17110 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17137 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17154 assert(!Args.empty() &&
"Should have at least one argument.");
17156 Expr *Arg0 = Args.front();
17159 auto EmitError = [&](
Expr *ArgI) {
17161 diag::err_typecheck_call_different_arg_types)
17162 << Arg0->
getType() << ArgI->getType();
17167 for (
Expr *ArgI : Args.drop_front())
17178 for (
Expr *ArgI : Args.drop_front()) {
17179 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17182 VecI->getElementType()) ||
17183 Vec0->getNumElements() != VecI->getNumElements()) {
17192std::optional<QualType>
17196 return std::nullopt;
17200 return std::nullopt;
17203 for (
int I = 0; I < 2; ++I) {
17207 return std::nullopt;
17208 Args[I] = Converted.
get();
17215 return std::nullopt;
17218 return std::nullopt;
17220 TheCall->
setArg(0, Args[0]);
17221 TheCall->
setArg(1, Args[1]);
17232 TheCall->
getArg(1), Loc) ||
17234 TheCall->
getArg(2), Loc))
17238 for (
int I = 0; I < 3; ++I) {
17243 Args[I] = Converted.
get();
17246 int ArgOrdinal = 1;
17247 for (
Expr *Arg : Args) {
17249 ArgTyRestr, ArgOrdinal++))
17256 for (
int I = 0; I < 3; ++I)
17257 TheCall->
setArg(I, Args[I]);
17263bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17275bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17284 diag::err_builtin_invalid_arg_type)
17285 << 1 << 2 << 1 << 1 << TyArg;
17299 Expr *Matrix = MatrixArg.
get();
17301 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17304 << 1 << 3 << 0 << 0
17311 QualType ResultType =
Context.getConstantMatrixType(
17312 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17315 TheCall->
setType(ResultType);
17318 TheCall->
setArg(0, Matrix);
17323static std::optional<unsigned>
17331 uint64_t
Dim =
Value->getZExtValue();
17347 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17349 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17357 unsigned PtrArgIdx = 0;
17358 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17359 Expr *RowsExpr = TheCall->
getArg(1);
17360 Expr *ColumnsExpr = TheCall->
getArg(2);
17361 Expr *StrideExpr = TheCall->
getArg(3);
17363 bool ArgError =
false;
17370 PtrExpr = PtrConv.
get();
17371 TheCall->
setArg(0, PtrExpr);
17378 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17379 QualType ElementTy;
17382 << PtrArgIdx + 1 << 0 << 5 << 0
17386 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17390 << PtrArgIdx + 1 << 0 << 5
17397 auto ApplyArgumentConversions = [
this](Expr *E) {
17406 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17408 RowsExpr = RowsConv.
get();
17409 TheCall->
setArg(1, RowsExpr);
17411 RowsExpr =
nullptr;
17413 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17415 ColumnsExpr = ColumnsConv.
get();
17416 TheCall->
setArg(2, ColumnsExpr);
17418 ColumnsExpr =
nullptr;
17429 std::optional<unsigned> MaybeRows;
17433 std::optional<unsigned> MaybeColumns;
17438 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17441 StrideExpr = StrideConv.
get();
17442 TheCall->
setArg(3, StrideExpr);
17445 if (std::optional<llvm::APSInt>
Value =
17448 if (Stride < *MaybeRows) {
17450 diag::err_builtin_matrix_stride_too_small);
17456 if (ArgError || !MaybeRows || !MaybeColumns)
17460 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17471 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17473 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17481 unsigned PtrArgIdx = 1;
17482 Expr *MatrixExpr = TheCall->
getArg(0);
17483 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17484 Expr *StrideExpr = TheCall->
getArg(2);
17486 bool ArgError =
false;
17492 MatrixExpr = MatrixConv.
get();
17493 TheCall->
setArg(0, MatrixExpr);
17500 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17503 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17511 PtrExpr = PtrConv.
get();
17512 TheCall->
setArg(1, PtrExpr);
17520 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17523 << PtrArgIdx + 1 << 0 << 5 << 0
17527 QualType ElementTy = PtrTy->getPointeeType();
17529 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17534 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17536 diag::err_builtin_matrix_pointer_arg_mismatch)
17537 << ElementTy << MatrixTy->getElementType();
17552 StrideExpr = StrideConv.
get();
17553 TheCall->
setArg(2, StrideExpr);
17558 if (std::optional<llvm::APSInt>
Value =
17561 if (Stride < MatrixTy->getNumRows()) {
17563 diag::err_builtin_matrix_stride_too_small);
17583 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17588 llvm::StringSet<> CalleeTCBs;
17589 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17590 CalleeTCBs.insert(A->getTCBName());
17591 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17592 CalleeTCBs.insert(A->getTCBName());
17596 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17597 StringRef CallerTCB = A->getTCBName();
17598 if (CalleeTCBs.count(CallerTCB) == 0) {
17599 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17600 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
Defines enumerations for traits support.
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.
Result
Implement __builtin_bit_cast and related operations.
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
llvm::MachO::Record Record
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 getFunctionName(const CallEvent &Call)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool isValidMathElementType(QualType T)
static void DiagnoseDeprecatedHIPAtomic(Sema &S, SourceRange ExprRange, MultiExprArg Args, AtomicExpr::AtomicOp Op)
Deprecate __hip_atomic_* builtins in favour of __scoped_atomic_* equivalents.
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)
#define HIP_ATOMIC_FIXABLE(hip, scoped)
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 QualType getVectorElementType(ASTContext &Context, QualType VecTy)
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 bool BuiltinBitreverseg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bitreverseg was called with a single argument, which is an integer.
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 bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
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 ExprResult PointerAuthAuthWithPCAndResign(Sema &S, CallExpr *Call)
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 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, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
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 ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
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 for SYCL 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.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
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 * getStart() const
StringRef toString() 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
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
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],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APValue & getMatrixElt(unsigned Idx)
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
unsigned getMatrixNumElements() const
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ conversion function within a class.
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 byte-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)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
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
SourceLocation getEndLoc() const LLVM_READONLY
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,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ 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.
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 * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
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 ...
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
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.
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() const
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.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
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
ARM8_3Key
Hardware pointer-signing keys in ARM8.3.
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 hasFlexibleArrayMember() const
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
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.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
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 PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
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...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
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)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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 isAnyComplexType() 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 isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isMatrixType() 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
bool isSizelessVectorType() const
Returns true for all scalable vector types.
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
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)
SetTy< T > join(SetTy< T > A, SetTy< T > B, typename SetTy< T >::Factory &F)
Computes the union of two ImmutableSets.
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
bool isFunctionOrMethodVariadic(const Decl *D)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
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 Indentation
The number of spaces to use to indent each line.
unsigned AnonymousTagNameStyle
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.