48 changes: 47 additions & 1 deletion clang/lib/Headers/hlsl/hlsl_basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,98 @@ namespace hlsl {
// 16-bit integer.
typedef unsigned short uint16_t;
typedef short int16_t;

// 16-bit floating point.
typedef half float16_t;
#endif

// 32-bit integer.
typedef int int32_t;

// unsigned 32-bit integer.
typedef unsigned int uint;
typedef unsigned int uint32_t;

// 32-bit floating point.
typedef float float32_t;

// 64-bit integer.
typedef unsigned long uint64_t;
typedef long int64_t;

// 64-bit floating point
typedef double float64_t;

// built-in vector data types:

#ifdef __HLSL_ENABLE_16_BIT
typedef vector<int16_t, 1> int16_t1;
typedef vector<int16_t, 2> int16_t2;
typedef vector<int16_t, 3> int16_t3;
typedef vector<int16_t, 4> int16_t4;
typedef vector<uint16_t, 1> uint16_t1;
typedef vector<uint16_t, 2> uint16_t2;
typedef vector<uint16_t, 3> uint16_t3;
typedef vector<uint16_t, 4> uint16_t4;
#endif
typedef vector<bool, 1> bool1;
typedef vector<bool, 2> bool2;
typedef vector<bool, 3> bool3;
typedef vector<bool, 4> bool4;
typedef vector<int, 1> int1;
typedef vector<int, 2> int2;
typedef vector<int, 3> int3;
typedef vector<int, 4> int4;
typedef vector<uint, 1> uint1;
typedef vector<uint, 2> uint2;
typedef vector<uint, 3> uint3;
typedef vector<uint, 4> uint4;
typedef vector<int32_t, 1> int32_t1;
typedef vector<int32_t, 2> int32_t2;
typedef vector<int32_t, 3> int32_t3;
typedef vector<int32_t, 4> int32_t4;
typedef vector<uint32_t, 1> uint32_t1;
typedef vector<uint32_t, 2> uint32_t2;
typedef vector<uint32_t, 3> uint32_t3;
typedef vector<uint32_t, 4> uint32_t4;
typedef vector<int64_t, 1> int64_t1;
typedef vector<int64_t, 2> int64_t2;
typedef vector<int64_t, 3> int64_t3;
typedef vector<int64_t, 4> int64_t4;
typedef vector<uint64_t, 1> uint64_t1;
typedef vector<uint64_t, 2> uint64_t2;
typedef vector<uint64_t, 3> uint64_t3;
typedef vector<uint64_t, 4> uint64_t4;

typedef vector<half, 1> half1;
typedef vector<half, 2> half2;
typedef vector<half, 3> half3;
typedef vector<half, 4> half4;

typedef vector<float, 1> float1;
typedef vector<float, 2> float2;
typedef vector<float, 3> float3;
typedef vector<float, 4> float4;
typedef vector<double, 1> double1;
typedef vector<double, 2> double2;
typedef vector<double, 3> double3;
typedef vector<double, 4> double4;

#ifdef __HLSL_ENABLE_16_BIT
typedef vector<float16_t, 1> float16_t1;
typedef vector<float16_t, 2> float16_t2;
typedef vector<float16_t, 3> float16_t3;
typedef vector<float16_t, 4> float16_t4;
#endif

typedef vector<float32_t, 1> float32_t1;
typedef vector<float32_t, 2> float32_t2;
typedef vector<float32_t, 3> float32_t3;
typedef vector<float32_t, 4> float32_t4;
typedef vector<float64_t, 1> float64_t1;
typedef vector<float64_t, 2> float64_t2;
typedef vector<float64_t, 3> float64_t3;
typedef vector<float64_t, 4> float64_t4;

} // namespace hlsl

#endif //_HLSL_HLSL_BASIC_TYPES_H_
103 changes: 97 additions & 6 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,10 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
[[fallthrough]];
default:
ParsedAttributes DeclAttrs(AttrFactory);
MaybeParseCXX11Attributes(DeclAttrs);
ParsedAttributes DeclSpecAttrs(AttrFactory);
while (MaybeParseCXX11Attributes(DeclAttrs) ||
MaybeParseGNUAttributes(DeclSpecAttrs))
;
ParseExternalDeclaration(DeclAttrs, DeclSpecAttrs);
continue;
}
Expand All @@ -449,7 +452,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, DeclaratorContext Context) {
///
/// export-function-declaration:
/// 'export' function-declaration
///
///
/// export-declaration-group:
/// 'export' '{' function-declaration-seq[opt] '}'
///
Expand Down Expand Up @@ -2004,9 +2007,16 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,

const PrintingPolicy &Policy = Actions.getASTContext().getPrintingPolicy();
TagUseKind TUK;
if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==
AllowDefiningTypeSpec::No ||
(getLangOpts().OpenMP && OpenMPDirectiveParsing))

// C++26 [class.mem.general]p10: If a name-declaration matches the
// syntactic requirements of friend-type-declaration, it is a
// friend-type-declaration.
if (getLangOpts().CPlusPlus && DS.isFriendSpecifiedFirst() &&
Tok.isOneOf(tok::comma, tok::ellipsis))
TUK = TagUseKind::Friend;
else if (isDefiningTypeSpecifierContext(DSC, getLangOpts().CPlusPlus) ==
AllowDefiningTypeSpec::No ||
(getLangOpts().OpenMP && OpenMPDirectiveParsing))
TUK = TagUseKind::Reference;
else if (Tok.is(tok::l_brace) ||
(DSC != DeclSpecContext::DSC_association &&
Expand Down Expand Up @@ -2238,9 +2248,28 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
diag::err_keyword_not_allowed,
/*DiagnoseEmptyAttrs=*/true);

// Consume '...' first so we error on the ',' after it if there is one.
SourceLocation EllipsisLoc;
TryConsumeToken(tok::ellipsis, EllipsisLoc);

// CWG 2917: In a template-declaration whose declaration is a
// friend-type-declaration, the friend-type-specifier-list shall
// consist of exactly one friend-type-specifier.
//
// Essentially, the following is obviously nonsense, so disallow it:
//
// template <typename>
// friend class S, int;
//
if (Tok.is(tok::comma)) {
Diag(Tok.getLocation(),
diag::err_friend_template_decl_multiple_specifiers);
SkipUntil(tok::semi, StopBeforeMatch);
}

TagOrTempResult = Actions.ActOnTemplatedFriendTag(
getCurScope(), DS.getFriendSpecLoc(), TagType, StartLoc, SS, Name,
NameLoc, attrs,
NameLoc, EllipsisLoc, attrs,
MultiTemplateParamsArg(TemplateParams ? &(*TemplateParams)[0] : nullptr,
TemplateParams ? TemplateParams->size() : 0));
} else {
Expand Down Expand Up @@ -2815,6 +2844,7 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
/// member-declaration:
/// decl-specifier-seq[opt] member-declarator-list[opt] ';'
/// function-definition ';'[opt]
/// [C++26] friend-type-declaration
/// ::[opt] nested-name-specifier template[opt] unqualified-id ';'[TODO]
/// using-declaration [TODO]
/// [C++0x] static_assert-declaration
Expand Down Expand Up @@ -2847,6 +2877,18 @@ void Parser::MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(
/// constant-initializer:
/// '=' constant-expression
///
/// friend-type-declaration:
/// 'friend' friend-type-specifier-list ;
///
/// friend-type-specifier-list:
/// friend-type-specifier ...[opt]
/// friend-type-specifier-list , friend-type-specifier ...[opt]
///
/// friend-type-specifier:
/// simple-type-specifier
/// elaborated-type-specifier
/// typename-specifier
///
Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
AccessSpecifier AS, ParsedAttributes &AccessAttrs,
ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject *TemplateDiags) {
Expand Down Expand Up @@ -3048,6 +3090,55 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration(
if (DS.hasTagDefinition())
Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl());

// Handle C++26's variadic friend declarations. These don't even have
// declarators, so we get them out of the way early here.
if (DS.isFriendSpecifiedFirst() && Tok.isOneOf(tok::comma, tok::ellipsis)) {
Diag(Tok.getLocation(), getLangOpts().CPlusPlus26
? diag::warn_cxx23_variadic_friends
: diag::ext_variadic_friends);

SourceLocation FriendLoc = DS.getFriendSpecLoc();
SmallVector<Decl *> Decls;

// Handles a single friend-type-specifier.
auto ParsedFriendDecl = [&](ParsingDeclSpec &DeclSpec) {
SourceLocation VariadicLoc;
TryConsumeToken(tok::ellipsis, VariadicLoc);

RecordDecl *AnonRecord = nullptr;
Decl *D = Actions.ParsedFreeStandingDeclSpec(
getCurScope(), AS, DeclSpec, DeclAttrs, TemplateParams, false,
AnonRecord, VariadicLoc);
DeclSpec.complete(D);
if (!D) {
SkipUntil(tok::semi, tok::r_brace);
return true;
}

Decls.push_back(D);
return false;
};

if (ParsedFriendDecl(DS))
return nullptr;

while (TryConsumeToken(tok::comma)) {
ParsingDeclSpec DeclSpec(*this, TemplateDiags);
const char *PrevSpec = nullptr;
unsigned DiagId = 0;
DeclSpec.SetFriendSpec(FriendLoc, PrevSpec, DiagId);
ParseDeclarationSpecifiers(DeclSpec, TemplateInfo, AS,
DeclSpecContext::DSC_class, nullptr);
if (ParsedFriendDecl(DeclSpec))
return nullptr;
}

ExpectAndConsume(tok::semi, diag::err_expected_semi_after_stmt,
"friend declaration");

return Actions.BuildDeclaratorGroup(Decls);
}

ParsingDeclarator DeclaratorInfo(*this, DS, DeclAttrs,
DeclaratorContext::Member);
if (TemplateInfo.TemplateParams)
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,15 @@ static void ProcessAPINotes(Sema &S, VarDecl *D,
metadata);
}

/// Process API notes for a C field.
static void ProcessAPINotes(Sema &S, FieldDecl *D,
const api_notes::FieldInfo &Info,
VersionedInfoMetadata metadata) {
// Handle common entity information.
ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(Info),
metadata);
}

/// Process API notes for an Objective-C property.
static void ProcessAPINotes(Sema &S, ObjCPropertyDecl *D,
const api_notes::ObjCPropertyInfo &Info,
Expand Down Expand Up @@ -1062,6 +1071,17 @@ void Sema::ProcessAPINotes(Decl *D) {
}
}

if (auto Field = dyn_cast<FieldDecl>(D)) {
if (!Field->isUnnamedBitField() && !Field->isAnonymousStructOrUnion()) {
for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
if (auto Context = UnwindTagContext(TagContext, APINotes)) {
auto Info = Reader->lookupField(Context->id, Field->getName());
ProcessVersionedAPINotes(*this, Field, Info);
}
}
}
}

if (auto Tag = dyn_cast<TagDecl>(D)) {
for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
if (auto Context = UnwindTagContext(TagContext, APINotes)) {
Expand Down
22 changes: 15 additions & 7 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5000,7 +5000,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
const ParsedAttributesView &DeclAttrs,
MultiTemplateParamsArg TemplateParams,
bool IsExplicitInstantiation,
RecordDecl *&AnonRecord) {
RecordDecl *&AnonRecord,
SourceLocation EllipsisLoc) {
Decl *TagD = nullptr;
TagDecl *Tag = nullptr;
if (DS.getTypeSpecType() == DeclSpec::TST_class ||
Expand Down Expand Up @@ -5067,9 +5068,12 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
// whatever routines created it handled the friendship aspect.
if (TagD && !Tag)
return nullptr;
return ActOnFriendTypeDecl(S, DS, TemplateParams);
return ActOnFriendTypeDecl(S, DS, TemplateParams, EllipsisLoc);
}

assert(EllipsisLoc.isInvalid() &&
"Friend ellipsis but not friend-specified?");

// Track whether this decl-specifier declares anything.
bool DeclaresAnything = true;

Expand Down Expand Up @@ -18503,11 +18507,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
// the program is ill-formed, except when compiling with MSVC extensions
// enabled.
if (EltTy->isReferenceType()) {
Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ?
diag::ext_union_member_of_reference_type :
diag::err_union_member_of_reference_type)
<< NewFD->getDeclName() << EltTy;
if (!getLangOpts().MicrosoftExt)
const bool HaveMSExt =
getLangOpts().MicrosoftExt &&
!getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015);

Diag(NewFD->getLocation(),
HaveMSExt ? diag::ext_union_member_of_reference_type
: diag::err_union_member_of_reference_type)
<< NewFD->getDeclName() << EltTy;
if (!HaveMSExt)
NewFD->setInvalidDecl();
}
}
Expand Down
104 changes: 71 additions & 33 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7644,9 +7644,13 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
// parameter is of (possibly different) type “reference to C”,
// in which case the type of F1 would differ from the type of F2
// in that the type of F1 has an additional parameter;
if (!Context.hasSameType(
ThisType.getNonReferenceType().getUnqualifiedType(),
Context.getRecordType(RD))) {
QualType ExplicitObjectParameter = MD->isExplicitObjectMemberFunction()
? MD->getParamDecl(0)->getType()
: QualType();
if (!ExplicitObjectParameter.isNull() &&
(!ExplicitObjectParameter->isReferenceType() ||
!Context.hasSameType(ExplicitObjectParameter.getNonReferenceType(),
Context.getRecordType(RD)))) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
else {
Expand Down Expand Up @@ -8730,8 +8734,9 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
// If we're out-of-class, this is the class we're comparing.
if (!RD)
RD = MD->getParent();
QualType T = MD->getFunctionObjectParameterType();
if (!T.isConstQualified()) {
QualType T = MD->getFunctionObjectParameterReferenceType();
if (!T.getNonReferenceType().isConstQualified() &&
(MD->isImplicitObjectMemberFunction() || T->isLValueReferenceType())) {
SourceLocation Loc, InsertLoc;
if (MD->isExplicitObjectMemberFunction()) {
Loc = MD->getParamDecl(0)->getBeginLoc();
Expand All @@ -8750,11 +8755,17 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
}

// Add the 'const' to the type to recover.
const auto *FPT = MD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.TypeQuals.addConst();
MD->setType(Context.getFunctionType(FPT->getReturnType(),
FPT->getParamTypes(), EPI));
if (MD->isExplicitObjectMemberFunction()) {
assert(T->isLValueReferenceType());
MD->getParamDecl(0)->setType(Context.getLValueReferenceType(
T.getNonReferenceType().withConst()));
} else {
const auto *FPT = MD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.TypeQuals.addConst();
MD->setType(Context.getFunctionType(FPT->getReturnType(),
FPT->getParamTypes(), EPI));
}
}

if (MD->isVolatile()) {
Expand All @@ -8781,33 +8792,27 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,

const ParmVarDecl *KnownParm = nullptr;
for (const ParmVarDecl *Param : FD->parameters()) {
if (Param->isExplicitObjectParameter())
continue;
QualType ParmTy = Param->getType();

if (!KnownParm) {
auto CTy = ParmTy;
// Is it `T const &`?
bool Ok = !IsMethod;
bool Ok = !IsMethod || FD->hasCXXExplicitFunctionObjectParameter();
QualType ExpectedTy;
if (RD)
ExpectedTy = Context.getRecordType(RD);
if (auto *Ref = CTy->getAs<ReferenceType>()) {
if (auto *Ref = CTy->getAs<LValueReferenceType>()) {
CTy = Ref->getPointeeType();
if (RD)
ExpectedTy.addConst();
Ok = true;
}

// Is T a class?
if (!Ok) {
} else if (RD) {
if (!RD->isDependentType() && !Context.hasSameType(CTy, ExpectedTy))
Ok = false;
} else if (auto *CRD = CTy->getAsRecordDecl()) {
RD = cast<CXXRecordDecl>(CRD);
if (RD) {
Ok &= RD->isDependentType() || Context.hasSameType(CTy, ExpectedTy);
} else {
Ok = false;
RD = CTy->getAsCXXRecordDecl();
Ok &= RD != nullptr;
}

if (Ok) {
Expand Down Expand Up @@ -8847,7 +8852,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
assert(FD->getFriendObjectKind() && "expected a friend declaration");
} else {
// Out of class, require the defaulted comparison to be a friend (of a
// complete type).
// complete type, per CWG2547).
if (RequireCompleteType(FD->getLocation(), Context.getRecordType(RD),
diag::err_defaulted_comparison_not_friend, int(DCK),
int(1)))
Expand Down Expand Up @@ -17381,7 +17386,8 @@ Decl *Sema::BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc,
DeclResult Sema::ActOnTemplatedFriendTag(
Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc,
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
const ParsedAttributesView &Attr, MultiTemplateParamsArg TempParamLists) {
SourceLocation EllipsisLoc, const ParsedAttributesView &Attr,
MultiTemplateParamsArg TempParamLists) {
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);

bool IsMemberSpecialization = false;
Expand Down Expand Up @@ -17425,6 +17431,7 @@ DeclResult Sema::ActOnTemplatedFriendTag(
// If it's explicit specializations all the way down, just forget
// about the template header and build an appropriate non-templated
// friend. TODO: for source fidelity, remember the headers.
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
if (isAllExplicitSpecializations) {
if (SS.isEmpty()) {
bool Owned = false;
Expand All @@ -17440,7 +17447,6 @@ DeclResult Sema::ActOnTemplatedFriendTag(
/*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside);
}

NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
ElaboratedTypeKeyword Keyword
= TypeWithKeyword::getKeywordForTagTypeKind(Kind);
QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc,
Expand All @@ -17462,16 +17468,32 @@ DeclResult Sema::ActOnTemplatedFriendTag(
TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(NameLoc);
}

FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc,
TSI, FriendLoc, TempParamLists);
FriendDecl *Friend =
FriendDecl::Create(Context, CurContext, NameLoc, TSI, FriendLoc,
EllipsisLoc, TempParamLists);
Friend->setAccess(AS_public);
CurContext->addDecl(Friend);
return Friend;
}

assert(SS.isNotEmpty() && "valid templated tag with no SS and no direct?");


// CWG 2917: if it (= the friend-type-specifier) is a pack expansion
// (13.7.4 [temp.variadic]), any packs expanded by that pack expansion
// shall not have been introduced by the template-declaration.
SmallVector<UnexpandedParameterPack, 1> Unexpanded;
collectUnexpandedParameterPacks(QualifierLoc, Unexpanded);
unsigned FriendDeclDepth = TempParamLists.front()->getDepth();
for (UnexpandedParameterPack &U : Unexpanded) {
if (getDepthAndIndex(U).first >= FriendDeclDepth) {
auto *ND = U.first.dyn_cast<NamedDecl *>();
if (!ND)
ND = U.first.get<const TemplateTypeParmType *>()->getDecl();
Diag(U.second, diag::friend_template_decl_malformed_pack_expansion)
<< ND->getDeclName() << SourceRange(SS.getBeginLoc(), EllipsisLoc);
return true;
}
}

// Handle the case of a templated-scope friend class. e.g.
// template <class T> class A<T>::B;
Expand All @@ -17486,16 +17508,18 @@ DeclResult Sema::ActOnTemplatedFriendTag(
TL.setQualifierLoc(SS.getWithLocInContext(Context));
TL.setNameLoc(NameLoc);

FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc,
TSI, FriendLoc, TempParamLists);
FriendDecl *Friend =
FriendDecl::Create(Context, CurContext, NameLoc, TSI, FriendLoc,
EllipsisLoc, TempParamLists);
Friend->setAccess(AS_public);
Friend->setUnsupportedFriend(true);
CurContext->addDecl(Friend);
return Friend;
}

Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
MultiTemplateParamsArg TempParams) {
MultiTemplateParamsArg TempParams,
SourceLocation EllipsisLoc) {
SourceLocation Loc = DS.getBeginLoc();
SourceLocation FriendLoc = DS.getFriendSpecLoc();

Expand Down Expand Up @@ -17536,8 +17560,18 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
if (TheDeclarator.isInvalidType())
return nullptr;

if (DiagnoseUnexpandedParameterPack(Loc, TSI, UPPC_FriendDeclaration))
// If '...' is present, the type must contain an unexpanded parameter
// pack, and vice versa.
bool Invalid = false;
if (EllipsisLoc.isInvalid() &&
DiagnoseUnexpandedParameterPack(Loc, TSI, UPPC_FriendDeclaration))
return nullptr;
if (EllipsisLoc.isValid() &&
!TSI->getType()->containsUnexpandedParameterPack()) {
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< TSI->getTypeLoc().getSourceRange();
Invalid = true;
}

if (!T->isElaboratedTypeSpecifier()) {
if (TempParams.size()) {
Expand Down Expand Up @@ -17583,18 +17617,22 @@ Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,

Decl *D;
if (!TempParams.empty())
// TODO: Support variadic friend template decls?
D = FriendTemplateDecl::Create(Context, CurContext, Loc, TempParams, TSI,
FriendLoc);
else
D = FriendDecl::Create(Context, CurContext, TSI->getTypeLoc().getBeginLoc(),
TSI, FriendLoc);
TSI, FriendLoc, EllipsisLoc);

if (!D)
return nullptr;

D->setAccess(AS_public);
CurContext->addDecl(D);

if (Invalid)
D->setInvalidDecl();

return D;
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaTemplateDeduction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4462,6 +4462,9 @@ TemplateDeductionResult Sema::DeduceTemplateArguments(
ParamTypesForArgChecking.push_back(ParamType);

if (ParamIdx == 0 && HasExplicitObject) {
if (ObjectType.isNull())
return TemplateDeductionResult::InvalidExplicitArguments;

if (auto Result = DeduceCallArgument(ParamType, 0,
/*ExplicitObjectArgument=*/true);
Result != TemplateDeductionResult::Success)
Expand Down
43 changes: 41 additions & 2 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1442,8 +1442,47 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
if (D->isUnsupportedFriend()) {
InstTy = Ty;
} else {
InstTy = SemaRef.SubstType(Ty, TemplateArgs,
D->getLocation(), DeclarationName());
if (D->isPackExpansion()) {
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
SemaRef.collectUnexpandedParameterPacks(Ty->getTypeLoc(), Unexpanded);
assert(!Unexpanded.empty() && "Pack expansion without packs");

bool ShouldExpand = true;
bool RetainExpansion = false;
std::optional<unsigned> NumExpansions;
if (SemaRef.CheckParameterPacksForExpansion(
D->getEllipsisLoc(), D->getSourceRange(), Unexpanded,
TemplateArgs, ShouldExpand, RetainExpansion, NumExpansions))
return nullptr;

assert(!RetainExpansion &&
"should never retain an expansion for a variadic friend decl");

if (ShouldExpand) {
SmallVector<FriendDecl *> Decls;
for (unsigned I = 0; I != *NumExpansions; I++) {
Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
TypeSourceInfo *TSI = SemaRef.SubstType(
Ty, TemplateArgs, D->getEllipsisLoc(), DeclarationName());
if (!TSI)
return nullptr;

auto FD =
FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),
TSI, D->getFriendLoc());

FD->setAccess(AS_public);
Owner->addDecl(FD);
Decls.push_back(FD);
}

// Just drop this node; we have no use for it anymore.
return nullptr;
}
}

InstTy = SemaRef.SubstType(Ty, TemplateArgs, D->getLocation(),
DeclarationName());
}
if (!InstTy)
return nullptr;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTReaderDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2361,6 +2361,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
D->NextFriend = readDeclID().getRawValue();
D->UnsupportedFriend = (Record.readInt() != 0);
D->FriendLoc = readSourceLocation();
D->EllipsisLoc = readSourceLocation();
}

void ASTDeclReader::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Serialization/ASTWriterDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,6 +1660,7 @@ void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
Record.AddDeclRef(D->getNextFriend());
Record.push_back(D->UnsupportedFriend);
Record.AddSourceLocation(D->FriendLoc);
Record.AddSourceLocation(D->EllipsisLoc);
Code = serialization::DECL_FRIEND;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/StringChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ bool StringChecker::isCharToStringCtor(const CallEvent &Call,

// Verify that the parameters have the expected types:
// - arg 1: `const CharT *`
// - arg 2: some allocator - which is definately not `size_t`.
// - arg 2: some allocator - which is definitely not `size_t`.
const QualType Arg1Ty = Call.getArgExpr(0)->getType().getCanonicalType();
const QualType Arg2Ty = Call.getArgExpr(1)->getType().getCanonicalType();

Expand Down
8 changes: 8 additions & 0 deletions clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3807,6 +3807,14 @@ void ExprEngine::VisitGCCAsmStmt(const GCCAsmStmt *A, ExplodedNode *Pred,
state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
}

// Do not reason about locations passed inside inline assembly.
for (const Expr *I : A->inputs()) {
SVal X = state->getSVal(I, Pred->getLocationContext());

if (std::optional<Loc> LV = X.getAs<Loc>())
state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
}

Bldr.generateNode(A, Pred, state);
}

Expand Down
23 changes: 23 additions & 0 deletions clang/test/APINotes/Inputs/Headers/Fields.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
Name: Fields
Tags:
- Name: IntWrapper
Fields:
- Name: value
Availability: none
AvailabilityMsg: "oh no"
- Name: Outer
Tags:
- Name: Inner
Fields:
- Name: value
Availability: none
AvailabilityMsg: "oh no 2"
Methods:
- Name: value
Availability: none
AvailabilityMsg: "this should have no effect"
Functions:
- Name: value
Availability: none
AvailabilityMsg: "this should have no effect"
21 changes: 21 additions & 0 deletions clang/test/APINotes/Inputs/Headers/Fields.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
struct IntWrapper {
int value;

bool : 1;

enum {
one,
two,
three
};
union {
int a;
char b;
};
};

struct Outer {
struct Inner {
int value;
};
};
5 changes: 5 additions & 0 deletions clang/test/APINotes/Inputs/Headers/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ module ExportAs {
export *
}

module Fields {
header "Fields.h"
export *
}

module HeaderLib {
header "HeaderLib.h"
}
Expand Down
17 changes: 17 additions & 0 deletions clang/test/APINotes/fields.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Fields -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x c++
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Fields -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter IntWrapper::value -x c++ | FileCheck --check-prefix=CHECK-FIELD %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Fields -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Outer::Inner::value -x c++ | FileCheck --check-prefix=CHECK-DEEP-FIELD %s

#include "Fields.h"

// CHECK-FIELD: Dumping IntWrapper::value:
// CHECK-FIELD-NEXT: FieldDecl {{.+}} value
// CHECK-FIELD: UnavailableAttr {{.+}} <<invalid sloc>> "oh no"

// CHECK-DEEP-FIELD: Dumping Outer::Inner::value:
// CHECK-DEEP-FIELD-NEXT: FieldDecl {{.+}} value
// CHECK-DEEP-FIELD: UnavailableAttr {{.+}} <<invalid sloc>> "oh no 2"

// CHECK-FIELD-NOT: this should have no effect
// CHECK-DEEP-FIELD-NOT: this should have no effect
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,8 @@ constexpr EC getB() {


static_assert(getB() == EC::B, "");

namespace B {
enum E : bool { Zero, One };
static_assert((int)(E)2 == 1, "");
} // namespace B
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,17 @@ namespace Comparison {
static_assert(pg == &g, "");
}

constexpr int Double(int n) { return 2 * n; }
constexpr int Triple(int n) { return 3 * n; }
constexpr int Twice(int (*F)(int), int n) { return F(F(n)); }
constexpr int Quadruple(int n) { return Twice(Double, n); }
constexpr auto Select(int n) -> int (*)(int) {
return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
}
constexpr int Apply(int (*F)(int), int n) { return F(n); } // both-note {{'F' evaluates to a null function pointer}}

constexpr int Invalid = Apply(Select(0), 0); // both-error {{must be initialized by a constant expression}} \
// both-note {{in call to 'Apply(nullptr, 0)'}}
}

struct F {
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ namespace MoveFnWorks {
}
static_assert(dtor_calls_dtor(), "");
}

namespace PrimitiveMoveFn {
/// This used to crash.
void test() {
const float y = 100;
const float &x = y;
}
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -1627,3 +1627,29 @@ namespace DtorDestroysFieldsAfterSelf {
static_assert(foo() == 15);
}
#endif

namespace ExprWithCleanups {
struct A { A(); ~A(); int get(); };
constexpr int get() {return false ? A().get() : 1;}
static_assert(get() == 1, "");


struct S {
int V;
constexpr S(int V) : V(V) {}
constexpr int get() {
return V;
}
};
constexpr int get(bool b) {
S a = b ? S(1) : S(2);

return a.get();
}
static_assert(get(true) == 1, "");
static_assert(get(false) == 2, "");


constexpr auto F = true ? 1i : 2i;
static_assert(F == 1i, "");
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
441 changes: 316 additions & 125 deletions clang/test/AST/ast-dump-funcs-json.cpp

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions clang/test/AST/cxx2c-variadic-friends.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// RUN: %clang_cc1 -fsyntax-only -ast-dump -std=c++2c %s | FileCheck %s
// RUN: %clang_cc1 -ast-print -std=c++2c %s | FileCheck %s --check-prefix=PRINT
// RUN: %clang_cc1 -emit-pch -std=c++2c -o %t %s
// RUN: %clang_cc1 -x c++ -std=c++2c -include-pch %t -ast-dump-all /dev/null

struct S;
template <typename> struct TS; // #template

// CHECK-LABEL: CXXRecordDecl {{.*}} struct Friends
// PRINT-LABEL: struct Friends {
struct Friends {
// CHECK: FriendDecl {{.*}} 'int'
// CHECK-NEXT: FriendDecl {{.*}} 'long'
// PRINT-NEXT: friend int;
// PRINT-NEXT: friend long;
friend int, long;

// CHECK-NEXT: FriendDecl {{.*}} 'int'
// CHECK-NEXT: FriendDecl {{.*}} 'long'
// CHECK-NEXT: FriendDecl {{.*}} 'char'
// PRINT-NEXT: friend int;
// PRINT-NEXT: friend long;
// PRINT-NEXT: friend char;
friend int, long, char;

// CHECK-NEXT: FriendDecl {{.*}} 'S'
// PRINT-NEXT: friend S;
friend S;

// CHECK-NEXT: FriendDecl {{.*}} 'S'
// CHECK-NEXT: FriendDecl {{.*}} 'S'
// CHECK-NEXT: FriendDecl {{.*}} 'S'
// PRINT-NEXT: friend S;
// PRINT-NEXT: friend S;
// PRINT-NEXT: friend S;
friend S, S, S;

// CHECK-NEXT: FriendDecl
// CHECK-NEXT: ClassTemplateDecl {{.*}} friend TS
// PRINT-NEXT: friend template <typename> struct TS;
template <typename> friend struct TS;
};

namespace specialisations {
template<class T>
struct C {
template<class U> struct Nested;
};

struct N {
template<class U> class C;
};

// CHECK-LABEL: ClassTemplateDecl {{.*}} Variadic
// PRINT-LABEL: template <typename ...Pack> struct Variadic {
template <typename ...Pack> struct Variadic {
// CHECK: FriendDecl {{.*}} 'Pack'...
// CHECK-NEXT: FriendDecl {{.*}} 'long'
// CHECK-NEXT: FriendDecl {{.*}} 'Pack'...
// PRINT-NEXT: friend Pack...;
// PRINT-NEXT: friend long;
// PRINT-NEXT: friend Pack...;
friend Pack..., long, Pack...;

// CHECK-NEXT: FriendDecl {{.*}} 'TS<Pack>'...
// PRINT-NEXT: friend TS<Pack>...;
friend TS<Pack>...;
};

// CHECK-LABEL: ClassTemplateDecl {{.*}} S2
// PRINT-LABEL: template <class ...Ts> struct S2 {
template<class ...Ts> struct S2 {
// CHECK: FriendDecl {{.*}} 'class C<Ts>':'C<Ts>'...
// PRINT-NEXT: friend class C<Ts>...;
friend class C<Ts>...;

// CHECK-NEXT: FriendDecl {{.*}} 'class N::C<Ts>':'C<Ts>'...
// PRINT-NEXT: friend class N::C<Ts>...
friend class N::C<Ts>...;
};
}
32 changes: 31 additions & 1 deletion clang/test/Analysis/asm.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %clang_analyze_cc1 -analyzer-checker debug.ExprInspection -fheinous-gnu-extensions -w %s -verify
// RUN: %clang_analyze_cc1 -triple=x86_64-unknown-unknown \
// RUN: -analyzer-checker debug.ExprInspection,core -fheinous-gnu-extensions -w %s -verify

int clang_analyzer_eval(int);

Expand All @@ -10,3 +11,32 @@ void testRValueOutput() {
clang_analyzer_eval(global == 1); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(ref == 1); // expected-warning{{UNKNOWN}}
}

void *MyMemcpy(void *d, const void *s, const int n) {
asm volatile (
"cld\n rep movsb\n"
:: "S" (s), "D" (d), "c" (n) : "memory"
);
return d;
}

void testInlineAsmMemcpy(void)
{
int a, b = 10, c;
MyMemcpy(&a, &b, sizeof(b));
c = a; // no-warning
}

void testInlineAsmMemcpyArray(void)
{
int a[10], b[10] = {}, c;
MyMemcpy(&a, &b, sizeof(b));
c = a[8]; // no-warning
}

void testInlineAsmMemcpyUninit(void)
{
int a[10], b[10] = {}, c;
MyMemcpy(&a[1], &b[1], sizeof(b) - sizeof(b[1]));
c = a[0]; // expected-warning{{Assigned value is garbage or undefined}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ struct A {
bool operator<(const A&) const;
bool operator<=(const A&) const = default;
bool operator==(const A&) const && = default; // expected-error {{ref-qualifier '&&' is not allowed on a defaulted comparison operator}}
bool operator<=(const A&&) const = default; // expected-error {{invalid parameter type for defaulted relational comparison operator; found 'const A &&', expected 'const A &'}}
bool operator<=(const int&) const = default; // expected-error {{invalid parameter type for defaulted relational comparison operator; found 'const int &', expected 'const A &'}}
bool operator>=(const A&) const volatile = default; // expected-error {{defaulted comparison function must not be volatile}}
bool operator<=>(const A&) = default; // expected-error {{defaulted member three-way comparison operator must be const-qualified}}
bool operator>=(const B&) const = default; // expected-error-re {{invalid parameter type for defaulted relational comparison operator; found 'const B &', expected 'const A &'{{$}}}}
Expand Down
25 changes: 24 additions & 1 deletion clang/test/CXX/drs/cwg20xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,34 @@ namespace cwg2083 { // cwg2083: partial
#endif
}

namespace cwg2091 { // cwg2091: 2.7
namespace cwg2091 { // cwg2091: 10
template<int &> struct X;
template<int &N> void f(X<N>&);
int n;
void g(X<n> &x) { f(x); }

namespace GH42233 {
enum E { I };

class AA { };
E EV[1] = {I};

template<class ENUM, const ENUM* const VALUES>
struct S
{
template< class E, const E* const V>
friend AA& operator<<( AA& os, const S<E,V>& e );
};

int f()
{
S< E, EV > x;

AA a;
a << x;
return 0;
}
} // namespace GH42233
} // namespace cwg2091

namespace cwg2094 { // cwg2094: 5
Expand Down
59 changes: 59 additions & 0 deletions clang/test/CXX/drs/cwg25xx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,30 @@ using ::cwg2521::operator""_div;
#endif
} // namespace cwg2521

namespace cwg2547 { // cwg2547: 20
#if __cplusplus >= 202302L
struct S;
// since-cxx23-note@-1 {{forward declaration of 'cwg2547::S'}}
// since-cxx23-note@-2 {{forward declaration of 'cwg2547::S'}}
// since-cxx23-note@-3 {{forward declaration of 'cwg2547::S'}}
bool operator==(S, S) = default; // error: S is not complete
// since-cxx23-error@-1 {{variable has incomplete type 'S'}}
// since-cxx23-error@-2 {{variable has incomplete type 'S'}}
// since-cxx23-error@-3 {{equality comparison operator is not a friend of incomplete class 'cwg2547::S'}}
struct S {
friend bool operator==(S, const S&) = default; // error: parameters of different types
// since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'S' vs 'const S &')}}
};
enum E { };
bool operator==(E, E) = default; // error: not a member or friend of a class
// since-cxx23-error@-1 {{invalid parameter type for non-member defaulted equality comparison operator; found 'E', expected class or reference to a constant class}}

struct S2 {
bool operator==(this int, S2) = default;
// since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2547::S2 &'}}
};
#endif
} // namespace cwg2547

#if __cplusplus >= 202302L
namespace cwg2553 { // cwg2553: 18 review 2023-07-14
Expand Down Expand Up @@ -253,6 +277,41 @@ static_assert(__is_layout_compatible(U, V), "");
#endif
} // namespace cwg2583

namespace cwg2586 { // cwg2586: 20
#if __cplusplus >= 202302L
struct X {
X& operator=(this X&, const X&) = default;
X& operator=(this X&, X&) = default;
X& operator=(this X&&, X&&) = default;
// FIXME: The notes could be clearer on *how* the type differs
// e.g., "if an explicit object parameter is used it must be of type reference to 'X'"
X& operator=(this int, const X&) = default;
// since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
// since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
X& operator=(this X, const X&) = default;
// since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
// since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
};
struct Y {
void operator=(this int, const Y&); // This is copy constructor, suppresses implicit declaration
};
static_assert([]<typename T = Y>{
return !requires(T t, const T& ct) { t = ct; };
}());

struct Z {
bool operator==(this const Z&, const Z&) = default;
bool operator==(this Z, Z) = default;
bool operator==(this Z, const Z&) = default;
// since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'Z' vs 'const Z &')}}
bool operator==(this const Z&, Z) = default;
// since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'const Z &' vs 'Z')}}
bool operator==(this int, Z) = default;
// since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2586::Z &'}}
};
#endif
} // namespace cwg2586

namespace cwg2598 { // cwg2598: 18
#if __cplusplus >= 201103L
struct NonLiteral {
Expand Down
25 changes: 25 additions & 0 deletions clang/test/CXX/drs/cwg29xx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %clang_cc1 -std=c++98 -pedantic-errors -verify=expected,cxx98 %s
// RUN: %clang_cc1 -std=c++11 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++14 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++17 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++20 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++23 -pedantic-errors -verify=expected %s
// RUN: %clang_cc1 -std=c++2c -pedantic-errors -verify=expected %s

namespace cwg2917 { // cwg2917: 20 open 2024-07-30
template <typename>
class Foo;

template<class ...> // cxx98-error {{variadic templates are a C++11 extension}}
struct C {
struct Nested { };
};

struct S {
template <typename>
friend class Foo, int; // expected-error {{a friend declaration that befriends a template must contain exactly one type-specifier}}

template <typename ...Ts> // cxx98-error {{variadic templates are a C++11 extension}}
friend class C<Ts>::Nested...; // expected-error {{friend declaration expands pack 'Ts' that is declared it its own template parameter list}}
};
} // namespace cwg2917
48 changes: 24 additions & 24 deletions clang/test/CodeGen/X86/cmpccxadd-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,50 +52,50 @@ long long test_cmplxadd64(void *__A, long long __B, long long __C) {
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_NB);
}

int test_cmpnbexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnbexadd32(
int test_cmpaxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpaxadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 4)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_Z);
}

long long test_cmpnbexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnbexadd64(
long long test_cmpaxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpaxadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 4)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_Z);
}

int test_cmpnbxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnbxadd32(
int test_cmpaexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpaexadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 5)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_NZ);
}

long long test_cmpnbxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnbxadd64(
long long test_cmpaexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpaexadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 5)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_NZ);
}

int test_cmpnlexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnlexadd32(
int test_cmpgxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpgxadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 6)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_BE);
}

long long test_cmpnlexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnlexadd64(
long long test_cmpgxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpgxadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 6)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_BE);
}

int test_cmpnlxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnlxadd32(
int test_cmpgexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpgexadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 7)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_NBE);
}

long long test_cmpnlxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnlxadd64(
long long test_cmpgexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpgexadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 7)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_NBE);
}
Expand Down Expand Up @@ -136,14 +136,14 @@ long long test_cmpnsxadd64(void *__A, long long __B, long long __C) {
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_P);
}

int test_cmpnzxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnzxadd32(
int test_cmpnexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpnexadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 11)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_NP);
}

long long test_cmpnzxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnzxadd64(
long long test_cmpnexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpnexadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 11)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_NP);
}
Expand Down Expand Up @@ -184,14 +184,14 @@ long long test_cmpsxadd64(void *__A, long long __B, long long __C) {
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_LE);
}

int test_cmpzxadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpzxadd32(
int test_cmpexadd32(void *__A, int __B, int __C) {
// CHECK-LABEL: @test_cmpexadd32(
// CHECK: call i32 @llvm.x86.cmpccxadd32(ptr %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 15)
return _cmpccxadd_epi32(__A, __B, __C, _CMPCCX_NLE);
}

long long test_cmpzxadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpzxadd64(
long long test_cmpexadd64(void *__A, long long __B, long long __C) {
// CHECK-LABEL: @test_cmpexadd64(
// CHECK: call i64 @llvm.x86.cmpccxadd64(ptr %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i32 15)
return _cmpccxadd_epi64(__A, __B, __C, _CMPCCX_NLE);
}
78 changes: 78 additions & 0 deletions clang/test/CodeGen/bit-int-ubsan.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// REQUIRES: x86-registered-target
// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -Wno-constant-conversion -Wno-array-bounds -Wno-division-by-zero -Wno-shift-negative-value -Wno-shift-count-negative -Wno-int-to-pointer-cast -fsanitize=array-bounds,enum,float-cast-overflow,integer-divide-by-zero,implicit-unsigned-integer-truncation,implicit-signed-integer-truncation,implicit-integer-sign-change,unsigned-integer-overflow,signed-integer-overflow,shift-base,shift-exponent -O0 -emit-llvm -o - %s | FileCheck %s

// The runtime test checking the _BitInt ubsan feature is located in compiler-rt/test/ubsan/TestCases/Integer/bit-int.c

typedef unsigned int uint32_t;
uint32_t float_divide_by_zero() {
float f = 1.0f / 0.0f;
// CHECK: constant { i16, i16, [8 x i8] } { i16 1, i16 32, [8 x i8] c"'float'\00" }
_BitInt(37) r = (_BitInt(37))f;
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 13, [20 x i8] c"'_BitInt(37)'\00%\00\00\00\00\00" }
return r;
}

uint32_t integer_divide_by_zero() __attribute__((no_sanitize("memory"))) {
_BitInt(37) x = 1 / 0;
// CHECK: constant { i16, i16, [32 x i8] } { i16 0, i16 10, [32 x i8] c"'uint32_t' (aka 'unsigned int')\00" }
return x;
}

uint32_t implicit_unsigned_integer_truncation() {
unsigned _BitInt(37) x = 2U;
x += float_divide_by_zero();
x += integer_divide_by_zero();
x = x + 0xFFFFFFFFFFFFFFFFULL;
// CHECK: constant { i16, i16, [23 x i8] } { i16 0, i16 12, [23 x i8] c"'unsigned _BitInt(37)'\00" }
uint32_t r = x & 0xFFFFFFFF;
return r;
}

uint32_t array_bounds() {
_BitInt(37) x[4];
_BitInt(37) y = x[10];
// CHECK: constant { i16, i16, [17 x i8] } { i16 -1, i16 0, [17 x i8] c"'_BitInt(37)[4]'\00" }
return (uint32_t)y;
}

uint32_t float_cast_overflow() {
float a = 100000000.0f;
_BitInt(7) b = (_BitInt(7))a;
// CHECK: constant { i16, i16, [19 x i8] } { i16 2, i16 7, [19 x i8] c"'_BitInt(7)'\00\07\00\00\00\00\00" }
return b;
}

_BitInt(13) implicit_signed_integer_truncation() {
_BitInt(73) x = (_BitInt(73)) ~((~0UL) >> 1);
return x;
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 {{([[:xdigit:]]{2})}}, [20 x i8] c"'_BitInt(73)'\00I\00\00\00\00\00" }
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 9, [20 x i8] c"'_BitInt(13)'\00\0D\00\00\00\00\00" }
}

uint32_t negative_shift1(unsigned _BitInt(37) x)
__attribute__((no_sanitize("memory"))) {
_BitInt(9) c = -2;
return x >> c;
// CHECK: constant { i16, i16, [19 x i8] } { i16 2, i16 9, [19 x i8] c"'_BitInt(9)'\00\09\00\00\00\00\00" }
}

uint32_t negative_shift2(unsigned _BitInt(37) x)
__attribute__((no_sanitize("memory"))) {
_BitInt(17) c = -2;
return x >> c;
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 11, [20 x i8] c"'_BitInt(17)'\00\11\00\00\00\00\00" }
}

uint32_t negative_shift3(unsigned _BitInt(37) x)
__attribute__((no_sanitize("memory"))) {
_BitInt(34) c = -2;
return x >> c;
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 13, [20 x i8] c"'_BitInt(34)'\00\22\00\00\00\00\00" }
}

uint32_t negative_shift5(unsigned _BitInt(37) x)
__attribute__((no_sanitize("memory"))) {
_BitInt(68) c = -2;
return x >> c;
// CHECK: constant { i16, i16, [20 x i8] } { i16 2, i16 {{([[:xdigit:]]{2})}}, [20 x i8] c"'_BitInt(68)'\00D\00\00\00\00\00" }
}
10 changes: 10 additions & 0 deletions clang/test/CodeGenHLSL/default_validator_version.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -xhlsl -o - %s | FileCheck %s

// CHECK:!dx.valver = !{![[valver:[0-9]+]]}
// CHECK:![[valver]] = !{i32 1, i32 8}

float bar(float a, float b);

float foo(float a, float b) {
return bar(a, b);
}
2 changes: 1 addition & 1 deletion clang/test/CodeGenOpenCL/builtins-amdgcn-gfx11.cl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void test_s_wait_event_export_ready() {
}

// CHECK-LABEL: @test_global_add_f32
// CHECK: {{.*}}call{{.*}} float @llvm.amdgcn.global.atomic.fadd.f32.p1.f32(ptr addrspace(1) %{{.*}}, float %{{.*}})
// CHECK: = atomicrmw fadd ptr addrspace(1) %addr, float %x syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}}
void test_global_add_f32(float *rtn, global float *addr, float x) {
*rtn = __builtin_amdgcn_global_atomic_fadd_f32(addr, x);
}
8 changes: 4 additions & 4 deletions clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx12.cl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ typedef short __attribute__((ext_vector_type(2))) short2;

// CHECK-LABEL: test_local_add_2bf16
// CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat>
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] seq_cst, align 4
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4
// CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16>

// GFX12-LABEL: test_local_add_2bf16
Expand All @@ -22,7 +22,7 @@ short2 test_local_add_2bf16(__local short2 *addr, short2 x) {

// CHECK-LABEL: test_local_add_2bf16_noret
// CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat>
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] seq_cst, align 4
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4
// CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16>

// GFX12-LABEL: test_local_add_2bf16_noret
Expand All @@ -32,15 +32,15 @@ void test_local_add_2bf16_noret(__local short2 *addr, short2 x) {
}

// CHECK-LABEL: test_local_add_2f16
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} monotonic, align 4
// GFX12-LABEL: test_local_add_2f16
// GFX12: ds_pk_add_rtn_f16
half2 test_local_add_2f16(__local half2 *addr, half2 x) {
return __builtin_amdgcn_ds_atomic_fadd_v2f16(addr, x);
}

// CHECK-LABEL: test_local_add_2f16_noret
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} monotonic, align 4
// GFX12-LABEL: test_local_add_2f16_noret
// GFX12: ds_pk_add_f16
void test_local_add_2f16_noret(__local half2 *addr, half2 x) {
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx8.cl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// REQUIRES: amdgpu-registered-target

// CHECK-LABEL: test_fadd_local
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, float %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, float %{{.+}} monotonic, align 4
// GFX8-LABEL: test_fadd_local$local:
// GFX8: ds_add_rtn_f32 v2, v0, v1
// GFX8: s_endpgm
Expand All @@ -16,7 +16,7 @@ kernel void test_fadd_local(__local float *ptr, float val){
}

// CHECK-LABEL: test_fadd_local_volatile
// CHECK: = atomicrmw volatile fadd ptr addrspace(3) %{{.+}}, float %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw volatile fadd ptr addrspace(3) %{{.+}}, float %{{.+}} monotonic, align 4
kernel void test_fadd_local_volatile(volatile __local float *ptr, float val){
volatile float *res;
*res = __builtin_amdgcn_ds_atomic_fadd_f32(ptr, val);
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx90a.cl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
typedef half __attribute__((ext_vector_type(2))) half2;

// CHECK-LABEL: test_global_add_f64
// CHECK: call double @llvm.amdgcn.global.atomic.fadd.f64.p1.f64(ptr addrspace(1) %{{.*}}, double %{{.*}})
// CHECK: = atomicrmw fadd ptr addrspace(1) %{{.+}}, double %{{.+}} syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory !{{[0-9]+$}}
// GFX90A-LABEL: test_global_add_f64$local:
// GFX90A: global_atomic_add_f64
void test_global_add_f64(__global double *addr, double x) {
Expand Down Expand Up @@ -99,7 +99,7 @@ void test_flat_global_max_f64(__global double *addr, double x){
}

// CHECK-LABEL: test_ds_add_local_f64
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, double %{{.+}} seq_cst, align 8
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, double %{{.+}} monotonic, align 8
// GFX90A: test_ds_add_local_f64$local
// GFX90A: ds_add_rtn_f64
void test_ds_add_local_f64(__local double *addr, double x){
Expand All @@ -108,7 +108,7 @@ void test_ds_add_local_f64(__local double *addr, double x){
}

// CHECK-LABEL: test_ds_addf_local_f32
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, float %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, float %{{.+}} monotonic, align 4
// GFX90A-LABEL: test_ds_addf_local_f32$local
// GFX90A: ds_add_rtn_f32
void test_ds_addf_local_f32(__local float *addr, float x){
Expand All @@ -117,7 +117,7 @@ void test_ds_addf_local_f32(__local float *addr, float x){
}

// CHECK-LABEL: @test_global_add_f32
// CHECK: call float @llvm.amdgcn.global.atomic.fadd.f32.p1.f32(ptr addrspace(1) %{{.*}}, float %{{.*}})
// CHECK: = atomicrmw fadd ptr addrspace(1) %{{.+}}, float %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}}
void test_global_add_f32(float *rtn, global float *addr, float x) {
*rtn = __builtin_amdgcn_global_atomic_fadd_f32(addr, x);
}
8 changes: 4 additions & 4 deletions clang/test/CodeGenOpenCL/builtins-fp-atomics-gfx940.cl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ short2 test_global_add_2bf16(__global short2 *addr, short2 x) {
// CHECK-LABEL: test_local_add_2bf16

// CHECK: [[BC0:%.+]] = bitcast <2 x i16> {{.+}} to <2 x bfloat>
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] seq_cst, align 4
// CHECK: [[RMW:%.+]] = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x bfloat> [[BC0]] syncscope("agent") monotonic, align 4{{$}}
// CHECK-NEXT: bitcast <2 x bfloat> [[RMW]] to <2 x i16>

// GFX940-LABEL: test_local_add_2bf16
Expand All @@ -54,23 +54,23 @@ short2 test_local_add_2bf16(__local short2 *addr, short2 x) {
}

// CHECK-LABEL: test_local_add_2f16
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} monotonic, align 4
// GFX940-LABEL: test_local_add_2f16
// GFX940: ds_pk_add_rtn_f16
half2 test_local_add_2f16(__local half2 *addr, half2 x) {
return __builtin_amdgcn_ds_atomic_fadd_v2f16(addr, x);
}

// CHECK-LABEL: test_local_add_2f16_noret
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} seq_cst, align 4
// CHECK: = atomicrmw fadd ptr addrspace(3) %{{.+}}, <2 x half> %{{.+}} monotonic, align 4
// GFX940-LABEL: test_local_add_2f16_noret
// GFX940: ds_pk_add_f16
void test_local_add_2f16_noret(__local half2 *addr, half2 x) {
__builtin_amdgcn_ds_atomic_fadd_v2f16(addr, x);
}

// CHECK-LABEL: @test_global_add_f32
// CHECK: call float @llvm.amdgcn.global.atomic.fadd.f32.p1.f32(ptr addrspace(1) %{{.*}}, float %{{.*}})
// CHECK: = atomicrmw fadd ptr addrspace(1) %{{.+}}, float %{{.+}} syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory !{{[0-9]+}}, !amdgpu.ignore.denormal.mode !{{[0-9]+$}}
void test_global_add_f32(float *rtn, global float *addr, float x) {
*rtn = __builtin_amdgcn_global_atomic_fadd_f32(addr, x);
}
5 changes: 2 additions & 3 deletions clang/test/Driver/arm-target-as-mimplicit-it.s
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

/// Test invalid input.
// RUN: not %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID
// RUN: not %clang -target arm-linux-gnueabi -### -Xassembler -mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=XINVALID
// RUN: not %clang -target arm-linux-gnueabi -### -Xassembler -mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID
// RUN: not %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always -Wa,-mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID
// RUN: not %clang -target arm-linux-gnueabi -### -Wa,-mimplicit-it=always,-mimplicit-it=foo %s 2>&1 | FileCheck %s --check-prefix=INVALID

Expand All @@ -47,5 +47,4 @@
// NEVER-NOT: "-arm-implicit-it={{.*}}"
// ARM: "-mllvm" "-arm-implicit-it=arm"
// THUMB: "-mllvm" "-arm-implicit-it=thumb"
// INVALID: error: unsupported argument '-mimplicit-it=foo' to option '-Wa,'
// XINVALID: error: unsupported argument '-mimplicit-it=foo' to option '-Xassembler'
// INVALID: error: unsupported argument 'foo' to option '-Wa,-mimplicit-it='
2 changes: 2 additions & 0 deletions clang/test/Driver/crel.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@

/// The --allow-experimental-crel error check doesn't apply to LTO.
// RUN: %clang -### --target=x86_64-linux -Werror -flto -Wa,--crel %s 2>&1 | FileCheck %s --check-prefix=LTO
// RUN: %clang -### --target=x86_64-linux -Werror -flto -Wa,--crel -Wa,--no-crel %s 2>&1 | FileCheck %s --check-prefix=LTO-NO

// LTO: "-plugin-opt=-crel"
// LTO-NO-NOT: "-plugin-opt=-crel"

// RUN: touch %t.o
// RUN: not %clang -### --target=mips64-linux-gnu -flto -Wa,--crel %t.o 2>&1 | FileCheck %s --check-prefix=ERR
8 changes: 4 additions & 4 deletions clang/test/Driver/msse2avx.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: %clang -### -c -target x86_64 -march=x86-64 -Xassembler -msse2avx %s 2>&1 | FileCheck %s
// RUN: %clang -### -c -target x86_64 -march=x86-64 -x assembler -Xassembler -msse2avx %s 2>&1 | FileCheck %s
// RUN: %clang -### -c --target=x86_64 -march=x86-64 -Wa,-msse2avx %s 2>&1 | FileCheck %s
// RUN: %clang -### -c --target=x86_64 -march=x86-64 -x assembler -Xassembler -msse2avx %s 2>&1 | FileCheck %s

// CHECK: "-msse2avx"

// RUN: not %clang -### -c -target aarch64 -march=armv8a -msse2avx %s 2>&1 | FileCheck --check-prefix=ERR %s
// ERR: error: unsupported option '-msse2avx' for target 'aarch64'
// RUN: not %clang -### -c --target=aarch64 -march=armv8a -Wa,-msse2avx %s 2>&1 | FileCheck --check-prefix=ERR %s
// ERR: error: unsupported argument '-msse2avx' to option '-Wa,'
1 change: 0 additions & 1 deletion clang/test/Driver/ohos.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
// RUN: --sysroot=%S/Inputs/ohos_native_tree/sysroot -fuse-ld=ld -march=armv7-a -mcpu=cortex-a7 -mfloat-abi=soft 2>&1 \
// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARM-A7-SOFT %s
// CHECK: {{.*}}clang{{.*}}" "-cc1"
// CHECK-NOT: "--mrelax-relocations"
// CHECK-NOT: "-munwind-tables"
// CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]"
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
Expand Down
15 changes: 15 additions & 0 deletions clang/test/Driver/print-multi-selection-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,18 @@
// RUN: %clang -print-multi-flags-experimental --target=aarch64-none-elf -march=armv9-a | FileCheck --check-prefix=CHECK-SVE2 %s
// CHECK-SVE2: --target=aarch64-unknown-none-elf
// CHECK-SVE2: -march=armv{{.*}}-a{{.*}}+simd{{.*}}+sve{{.*}}+sve2{{.*}}

// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32g | FileCheck --check-prefix=CHECK-RV32 %s
// CHECK-RV32: --target=riscv32-unknown-none-elf
// CHECK-RV32: -mabi=ilp32d
// CHECK-RV32: -march=rv32i{{[0-9]+p[0-9]+}}_m{{[0-9]+p[0-9]+}}_a{{[0-9]+p[0-9]+}}_f{{[0-9]+p[0-9]+}}_d{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}_zifencei{{[0-9]+p[0-9]+}}_zmmul{{[0-9]+p[0-9]+}}

// RUN: %clang -print-multi-flags-experimental --target=riscv64-none-elf -march=rv64g | FileCheck --check-prefix=CHECK-RV64 %s
// CHECK-RV64: --target=riscv64-unknown-none-elf
// CHECK-RV64: -mabi=lp64d
// CHECK-RV64: -march=rv64i{{[0-9]+p[0-9]+}}_m{{[0-9]+p[0-9]+}}_a{{[0-9]+p[0-9]+}}_f{{[0-9]+p[0-9]+}}_d{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}_zifencei{{[0-9]+p[0-9]+}}_zmmul{{[0-9]+p[0-9]+}}

// RUN: %clang -print-multi-flags-experimental --target=riscv32-none-elf -march=rv32e_zicsr_c | FileCheck --check-prefix=CHECK-RV32E-ORDER %s
// CHECK-RV32E-ORDER: --target=riscv32-unknown-none-elf
// CHECK-RV32E-ORDER: -mabi=ilp32e
// CHECK-RV32E-ORDER: -march=rv32e{{[0-9]+p[0-9]+}}_c{{[0-9]+p[0-9]+}}_zicsr{{[0-9]+p[0-9]+}}
11 changes: 10 additions & 1 deletion clang/test/Driver/relax.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
// RUN: %clang -### -c -integrated-as -Wa,--mrelax-relocations=no %s 2>&1 | FileCheck %s
// RUN: %clang -### --target=x86_64 -c -Wa,--mrelax-relocations=no %s 2>&1 | FileCheck %s

// CHECK: "-cc1"
// CHECK: "-mrelax-relocations=no"

// RUN: not %clang -### --target=x86_64 -c -Wa,-mrelax-relocations=x %s 2>&1 | FileCheck %s --check-prefix=ERR
// ERR: error: unsupported argument 'x' to option '-Wa,-mrelax-relocations='

// RUN: not %clang -### --target=aarch64 -c -Wa,-mrelax-relocations=no %s 2>&1 | FileCheck %s --check-prefix=ERR2
// ERR2: error: unsupported argument '-mrelax-relocations=no' to option '-Wa,'

// RUN: not %clang -### --target=x86_64-apple-darwin -c -Wa,-mrelax-relocations=no %s 2>&1 | FileCheck %s --check-prefix=ERR3
// ERR3: error: unsupported option '-Wa,-mrelax-relocations=' for target 'x86_64-apple-darwin'
3 changes: 3 additions & 0 deletions clang/test/Driver/sparc-target-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@
// RUN: %clang --target=sparc -msoft-quad-float %s -### 2>&1 | FileCheck -check-prefix=SOFT-QUAD-FLOAT %s
// HARD-QUAD-FLOAT: "-target-feature" "+hard-quad-float"
// SOFT-QUAD-FLOAT: "-target-feature" "-hard-quad-float"

// RUN: %clang --target=sparc -mv8plus %s -### 2>&1 | FileCheck -check-prefix=V8PLUS %s
// V8PLUS: "-target-feature" "+v8plus"
175 changes: 175 additions & 0 deletions clang/test/ExtractAPI/inherited_availability.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing -triple arm64-apple-macosx \
// RUN: -x objective-c-header %s -o %t/output.symbols.json -verify


// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix A
__attribute__((availability(macos, introduced=9.0, deprecated=12.0, obsoleted=20.0)))
@interface A
// A-LABEL: "!testLabel": "c:objc(cs)A"
// A: "availability": [
// A-NEXT: {
// A-NEXT: "deprecated": {
// A-NEXT: "major": 12,
// A-NEXT: "minor": 0,
// A-NEXT: "patch": 0
// A-NEXT: }
// A-NEXT: "domain": "macos"
// A-NEXT: "introduced": {
// A-NEXT: "major": 9,
// A-NEXT: "minor": 0,
// A-NEXT: "patch": 0
// A-NEXT: }
// A-NEXT: "obsoleted": {
// A-NEXT: "major": 20,
// A-NEXT: "minor": 0,
// A-NEXT: "patch": 0
// A-NEXT: }
// A-NEXT: }
// A-NEXT: ]

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix CP
@property(class) int CP;
// CP-LABEL: "!testLabel": "c:objc(cs)A(cpy)CP"
// CP: "availability": [
// CP-NEXT: {
// CP-NEXT: "deprecated": {
// CP-NEXT: "major": 12,
// CP-NEXT: "minor": 0,
// CP-NEXT: "patch": 0
// CP-NEXT: }
// CP-NEXT: "domain": "macos"
// CP-NEXT: "introduced": {
// CP-NEXT: "major": 9,
// CP-NEXT: "minor": 0,
// CP-NEXT: "patch": 0
// CP-NEXT: }
// CP-NEXT: "obsoleted": {
// CP-NEXT: "major": 20,
// CP-NEXT: "minor": 0,
// CP-NEXT: "patch": 0
// CP-NEXT: }
// CP-NEXT: }
// CP-NEXT: ]

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix IP
@property int IP;
// IP-LABEL: "!testLabel": "c:objc(cs)A(py)IP"
// IP: "availability": [
// IP-NEXT: {
// IP-NEXT: "deprecated": {
// IP-NEXT: "major": 12,
// IP-NEXT: "minor": 0,
// IP-NEXT: "patch": 0
// IP-NEXT: }
// IP-NEXT: "domain": "macos"
// IP-NEXT: "introduced": {
// IP-NEXT: "major": 9,
// IP-NEXT: "minor": 0,
// IP-NEXT: "patch": 0
// IP-NEXT: }
// IP-NEXT: "obsoleted": {
// IP-NEXT: "major": 20,
// IP-NEXT: "minor": 0,
// IP-NEXT: "patch": 0
// IP-NEXT: }
// IP-NEXT: }
// IP-NEXT: ]

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix MR
@property int moreRestrictive __attribute__((availability(macos, introduced=10.0, deprecated=11.0, obsoleted=19.0)));
// MR-LABEL: "!testLabel": "c:objc(cs)A(py)moreRestrictive"
// MR: "availability": [
// MR-NEXT: {
// MR-NEXT: "deprecated": {
// MR-NEXT: "major": 11,
// MR-NEXT: "minor": 0,
// MR-NEXT: "patch": 0
// MR-NEXT: }
// MR-NEXT: "domain": "macos"
// MR-NEXT: "introduced": {
// MR-NEXT: "major": 10,
// MR-NEXT: "minor": 0,
// MR-NEXT: "patch": 0
// MR-NEXT: }
// MR-NEXT: "obsoleted": {
// MR-NEXT: "major": 19,
// MR-NEXT: "minor": 0,
// MR-NEXT: "patch": 0
// MR-NEXT: }
// MR-NEXT: }
// MR-NEXT: ]

@end

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix B
__attribute__((deprecated("B is deprecated")))
@interface B
// B-LABEL: "!testLabel": "c:objc(cs)B"
// B: "availability": [
// B-NEXT: {
// B-NEXT: "domain": "*"
// B-NEXT: "isUnconditionallyDeprecated": true
// B-NEXT: }
// B-NEXT: ]

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix BIP
@property int BIP;
// BIP-LABEL: "!testLabel": "c:objc(cs)B(py)BIP"
// BIP: "availability": [
// BIP-NEXT: {
// BIP-NEXT: "domain": "*"
// BIP-NEXT: "isUnconditionallyDeprecated": true
// BIP-NEXT: }
// BIP-NEXT: ]
@end

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix C
__attribute__((availability(macos, unavailable)))
@interface C
// C-LABEL: "!testLabel": "c:objc(cs)C"
// C: "availability": [
// C-NEXT: {
// C-NEXT: "domain": "macos"
// C-NEXT: "isUnconditionallyUnavailable": true
// C-NEXT: }
// C-NEXT: ]

// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix CIP
@property int CIP;
// CIP-LABEL: "!testLabel": "c:objc(cs)C(py)CIP"
// CIP: "availability": [
// CIP-NEXT: {
// CIP-NEXT: "domain": "macos"
// CIP-NEXT: "isUnconditionallyUnavailable": true
// CIP-NEXT: }
// CIP-NEXT: ]
@end

@interface D
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix DIP
@property int DIP __attribute__((availability(macos, introduced=10.0, deprecated=11.0, obsoleted=19.0)));
// DIP-LABEL: "!testLabel": "c:objc(cs)D(py)DIP"
// DIP: "availability": [
// DIP-NEXT: {
// DIP-NEXT: "deprecated": {
// DIP-NEXT: "major": 11,
// DIP-NEXT: "minor": 0,
// DIP-NEXT: "patch": 0
// DIP-NEXT: }
// DIP-NEXT: "domain": "macos"
// DIP-NEXT: "introduced": {
// DIP-NEXT: "major": 10,
// DIP-NEXT: "minor": 0,
// DIP-NEXT: "patch": 0
// DIP-NEXT: }
// DIP-NEXT: "obsoleted": {
// DIP-NEXT: "major": 19,
// DIP-NEXT: "minor": 0,
// DIP-NEXT: "patch": 0
// DIP-NEXT: }
// DIP-NEXT: }
// DIP-NEXT: ]
@end

// expected-no-diagnostics
20 changes: 20 additions & 0 deletions clang/test/ExtractAPI/platform-serialization.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -extract-api --pretty-sgf -triple arm64-apple-ios17.1-macabi \
// RUN: -x c-header %s -verify -o - | FileCheck %s

int a;

// CHECK: "platform": {
// CHECK-NEXT: "architecture": "arm64",
// CHECK-NEXT: "environment": "macabi",
// CHECK-NEXT: "operatingSystem": {
// CHECK-NEXT: "minimumVersion": {
// CHECK-NEXT: "major": 14,
// CHECK-NEXT: "minor": 0,
// CHECK-NEXT: "patch": 0
// CHECK-NEXT: },
// CHECK-NEXT: "name": "ios"
// CHECK-NEXT: },
// CHECK-NEXT: "vendor": "apple"
// CHECK-NEXT: }

// expected-no-diagnostics
41 changes: 41 additions & 0 deletions clang/test/Headers/gpu_disabled_math.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5
// RUN: %clang_cc1 -include __clang_hip_runtime_wrapper.h \
// RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \
// RUN: -internal-isystem %S/Inputs/include \
// RUN: -triple amdgcn-amd-amdhsa -aux-triple x86_64-unknown-unknown \
// RUN: -target-cpu gfx906 -emit-llvm %s -fcuda-is-device -o - \
// RUN: -D __CLANG_GPU_DISABLE_MATH_WRAPPERS | FileCheck -check-prefix=AMDGPU %s

// RUN: %clang_cc1 -include __clang_cuda_runtime_wrapper.h \
// RUN: -internal-isystem %S/../../lib/Headers/cuda_wrappers \
// RUN: -internal-isystem %S/Inputs/include \
// RUN: -triple nvptx64-nvidia-cuda -aux-triple x86_64-unknown-unknown \
// RUN: -target-cpu sm_90 -emit-llvm %s -fcuda-is-device -o - \
// RUN: -D __CLANG_GPU_DISABLE_MATH_WRAPPERS | FileCheck -check-prefix=NVPTX %s

extern "C" double sin(double x);

// AMDGPU-LABEL: define dso_local noundef double @_Z3food(
// AMDGPU-SAME: double noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
// AMDGPU-NEXT: [[ENTRY:.*:]]
// AMDGPU-NEXT: [[RETVAL:%.*]] = alloca double, align 8, addrspace(5)
// AMDGPU-NEXT: [[X_ADDR:%.*]] = alloca double, align 8, addrspace(5)
// AMDGPU-NEXT: [[RETVAL_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RETVAL]] to ptr
// AMDGPU-NEXT: [[X_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[X_ADDR]] to ptr
// AMDGPU-NEXT: store double [[X]], ptr [[X_ADDR_ASCAST]], align 8
// AMDGPU-NEXT: [[TMP0:%.*]] = load double, ptr [[X_ADDR_ASCAST]], align 8
// AMDGPU-NEXT: [[TMP1:%.*]] = call double @llvm.sin.f64(double [[TMP0]])
// AMDGPU-NEXT: ret double [[TMP1]]
//
// NVPTX-LABEL: define dso_local noundef double @_Z3food(
// NVPTX-SAME: double noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] {
// NVPTX-NEXT: [[ENTRY:.*:]]
// NVPTX-NEXT: [[X_ADDR:%.*]] = alloca double, align 8
// NVPTX-NEXT: store double [[X]], ptr [[X_ADDR]], align 8
// NVPTX-NEXT: [[TMP0:%.*]] = load double, ptr [[X_ADDR]], align 8
// NVPTX-NEXT: [[TMP1:%.*]] = call double @llvm.sin.f64(double [[TMP0]])
// NVPTX-NEXT: ret double [[TMP1]]
//
double foo(double x) {
return sin(x);
}
4 changes: 4 additions & 0 deletions clang/test/Lexer/cxx-features.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@

// --- C++26 features ---

#if check(variadic_friend, 202403, 202403, 202403, 202403, 202403, 202403, 202403)
#error "wrong value for __cpp_variadic_friend"
#endif

#if check(deleted_function, 202403, 202403, 202403, 202403, 202403, 202403, 202403)
#error "wrong value for __cpp_deleted_function"
#endif
Expand Down
3 changes: 1 addition & 2 deletions clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@ This test serves two purposes:

The list of warnings below should NEVER grow. It should gradually shrink to 0.

CHECK: Warnings without flags (65):
CHECK: Warnings without flags (64):

CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_missing_whitespace_after_macro_name
CHECK-NEXT: ext_new_paren_array_nonconst
CHECK-NEXT: ext_plain_complex
CHECK-NEXT: ext_template_arg_extra_parens
CHECK-NEXT: ext_template_spec_extra_headers
CHECK-NEXT: ext_typecheck_cond_incompatible_operands
CHECK-NEXT: ext_typecheck_ordered_comparison_of_pointer_integer
CHECK-NEXT: ext_using_undefined_std
Expand Down
1 change: 1 addition & 0 deletions clang/test/Modules/enum-codegen.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fmodules-cache-path=%t %s -emit-llvm -o - | FileCheck %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -fmodules -fmodules-cache-path=%t %s -emit-llvm -o - -fexperimental-new-constant-interpreter | FileCheck %s

// CHECK: @{{.*var.*}} = {{.*}} %union.union_type { i8 1 },

Expand Down
12 changes: 6 additions & 6 deletions clang/test/OpenMP/target_teams_codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ int foo(int n) {
aa += 1;
}

#pragma omp target teams ompx_bare num_teams(1, 2) thread_limit(1)
#pragma omp target teams ompx_bare num_teams(1, 2) thread_limit(1, 2)
{
a += 1;
aa += 1;
}

#pragma omp target teams ompx_bare num_teams(1, 2, 3) thread_limit(1)
#pragma omp target teams ompx_bare num_teams(1, 2, 3) thread_limit(1, 2, 3)
{
a += 1;
aa += 1;
Expand Down Expand Up @@ -667,7 +667,7 @@ int bar(int n){
// CHECK1-NEXT: [[TMP144:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 10
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 2, i32 0], ptr [[TMP144]], align 4
// CHECK1-NEXT: [[TMP145:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 11
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP145]], align 4
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 2, i32 0], ptr [[TMP145]], align 4
// CHECK1-NEXT: [[TMP146:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 12
// CHECK1-NEXT: store i32 0, ptr [[TMP146]], align 4
// CHECK1-NEXT: [[TMP147:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l130.region_id, ptr [[KERNEL_ARGS29]])
Expand Down Expand Up @@ -720,7 +720,7 @@ int bar(int n){
// CHECK1-NEXT: [[TMP171:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 10
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 2, i32 3], ptr [[TMP171]], align 4
// CHECK1-NEXT: [[TMP172:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 11
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP172]], align 4
// CHECK1-NEXT: store [3 x i32] [i32 1, i32 2, i32 3], ptr [[TMP172]], align 4
// CHECK1-NEXT: [[TMP173:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 12
// CHECK1-NEXT: store i32 0, ptr [[TMP173]], align 4
// CHECK1-NEXT: [[TMP174:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l136.region_id, ptr [[KERNEL_ARGS37]])
Expand Down Expand Up @@ -2458,7 +2458,7 @@ int bar(int n){
// CHECK3-NEXT: [[TMP142:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 10
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 2, i32 0], ptr [[TMP142]], align 4
// CHECK3-NEXT: [[TMP143:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 11
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP143]], align 4
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 2, i32 0], ptr [[TMP143]], align 4
// CHECK3-NEXT: [[TMP144:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS29]], i32 0, i32 12
// CHECK3-NEXT: store i32 0, ptr [[TMP144]], align 4
// CHECK3-NEXT: [[TMP145:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l130.region_id, ptr [[KERNEL_ARGS29]])
Expand Down Expand Up @@ -2511,7 +2511,7 @@ int bar(int n){
// CHECK3-NEXT: [[TMP169:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 10
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 2, i32 3], ptr [[TMP169]], align 4
// CHECK3-NEXT: [[TMP170:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 11
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 0, i32 0], ptr [[TMP170]], align 4
// CHECK3-NEXT: store [3 x i32] [i32 1, i32 2, i32 3], ptr [[TMP170]], align 4
// CHECK3-NEXT: [[TMP171:%.*]] = getelementptr inbounds nuw [[STRUCT___TGT_KERNEL_ARGUMENTS]], ptr [[KERNEL_ARGS37]], i32 0, i32 12
// CHECK3-NEXT: store i32 0, ptr [[TMP171]], align 4
// CHECK3-NEXT: [[TMP172:%.*]] = call i32 @__tgt_target_kernel(ptr @[[GLOB1]], i64 -1, i32 1, i32 1, ptr @.{{__omp_offloading_[0-9a-z]+_[0-9a-z]+}}__Z3fooi_l136.region_id, ptr [[KERNEL_ARGS37]])
Expand Down
13 changes: 13 additions & 0 deletions clang/test/Parser/attr-order.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,16 @@ template <int a>

template <int a>
[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok

extern "C" {
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int l(int); // ok
[[__maybe_unused__]] __attribute__ ((__warn_unused_result__)) int m(int); // ok
}

extern "C" {
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int n (int); // ok
__attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] static int o (int x) { return x; }; // ok
}

extern "C" __attribute__ ((__warn_unused_result__)) [[__maybe_unused__]] int p(int); // ok
extern "C" [[__maybe_unused__]] __attribute__ ((__warn_unused_result__)) int q(int); // ok
16 changes: 16 additions & 0 deletions clang/test/Parser/cxx2c-variadic-friends-ext-diags.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %clang_cc1 -std=c++2c -verify=compat -fsyntax-only -Wpre-c++26-compat %s
// RUN: %clang_cc1 -std=c++11 -verify=pre2c -fsyntax-only -Wc++26-extensions %s

struct S {
friend int, long, char; // compat-warning {{variadic 'friend' declarations are incompatible with C++ standards before C++2c}} \
// pre2c-warning {{variadic 'friend' declarations are a C++2c extension}}
};

template <typename ...Types>
struct TS {
friend Types...; // compat-warning {{variadic 'friend' declarations are incompatible with C++ standards before C++2c}} \
// pre2c-warning {{variadic 'friend' declarations are a C++2c extension}}

friend int, Types..., Types...; // compat-warning {{variadic 'friend' declarations are incompatible with C++ standards before C++2c}} \
// pre2c-warning {{variadic 'friend' declarations are a C++2c extension}}
};
91 changes: 91 additions & 0 deletions clang/test/Parser/cxx2c-variadic-friends.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2c %s

template <typename> struct TS; // #template

struct Errors {
friend int, int;
friend int, long, char;

// We simply diagnose and ignore the '...' here.
friend float...; // expected-error {{pack expansion does not contain any unexpanded parameter packs}}

friend short..., unsigned, unsigned short...; // expected-error 2 {{pack expansion does not contain any unexpanded parameter packs}}

template <typename>
friend struct TS, int; // expected-error {{a friend declaration that befriends a template must contain exactly one type-specifier}}

double friend; // expected-error {{'friend' must appear first in a non-function declaration}}
double friend, double; // expected-error {{expected member name or ';' after declaration specifiers}}
};

template <typename>
struct C { template<class T> class Nested; };

template <typename, typename>
struct D { template<class T> class Nested; };

template <bool>
struct E { template<class T> class Nested; };

template<class... Ts> // expected-note {{template parameter is declared here}}
struct VS {
friend Ts...;

friend class Ts...; // expected-error {{declaration of 'Ts' shadows template parameter}}
// expected-error@-1 {{pack expansion does not contain any unexpanded parameter packs}}

// TODO: Fix-it hint to insert '...'.
friend Ts; // expected-error {{friend declaration contains unexpanded parameter pack}}

template<class... Us>
friend Us...; // expected-error {{friend type templates must use an elaborated type}}

template<class... Us> // expected-note {{is declared here}}
friend class Us...; // expected-error {{declaration of 'Us' shadows template parameter}}

template<class U>
friend class C<Ts>::template Nested<U>...; // expected-error {{cannot specialize a dependent template}}

template<class... Us>
friend class C<Ts...>::template Nested<Us>...; // expected-error {{cannot specialize a dependent template}}

// Nonsense (see CWG 2917).
template<class... Us>
friend class C<Us>::Nested...; // expected-error {{friend declaration expands pack 'Us' that is declared it its own template parameter list}}

template<bool... Bs>
friend class E<Bs>::Nested...; // expected-error {{friend declaration expands pack 'Bs' that is declared it its own template parameter list}}

// FIXME: Both of these should be valid, but we can't handle these at
// the moment because the NNS is dependent.
template<class ...T>
friend class TS<Ts>::Nested...; // expected-warning {{dependent nested name specifier 'TS<Ts>::' for friend template declaration is not supported; ignoring this friend declaration}}

template<class T>
friend class D<T, Ts>::Nested...; // expected-warning {{dependent nested name specifier 'D<T, Ts>::' for friend class declaration is not supported; turning off access control for 'VS'}}
};

namespace length_mismatch {
struct A {
template <typename...>
struct Nested {
struct Foo{};
};
};
template <typename ...Ts>
struct S {
template <typename ...Us>
struct T {
// expected-error@+2 {{pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (1 vs. 2)}}
// expected-error@+1 {{pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (2 vs. 1)}}
friend class Ts::template Nested<Us>::Foo...;
};
};

void f() {
S<A>::T<int> s;
S<A, A>::T<int, long> s2;
S<A>::T<int, long> s3; // expected-note {{in instantiation of}}
S<A, A>::T<int> s4; // expected-note {{in instantiation of}}
}
}
28 changes: 14 additions & 14 deletions clang/test/SemaCXX/MicrosoftExtensions.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17 -fexceptions -fcxx-exceptions -DTEST2
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++98 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++11 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
// RUN: %clang_cc1 -std=c++14 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify=expected,precxx17,ms-union-ext-disabled -fexceptions -fcxx-exceptions -DTEST2
// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify=expected,ms-union-ext -DTEST3
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify=ms-union-ext -fms-extensions -fms-compatibility-version=18.00
// RUN: %clang_cc1 -std=c++17 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -verify=ms-union-ext-disabled -fms-extensions -fms-compatibility-version=19.00

#if TEST1

Expand Down Expand Up @@ -384,11 +386,6 @@ void TestSP9() {
c3.h(); // Overloaded unary op operand
}

union u {
int *i1;
int &i2; // expected-warning {{union member 'i2' has reference type 'int &', which is a Microsoft extension}}
};

// Property getter using reference.
struct SP11 {
__declspec(property(get=GetV)) int V;
Expand Down Expand Up @@ -619,9 +616,12 @@ template<typename T> struct A {};
template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-warning {{implicit 'typename' is a C++20 extension}}
}

#else

#error Unknown test mode

#endif

union u {
int *i1;

// ms-union-ext-warning@+2 {{union member 'i2' has reference type 'int &', which is a Microsoft extension}}
// ms-union-ext-disabled-error@+1 {{union member 'i2' has reference type 'int &'}}
int &i2;
};
535 changes: 329 additions & 206 deletions clang/test/SemaCXX/constexpr-vectors.cpp

Large diffs are not rendered by default.

62 changes: 60 additions & 2 deletions clang/test/SemaCXX/cxx2b-deducing-this.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,10 +729,10 @@ struct S2 {
};

S2& S2::operator=(this int&& self, const S2&) = default;
// expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted copy assignment operator should match the type of the class 'S2'}}
// expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted copy assignment operator should be reference to 'S2'}}

S2& S2::operator=(this int&& self, S2&&) = default;
// expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted move assignment operator should match the type of the class 'S2'}}
// expected-error@-1 {{the type of the explicit object parameter of an explicitly-defaulted move assignment operator should be reference to 'S2'}}

struct Move {
Move& operator=(this int&, Move&&) = default;
Expand Down Expand Up @@ -972,3 +972,61 @@ struct R {
f(r_value_ref); // expected-error {{no matching member function for call to 'f'}}
}
};

namespace GH100329 {
struct A {
bool operator == (this const int&, const A&);
};
bool A::operator == (this const int&, const A&) = default;
// expected-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'const int &', expected 'const GH100329::A &'}}
} // namespace GH100329

namespace defaulted_assign {
struct A {
A& operator=(this A, const A&) = default;
// expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
// expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
A& operator=(this int, const A&) = default;
// expected-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
// expected-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
};
} // namespace defaulted_assign

namespace defaulted_compare {
struct A {
bool operator==(this A&, const A&) = default;
// expected-error@-1 {{defaulted member equality comparison operator must be const-qualified}}
bool operator==(this const A, const A&) = default;
// expected-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'const A', expected 'const defaulted_compare::A &'}}
bool operator==(this A, A) = default;
};
struct B {
int a;
bool operator==(this B, B) = default;
};
static_assert(B{0} == B{0});
static_assert(B{0} != B{1});
template<B b>
struct X;
static_assert(__is_same(X<B{0}>, X<B{0}>));
static_assert(!__is_same(X<B{0}>, X<B{1}>));
} // namespace defaulted_compare

namespace GH102025 {
struct Foo {
template <class T>
constexpr auto operator[](this T &&self, auto... i) // expected-note {{candidate template ignored: substitution failure [with T = Foo &, i:auto = <>]: member '_evaluate' used before its declaration}}
-> decltype(_evaluate(self, i...)) {
return self._evaluate(i...);
}

private:
template <class T>
constexpr auto _evaluate(this T &&self, auto... i) -> decltype((i + ...));
};

int main() {
Foo foo;
return foo[]; // expected-error {{no viable overloaded operator[] for type 'Foo'}}
}
}
156 changes: 156 additions & 0 deletions clang/test/SemaCXX/cxx2c-variadic-friends.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2c %s

struct A;
struct B;
struct C;

struct S {};
template <typename> struct TS {};

template <typename ...Pack>
class X {
friend Pack...;
static void f() { } // expected-note {{declared private here}}
};

class Y {
friend A, B, C;
static void g() { } // expected-note {{declared private here}}
};

struct A {
A() {
X<A>::f();
Y::g();
};
};

struct B {
B() {
X<B, C>::f();
Y::g();
};
};

struct C {
C() {
X<A, B, C>::f();
Y::g();
};
};

struct D {
D() {
X<A, B, C>::f(); // expected-error {{'f' is a private member of 'X<A, B, C>'}}
Y::g(); // expected-error {{'g' is a private member of 'Y'}}
};
};

void f1() {
A a;
B b;
C c;
D d;
}

template <typename ...Pack>
struct Z {
template <template <typename> class Template>
struct Inner {
friend Template<Pack>...;
};
};

void f2() {
Z<int, long, char> z;
Z<int, long, char>::Inner<TS> inner;
}

namespace p2893r3_examples {
template<class... Ts>
class Passkey {
friend Ts...;
Passkey() {} // expected-note {{declared private here}}
};

class Foo;
class Bar;
class Baz;

class C {
public:
void f(Passkey<Foo, Bar, Baz>);
};

class Foo {
Foo() { C c; c.f({}); }
};

class Bar {
Bar() { C c; c.f({}); }
};

class Baz {
Baz() { C c; c.f({}); }
};

class Quux {
Quux() { C c; c.f({}); } // expected-error {{calling a private constructor of class 'p2893r3_examples::Passkey<p2893r3_examples::Foo, p2893r3_examples::Bar, p2893r3_examples::Baz>'}}
};

template<class Derived, class MsgT>
struct Receiver {
void receive(MsgT) {
static_cast<Derived*>(this)->private_ += 1;
}
};

template<class... MsgTs>
struct Dispatcher : Receiver<Dispatcher<MsgTs...>, MsgTs>... {
using Receiver<Dispatcher, MsgTs>::receive...;
friend Receiver<Dispatcher, MsgTs>...;

private:
int private_;
};

void f() {
Dispatcher<int, float> d;
d.receive(0);
d.receive(0.0f);
}
} // namespace p2893r3_examples

namespace p2893r3_note {
template <class... Ts> class R {
friend Ts...;
};

template <class... Ts, class... Us>
class R<R<Ts...>, R<Us...>> {
friend Ts::Nested..., Us...;
};

struct E { struct Nested; };
R<R<E>, R<C, int>> rr;
} // namespace p2893r3_note

namespace template_template {
template <typename U, template <typename> typename... Friend>
class S {
friend class Friend<U>...;
static constexpr int a = 42;
};

template <typename U>
struct T {
static_assert(S<U, T>::a == 42);
static_assert(S<U, T>::a == 43); // expected-error {{static assertion failed due to requirement 'S<int, template_template::T>::a == 43'}} \
// expected-note {{expression evaluates to '42 == 43'}}
};

void f() {
T<int> t; // expected-note {{in instantiation of}}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ namespace construct_wt_ptr_size {
unsigned Y = 10;
std::span<int> S = std::span{&X, 1}; // no-warning
int Arr[10];
typedef int TenInts_t[10];
TenInts_t Arr2;

S = std::span{&X, 2}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
S = std::span{new int[10], 10}; // no-warning
Expand All @@ -90,6 +92,7 @@ namespace construct_wt_ptr_size {
S = std::span{new int[10], 9}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
S = std::span{new int[10], Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
S = std::span{Arr, 10}; // no-warning
S = std::span{Arr2, 10}; // no-warning
S = std::span{Arr, Y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} // not smart enough to tell its safe
S = std::span{p, 0}; // no-warning
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaHLSL/BuiltIns/normalize-errors.hlsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected
// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -disable-llvm-passes -verify -verify-ignore-unexpected

void test_too_few_arg()
{
Expand Down
34 changes: 34 additions & 0 deletions clang/test/SemaHLSL/Types/typedefs.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.4-library -finclude-default-header -verify -fnative-half-type %s
// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -finclude-default-header -verify -fnative-half-type %s

// expected-no-diagnostics
#define SizeCheck(Ty, SizeInBits) \
_Static_assert(sizeof(Ty) == SizeInBits / 8, #Ty " is " #SizeInBits "-bit"); \
_Static_assert(sizeof(Ty##1) == (SizeInBits * 1) / 8, #Ty "1 is 1x" #SizeInBits "-bit"); \
_Static_assert(__builtin_vectorelements(Ty##1) == 1, #Ty "1 is has 1 " #SizeInBits "-bit element"); \
_Static_assert(sizeof(Ty##2) == (SizeInBits * 2) / 8, #Ty "2 is 2x" #SizeInBits "-bit"); \
_Static_assert(__builtin_vectorelements(Ty##2) == 2, #Ty "2 is has 2 " #SizeInBits "-bit element"); \
_Static_assert(__builtin_vectorelements(Ty##3) == 3, #Ty "3 is has 3 " #SizeInBits "-bit element"); \
_Static_assert(sizeof(Ty##4) == (SizeInBits * 4) / 8, #Ty "4 is 4x" #SizeInBits "-bit"); \
_Static_assert(__builtin_vectorelements(Ty##4) == 4, #Ty "4 is has 4 " #SizeInBits "-bit element");

// FIXME: https://github.com/llvm/llvm-project/issues/104503 - 3 element vectors
// should be the size of 3 elements not padded to 4.
// _Static_assert(sizeof(Ty##3) == (SizeInBits * 3) / 8, #Ty "3 is 3x" #SizeInBits "-bit");

SizeCheck(int16_t, 16);
SizeCheck(uint16_t, 16);
SizeCheck(half, 16);
SizeCheck(float16_t, 16);

SizeCheck(int, 32);
SizeCheck(uint, 32);
SizeCheck(int32_t, 32);
SizeCheck(uint32_t, 32);
SizeCheck(float, 32);
SizeCheck(float32_t, 32);

SizeCheck(int64_t, 64);
SizeCheck(uint64_t, 64);
SizeCheck(double, 64);
SizeCheck(float64_t, 64);
7 changes: 6 additions & 1 deletion clang/test/SemaTemplate/temp_explicit.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -std=c++20 %s
//
// Tests explicit instantiation of templates.
template<typename T, typename U = T> class X0 { };
Expand Down Expand Up @@ -128,11 +129,15 @@ struct Foo<int> // expected-note{{header not required for explicitly-specialized
{};
};

template <> // expected-warning{{extraneous template parameter list}}
template <> // expected-error{{extraneous template parameter list}}
template <>
struct Foo<int>::Bar<void>
{};

#if __cplusplus >= 202002L
template<> void f(auto); // expected-error{{extraneous template parameter list}}
#endif

namespace N1 {

template<typename T> struct X7 { }; // expected-note{{here}}
Expand Down
20 changes: 11 additions & 9 deletions clang/tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned GenDwarfForAssembly : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned RelaxELFRelocations : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned SSE2AVX : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned Dwarf64 : 1;
unsigned DwarfVersion;
std::string DwarfDebugFlags;
Expand Down Expand Up @@ -169,6 +165,11 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned Crel : 1;

LLVM_PREFERRED_TYPE(bool)
unsigned X86RelaxRelocations : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned X86Sse2Avx : 1;

/// The name of the relocation model to use.
std::string RelocationModel;

Expand Down Expand Up @@ -199,7 +200,6 @@ struct AssemblerInvocation {
ShowInst = 0;
ShowEncoding = 0;
RelaxAll = 0;
SSE2AVX = 0;
NoExecStack = 0;
FatalWarnings = 0;
NoWarn = 0;
Expand All @@ -211,6 +211,8 @@ struct AssemblerInvocation {
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
EmitCompactUnwindNonCanonical = false;
Crel = false;
X86RelaxRelocations = 0;
X86Sse2Avx = 0;
}

static bool CreateFromArgs(AssemblerInvocation &Res,
Expand Down Expand Up @@ -290,8 +292,6 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
.Default(llvm::DebugCompressionType::None);
}

Opts.RelaxELFRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
Opts.SSE2AVX = Args.hasArg(OPT_msse2avx);
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
Expand Down Expand Up @@ -382,6 +382,8 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.EmitCompactUnwindNonCanonical =
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
Opts.Crel = Args.hasArg(OPT_crel);
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);

Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);

Expand Down Expand Up @@ -440,8 +442,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
MCOptions.Crel = Opts.Crel;
MCOptions.X86RelaxRelocations = Opts.RelaxELFRelocations;
MCOptions.X86Sse2Avx = Opts.SSE2AVX;
MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;

Expand Down
12 changes: 12 additions & 0 deletions clang/tools/libclang/CXSourceLocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) {
loc1.int_data == loc2.int_data);
}

unsigned clang_isBeforeInTranslationUnit(CXSourceLocation loc1,
CXSourceLocation loc2) {
const SourceLocation Loc1 = SourceLocation::getFromRawEncoding(loc1.int_data);
const SourceLocation Loc2 = SourceLocation::getFromRawEncoding(loc2.int_data);

const SourceManager &SM =
*static_cast<const SourceManager *>(loc1.ptr_data[0]);
// Use the appropriate SourceManager method here rather than operator< because
// ordering is meaningful only if LHS and RHS have the same FileID.
return SM.isBeforeInTranslationUnit(Loc1, Loc2);
}

CXSourceRange clang_getNullRange() {
CXSourceRange Result = { { nullptr, nullptr }, 0, 0 };
return Result;
Expand Down
5 changes: 5 additions & 0 deletions clang/tools/libclang/libclang.map
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ LLVM_19 {
clang_Cursor_getBinaryOpcodeStr;
};

LLVM_20 {
global:
clang_isBeforeInTranslationUnit;
};

# Example of how to add a new symbol version entry. If you do add a new symbol
# version, please update the example to depend on the version you added.
# LLVM_X {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "../../../lib/AST/Interp/Descriptor.h"
#include "../../../lib/AST/Interp/Context.h"
#include "../../../lib/AST/Interp/Program.h"
#include "../../../lib/AST/ByteCode/Descriptor.h"
#include "../../../lib/AST/ByteCode/Context.h"
#include "../../../lib/AST/ByteCode/Program.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
Expand All @@ -15,17 +15,17 @@ using namespace clang::ast_matchers;
/// Inspect generated Descriptors as well as the pointers we create.
///
TEST(Descriptor, Primitives) {
constexpr char Code[] =
"struct A { bool a; bool b; };\n"
"struct S {\n"
" float f;\n"
" char s[4];\n"
" A a[3];\n"
" short l[3][3];\n"
" int EmptyA[0];\n"
"};\n"
"constexpr S d = {0.0, \"foo\", {{true, false}, {false, true}, {false, false}},\n"
" {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, {}};\n";
constexpr char Code[] = "struct A { bool a; bool b; };\n"
"struct S {\n"
" float f;\n"
" char s[4];\n"
" A a[3];\n"
" short l[3][3];\n"
" int EmptyA[0];\n"
"};\n"
"constexpr S d = {0.0, \"foo\", {{true, false}, "
"{false, true}, {false, false}},\n"
" {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}, {}};\n";

auto AST = tooling::buildASTFromCodeWithArgs(
Code, {"-fexperimental-new-constant-interpreter"});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "../../../lib/AST/Interp/Context.h"
#include "../../../lib/AST/Interp/Descriptor.h"
#include "../../../lib/AST/Interp/Program.h"
#include "../../../lib/AST/ByteCode/Context.h"
#include "../../../lib/AST/ByteCode/Descriptor.h"
#include "../../../lib/AST/ByteCode/Program.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
Expand Down
2 changes: 1 addition & 1 deletion clang/unittests/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set(LLVM_LINK_COMPONENTS
)


add_subdirectory(Interp)
add_subdirectory(ByteCode)

add_clang_unittest(ASTTests
ASTContextParentMapTest.cpp
Expand Down
Loading