Skip to content

Commit 255b0e1

Browse files
authored
[AutoBump] Merge with 983562d (Jan 29) (6) (#874)
2 parents f8117b9 + 97e1bc9 commit 255b0e1

File tree

119 files changed

+2431
-1242
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+2431
-1242
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,9 @@ The integer elementwise intrinsics, including ``__builtin_elementwise_popcount``
757757
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
758758
``__builtin_elementwise_sub_sat`` can be called in a ``constexpr`` context.
759759

760+
No implicit promotion of integer types takes place. The mixing of integer types
761+
of different sizes and signs is forbidden in binary and ternary builtins.
762+
760763
============================================== ====================================================================== =========================================
761764
Name Operation Supported element types
762765
============================================== ====================================================================== =========================================

clang/include/clang/Sema/Sema.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2331,7 +2331,8 @@ class Sema final : public SemaBase {
23312331
const FunctionProtoType *Proto);
23322332

23332333
/// \param FPOnly restricts the arguments to floating-point types.
2334-
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly = false);
2334+
std::optional<QualType> BuiltinVectorMath(CallExpr *TheCall,
2335+
bool FPOnly = false);
23352336
bool BuiltinVectorToScalarMath(CallExpr *TheCall);
23362337

23372338
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction,
@@ -7499,10 +7500,15 @@ class Sema final : public SemaBase {
74997500
return K == ConditionKind::Switch ? Context.IntTy : Context.BoolTy;
75007501
}
75017502

7502-
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
7503-
// functions and arrays to their respective pointers (C99 6.3.2.1).
7503+
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2), converts
7504+
// functions and arrays to their respective pointers (C99 6.3.2.1), and
7505+
// promotes floating-piont types according to the language semantics.
75047506
ExprResult UsualUnaryConversions(Expr *E);
75057507

7508+
// UsualUnaryFPConversions - promotes floating-point types according to the
7509+
// current language semantics.
7510+
ExprResult UsualUnaryFPConversions(Expr *E);
7511+
75067512
/// CallExprUnaryConversions - a special case of an unary conversion
75077513
/// performed on a function designator of a call expression.
75087514
ExprResult CallExprUnaryConversions(Expr *E);
@@ -7565,6 +7571,11 @@ class Sema final : public SemaBase {
75657571
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
75667572
FunctionDecl *FDecl);
75677573

7574+
// Check that the usual arithmetic conversions can be performed on this pair
7575+
// of expressions that might be of enumeration type.
7576+
void checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, SourceLocation Loc,
7577+
Sema::ArithConvKind ACK);
7578+
75687579
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
75697580
// operands and then handles various conversions that are common to binary
75707581
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6175,7 +6175,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
61756175
}
61766176

61776177
if (D->getType()->isReferenceType())
6178-
return false; // FIXME: Do we need to emit InvalidDeclRef?
6178+
return this->emitDummyPtr(D, E);
61796179
}
61806180

61816181
// In case we need to re-visit a declaration.

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ QualType Descriptor::getElemQualType() const {
409409
assert(isArray());
410410
QualType T = getType();
411411
if (T->isPointerOrReferenceType())
412-
return T->getPointeeType();
412+
T = T->getPointeeType();
413+
413414
if (const auto *AT = T->getAsArrayTypeUnsafe()) {
414415
// For primitive arrays, we don't save a QualType at all,
415416
// just a PrimType. Try to figure out the QualType here.
@@ -424,7 +425,8 @@ QualType Descriptor::getElemQualType() const {
424425
return CT->getElementType();
425426
if (const auto *CT = T->getAs<VectorType>())
426427
return CT->getElementType();
427-
llvm_unreachable("Array that's not an array/complex/vector type?");
428+
429+
return T;
428430
}
429431

430432
SourceLocation Descriptor::getLocation() const {

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC,
6868
const SourceInfo &E = S.Current->getSource(OpPC);
6969

7070
if (isa<ParmVarDecl>(D)) {
71+
if (D->getType()->isReferenceType())
72+
return false;
73+
7174
if (S.getLangOpts().CPlusPlus11) {
7275
S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
7376
S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
@@ -1287,6 +1290,12 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
12871290

12881291
const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);
12891292

1293+
// C++23 [expr.const]p5.6
1294+
// an invocation of a virtual function ([class.virtual]) for an object whose
1295+
// dynamic type is constexpr-unknown;
1296+
if (ThisPtr.isDummy() && Func->isVirtual())
1297+
return false;
1298+
12901299
// If the current function is a lambda static invoker and
12911300
// the function we're about to call is a lambda call operator,
12921301
// skip the CheckInvoke, since the ThisPtr is a null pointer
@@ -1661,17 +1670,6 @@ bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) {
16611670
if (!P.isBlockPointer())
16621671
return false;
16631672

1664-
if (P.isDummy()) {
1665-
QualType StarThisType =
1666-
S.getASTContext().getLValueReferenceType(P.getType());
1667-
S.FFDiag(S.Current->getSource(OpPC),
1668-
diag::note_constexpr_polymorphic_unknown_dynamic_type)
1669-
<< AK_TypeId
1670-
<< P.toAPValue(S.getASTContext())
1671-
.getAsString(S.getASTContext(), StarThisType);
1672-
return false;
1673-
}
1674-
16751673
S.Stk.push<Pointer>(P.getType().getTypePtr(), TypeInfoType);
16761674
return true;
16771675
}

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,9 +1538,12 @@ static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC,
15381538
if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
15391539
ArgType->isAnyComplexType() || ArgType->isPointerType() ||
15401540
ArgType->isNullPtrType()) {
1541+
auto PrevDiags = S.getEvalStatus().Diag;
1542+
S.getEvalStatus().Diag = nullptr;
15411543
InterpStack Stk;
15421544
Compiler<EvalEmitter> C(S.Ctx, S.P, S, Stk);
15431545
auto Res = C.interpretExpr(Arg, /*ConvertResultToRValue=*/Arg->isGLValue());
1546+
S.getEvalStatus().Diag = PrevDiags;
15441547
if (Res.isInvalid()) {
15451548
C.cleanup();
15461549
Stk.clear();

clang/lib/AST/ByteCode/Pointer.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
209209
return ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FieldIndex));
210210
};
211211

212+
bool UsePath = true;
213+
if (getType()->isLValueReferenceType())
214+
UsePath = false;
215+
212216
// Build the path into the object.
213217
Pointer Ptr = *this;
214218
while (Ptr.isField() || Ptr.isArrayElement()) {
@@ -217,38 +221,42 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
217221
// An array root may still be an array element itself.
218222
if (Ptr.isArrayElement()) {
219223
Ptr = Ptr.expand();
224+
const Descriptor *Desc = Ptr.getFieldDesc();
220225
unsigned Index = Ptr.getIndex();
221-
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
222-
QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
226+
QualType ElemType = Desc->getElemQualType();
223227
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
228+
if (Ptr.getArray().getType()->isArrayType())
229+
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
224230
Ptr = Ptr.getArray();
225231
} else {
226-
Path.push_back(APValue::LValuePathEntry(
227-
{Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false}));
232+
const Descriptor *Desc = Ptr.getFieldDesc();
233+
const auto *Dcl = Desc->asDecl();
234+
Path.push_back(APValue::LValuePathEntry({Dcl, /*IsVirtual=*/false}));
228235

229-
if (const auto *FD =
230-
dyn_cast_if_present<FieldDecl>(Ptr.getFieldDesc()->asDecl()))
236+
if (const auto *FD = dyn_cast_if_present<FieldDecl>(Dcl))
231237
Offset += getFieldOffset(FD);
232238

233239
Ptr = Ptr.getBase();
234240
}
235241
} else if (Ptr.isArrayElement()) {
236242
Ptr = Ptr.expand();
243+
const Descriptor *Desc = Ptr.getFieldDesc();
237244
unsigned Index;
238245
if (Ptr.isOnePastEnd())
239246
Index = Ptr.getArray().getNumElems();
240247
else
241248
Index = Ptr.getIndex();
242249

243-
QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
250+
QualType ElemType = Desc->getElemQualType();
244251
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
245-
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
252+
if (Ptr.getArray().getType()->isArrayType())
253+
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
246254
Ptr = Ptr.getArray();
247255
} else {
256+
const Descriptor *Desc = Ptr.getFieldDesc();
248257
bool IsVirtual = false;
249258

250259
// Create a path entry for the field.
251-
const Descriptor *Desc = Ptr.getFieldDesc();
252260
if (const auto *BaseOrMember = Desc->asDecl()) {
253261
if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
254262
Ptr = Ptr.getBase();
@@ -281,8 +289,11 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
281289
// Just invert the order of the elements.
282290
std::reverse(Path.begin(), Path.end());
283291

284-
return APValue(Base, Offset, Path, /*IsOnePastEnd=*/isOnePastEnd(),
285-
/*IsNullPtr=*/false);
292+
if (UsePath)
293+
return APValue(Base, Offset, Path,
294+
/*IsOnePastEnd=*/!isElementPastEnd() && isOnePastEnd());
295+
296+
return APValue(Base, Offset, APValue::NoLValuePath());
286297
}
287298

288299
void Pointer::print(llvm::raw_ostream &OS) const {

clang/lib/AST/ByteCode/Pointer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,7 @@ class Pointer {
630630
if (isUnknownSizeArray())
631631
return false;
632632

633-
return isElementPastEnd() || isPastEnd() ||
634-
(getSize() == getOffset() && !isZeroSizeArray());
633+
return isPastEnd() || (getSize() == getOffset() && !isZeroSizeArray());
635634
}
636635

637636
/// Checks if the pointer points past the end of the object.

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,8 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
608608
HasBTI = 1;
609609
} else if (Feature == "+fullbf16") {
610610
HasFullBFloat16 = true;
611+
} else if (Feature == "+execute-only") {
612+
TLSSupported = false;
611613
}
612614
}
613615

clang/lib/Sema/SemaChecking.cpp

Lines changed: 73 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -14649,11 +14649,23 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
1464914649
_2, _3, _4));
1465014650
}
1465114651

14652+
// Performs a similar job to Sema::UsualUnaryConversions, but without any
14653+
// implicit promotion of integral/enumeration types.
14654+
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) {
14655+
// First, convert to an r-value.
14656+
ExprResult Res = S.DefaultFunctionArrayLvalueConversion(E);
14657+
if (Res.isInvalid())
14658+
return ExprError();
14659+
14660+
// Promote floating-point types.
14661+
return S.UsualUnaryFPConversions(Res.get());
14662+
}
14663+
1465214664
bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1465314665
if (checkArgCount(TheCall, 1))
1465414666
return true;
1465514667

14656-
ExprResult A = UsualUnaryConversions(TheCall->getArg(0));
14668+
ExprResult A = BuiltinVectorMathConversions(*this, TheCall->getArg(0));
1465714669
if (A.isInvalid())
1465814670
return true;
1465914671

@@ -14668,67 +14680,95 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
1466814680
}
1466914681

1467014682
bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
14671-
QualType Res;
14672-
if (BuiltinVectorMath(TheCall, Res, FPOnly))
14673-
return true;
14674-
TheCall->setType(Res);
14675-
return false;
14683+
if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
14684+
TheCall->setType(*Res);
14685+
return false;
14686+
}
14687+
return true;
1467614688
}
1467714689

1467814690
bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
14679-
QualType Res;
14680-
if (BuiltinVectorMath(TheCall, Res))
14691+
std::optional<QualType> Res = BuiltinVectorMath(TheCall);
14692+
if (!Res)
1468114693
return true;
1468214694

14683-
if (auto *VecTy0 = Res->getAs<VectorType>())
14695+
if (auto *VecTy0 = (*Res)->getAs<VectorType>())
1468414696
TheCall->setType(VecTy0->getElementType());
1468514697
else
14686-
TheCall->setType(Res);
14698+
TheCall->setType(*Res);
1468714699

1468814700
return false;
1468914701
}
1469014702

14691-
bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
14703+
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,
14704+
SourceLocation Loc) {
14705+
QualType L = LHS->getEnumCoercedType(S.Context),
14706+
R = RHS->getEnumCoercedType(S.Context);
14707+
if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() &&
14708+
!S.Context.hasSameUnqualifiedType(L, R)) {
14709+
return S.Diag(Loc, diag::err_conv_mixed_enum_types_cxx26)
14710+
<< LHS->getSourceRange() << RHS->getSourceRange()
14711+
<< /*Arithmetic Between*/ 0 << L << R;
14712+
}
14713+
return false;
14714+
}
14715+
14716+
std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
14717+
bool FPOnly) {
1469214718
if (checkArgCount(TheCall, 2))
14693-
return true;
14719+
return std::nullopt;
1469414720

14695-
ExprResult A = TheCall->getArg(0);
14696-
ExprResult B = TheCall->getArg(1);
14697-
// Do standard promotions between the two arguments, returning their common
14698-
// type.
14699-
Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison);
14700-
if (A.isInvalid() || B.isInvalid())
14701-
return true;
14721+
if (checkBuiltinVectorMathMixedEnums(
14722+
*this, TheCall->getArg(0), TheCall->getArg(1), TheCall->getExprLoc()))
14723+
return std::nullopt;
1470214724

14703-
QualType TyA = A.get()->getType();
14704-
QualType TyB = B.get()->getType();
14725+
Expr *Args[2];
14726+
for (int I = 0; I < 2; ++I) {
14727+
ExprResult Converted =
14728+
BuiltinVectorMathConversions(*this, TheCall->getArg(I));
14729+
if (Converted.isInvalid())
14730+
return std::nullopt;
14731+
Args[I] = Converted.get();
14732+
}
1470514733

14706-
if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType())
14707-
return Diag(A.get()->getBeginLoc(),
14708-
diag::err_typecheck_call_different_arg_types)
14709-
<< TyA << TyB;
14734+
SourceLocation LocA = Args[0]->getBeginLoc();
14735+
QualType TyA = Args[0]->getType();
14736+
QualType TyB = Args[1]->getType();
14737+
14738+
if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
14739+
Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
14740+
return std::nullopt;
14741+
}
1471014742

1471114743
if (FPOnly) {
14712-
if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
14713-
return true;
14744+
if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1))
14745+
return std::nullopt;
1471414746
} else {
14715-
if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
14716-
return true;
14747+
if (checkMathBuiltinElementType(*this, LocA, TyA, 1))
14748+
return std::nullopt;
1471714749
}
1471814750

14719-
TheCall->setArg(0, A.get());
14720-
TheCall->setArg(1, B.get());
14721-
return false;
14751+
TheCall->setArg(0, Args[0]);
14752+
TheCall->setArg(1, Args[1]);
14753+
return TyA;
1472214754
}
1472314755

1472414756
bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
1472514757
bool CheckForFloatArgs) {
1472614758
if (checkArgCount(TheCall, 3))
1472714759
return true;
1472814760

14761+
SourceLocation Loc = TheCall->getExprLoc();
14762+
if (checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(0),
14763+
TheCall->getArg(1), Loc) ||
14764+
checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(1),
14765+
TheCall->getArg(2), Loc))
14766+
return true;
14767+
1472914768
Expr *Args[3];
1473014769
for (int I = 0; I < 3; ++I) {
14731-
ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
14770+
ExprResult Converted =
14771+
BuiltinVectorMathConversions(*this, TheCall->getArg(I));
1473214772
if (Converted.isInvalid())
1473314773
return true;
1473414774
Args[I] = Converted.get();

0 commit comments

Comments
 (0)