forked from OSchip/llvm-project
Revert "[clang] use getCommonSugar in an assortment of places"
This reverts commit aff1f6310e
.
This commit is contained in:
parent
aff1f6310e
commit
1d1a98e9a0
|
@ -330,7 +330,7 @@ TEST_F(ExtractVariableTest, Test) {
|
|||
void bar() {
|
||||
int (*placeholder)(int) = foo('c'); (void)placeholder;
|
||||
})cpp"},
|
||||
// Arithmetic on typedef types preserves typedef types
|
||||
// Arithmetic on typedef types yields plain integer types
|
||||
{R"cpp(typedef long NSInteger;
|
||||
void varDecl() {
|
||||
NSInteger a = 2 * 5;
|
||||
|
@ -339,7 +339,7 @@ TEST_F(ExtractVariableTest, Test) {
|
|||
R"cpp(typedef long NSInteger;
|
||||
void varDecl() {
|
||||
NSInteger a = 2 * 5;
|
||||
NSInteger placeholder = a * 7; NSInteger b = placeholder + 3;
|
||||
long placeholder = a * 7; NSInteger b = placeholder + 3;
|
||||
})cpp"},
|
||||
};
|
||||
for (const auto &IO : InputOutputs) {
|
||||
|
|
|
@ -42,7 +42,7 @@ void narrowing_size_method() {
|
|||
// IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t.
|
||||
|
||||
i = j + v.size();
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t.
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ void narrowing_size_method_binary_expr() {
|
|||
int j;
|
||||
vector v;
|
||||
i = j + v.size();
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t.
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ void narrowing_size_method_binary_op() {
|
|||
// IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t.
|
||||
|
||||
i += j + v.size();
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'global_size_t' (aka 'long long') to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
|
||||
// IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t.
|
||||
}
|
||||
|
||||
|
|
|
@ -1088,7 +1088,7 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr,
|
|||
if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true;
|
||||
if (SkipCast) return false;
|
||||
if (IntTy->isIntegerType()) {
|
||||
QualType fpTy = ComplexTy->castAs<ComplexType>()->getElementType();
|
||||
QualType fpTy = cast<ComplexType>(ComplexTy)->getElementType();
|
||||
IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating);
|
||||
IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy,
|
||||
CK_FloatingRealToComplex);
|
||||
|
@ -1100,59 +1100,60 @@ static bool handleIntegerToComplexFloatConversion(Sema &S, ExprResult &IntExpr,
|
|||
return false;
|
||||
}
|
||||
|
||||
// This handles complex/complex, complex/float, or float/complex.
|
||||
// When both operands are complex, the shorter operand is converted to the
|
||||
// type of the longer, and that is the type of the result. This corresponds
|
||||
// to what is done when combining two real floating-point operands.
|
||||
// The fun begins when size promotion occur across type domains.
|
||||
// From H&S 6.3.4: When one operand is complex and the other is a real
|
||||
// floating-point type, the less precise type is converted, within it's
|
||||
// real or complex domain, to the precision of the other type. For example,
|
||||
// when combining a "long double" with a "double _Complex", the
|
||||
// "double _Complex" is promoted to "long double _Complex".
|
||||
static QualType handleComplexFloatConversion(Sema &S, ExprResult &Shorter,
|
||||
QualType ShorterType,
|
||||
QualType LongerType,
|
||||
bool PromotePrecision) {
|
||||
bool LongerIsComplex = isa<ComplexType>(LongerType.getCanonicalType());
|
||||
QualType Result =
|
||||
LongerIsComplex ? LongerType : S.Context.getComplexType(LongerType);
|
||||
|
||||
if (PromotePrecision) {
|
||||
if (isa<ComplexType>(ShorterType.getCanonicalType())) {
|
||||
Shorter =
|
||||
S.ImpCastExprToType(Shorter.get(), Result, CK_FloatingComplexCast);
|
||||
} else {
|
||||
if (LongerIsComplex)
|
||||
LongerType = LongerType->castAs<ComplexType>()->getElementType();
|
||||
Shorter = S.ImpCastExprToType(Shorter.get(), LongerType, CK_FloatingCast);
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// Handle arithmetic conversion with complex types. Helper function of
|
||||
/// UsualArithmeticConversions()
|
||||
static QualType handleComplexConversion(Sema &S, ExprResult &LHS,
|
||||
ExprResult &RHS, QualType LHSType,
|
||||
QualType RHSType, bool IsCompAssign) {
|
||||
static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS,
|
||||
ExprResult &RHS, QualType LHSType,
|
||||
QualType RHSType,
|
||||
bool IsCompAssign) {
|
||||
// if we have an integer operand, the result is the complex type.
|
||||
if (!handleIntegerToComplexFloatConversion(S, RHS, LHS, RHSType, LHSType,
|
||||
/*SkipCast=*/false))
|
||||
/*skipCast*/false))
|
||||
return LHSType;
|
||||
if (!handleIntegerToComplexFloatConversion(S, LHS, RHS, LHSType, RHSType,
|
||||
/*SkipCast=*/IsCompAssign))
|
||||
/*skipCast*/IsCompAssign))
|
||||
return RHSType;
|
||||
|
||||
// This handles complex/complex, complex/float, or float/complex.
|
||||
// When both operands are complex, the shorter operand is converted to the
|
||||
// type of the longer, and that is the type of the result. This corresponds
|
||||
// to what is done when combining two real floating-point operands.
|
||||
// The fun begins when size promotion occur across type domains.
|
||||
// From H&S 6.3.4: When one operand is complex and the other is a real
|
||||
// floating-point type, the less precise type is converted, within it's
|
||||
// real or complex domain, to the precision of the other type. For example,
|
||||
// when combining a "long double" with a "double _Complex", the
|
||||
// "double _Complex" is promoted to "long double _Complex".
|
||||
|
||||
// Compute the rank of the two types, regardless of whether they are complex.
|
||||
int Order = S.Context.getFloatingTypeOrder(LHSType, RHSType);
|
||||
if (Order < 0)
|
||||
|
||||
auto *LHSComplexType = dyn_cast<ComplexType>(LHSType);
|
||||
auto *RHSComplexType = dyn_cast<ComplexType>(RHSType);
|
||||
QualType LHSElementType =
|
||||
LHSComplexType ? LHSComplexType->getElementType() : LHSType;
|
||||
QualType RHSElementType =
|
||||
RHSComplexType ? RHSComplexType->getElementType() : RHSType;
|
||||
|
||||
QualType ResultType = S.Context.getComplexType(LHSElementType);
|
||||
if (Order < 0) {
|
||||
// Promote the precision of the LHS if not an assignment.
|
||||
return handleComplexFloatConversion(S, LHS, LHSType, RHSType,
|
||||
/*PromotePrecision=*/!IsCompAssign);
|
||||
// Promote the precision of the RHS unless it is already the same as the LHS.
|
||||
return handleComplexFloatConversion(S, RHS, RHSType, LHSType,
|
||||
/*PromotePrecision=*/Order > 0);
|
||||
ResultType = S.Context.getComplexType(RHSElementType);
|
||||
if (!IsCompAssign) {
|
||||
if (LHSComplexType)
|
||||
LHS =
|
||||
S.ImpCastExprToType(LHS.get(), ResultType, CK_FloatingComplexCast);
|
||||
else
|
||||
LHS = S.ImpCastExprToType(LHS.get(), RHSElementType, CK_FloatingCast);
|
||||
}
|
||||
} else if (Order > 0) {
|
||||
// Promote the precision of the RHS.
|
||||
if (RHSComplexType)
|
||||
RHS = S.ImpCastExprToType(RHS.get(), ResultType, CK_FloatingComplexCast);
|
||||
else
|
||||
RHS = S.ImpCastExprToType(RHS.get(), LHSElementType, CK_FloatingCast);
|
||||
}
|
||||
return ResultType;
|
||||
}
|
||||
|
||||
/// Handle arithmetic conversion from integer to float. Helper function
|
||||
|
@ -1538,16 +1539,18 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
|
|||
|
||||
// For conversion purposes, we ignore any qualifiers.
|
||||
// For example, "const float" and "float" are equivalent.
|
||||
QualType LHSType = LHS.get()->getType().getUnqualifiedType();
|
||||
QualType RHSType = RHS.get()->getType().getUnqualifiedType();
|
||||
QualType LHSType =
|
||||
Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType();
|
||||
QualType RHSType =
|
||||
Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType();
|
||||
|
||||
// For conversion purposes, we ignore any atomic qualifier on the LHS.
|
||||
if (const AtomicType *AtomicLHS = LHSType->getAs<AtomicType>())
|
||||
LHSType = AtomicLHS->getValueType();
|
||||
|
||||
// If both types are identical, no conversion is needed.
|
||||
if (Context.hasSameType(LHSType, RHSType))
|
||||
return Context.getCommonSugaredType(LHSType, RHSType);
|
||||
if (LHSType == RHSType)
|
||||
return LHSType;
|
||||
|
||||
// If either side is a non-arithmetic type (e.g. a pointer), we are done.
|
||||
// The caller can deal with this (e.g. pointer + int).
|
||||
|
@ -1565,8 +1568,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
|
|||
LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast);
|
||||
|
||||
// If both types are identical, no conversion is needed.
|
||||
if (Context.hasSameType(LHSType, RHSType))
|
||||
return Context.getCommonSugaredType(LHSType, RHSType);
|
||||
if (LHSType == RHSType)
|
||||
return LHSType;
|
||||
|
||||
// At this point, we have two different arithmetic types.
|
||||
|
||||
|
@ -1577,8 +1580,8 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
|
|||
|
||||
// Handle complex types first (C99 6.3.1.8p1).
|
||||
if (LHSType->isComplexType() || RHSType->isComplexType())
|
||||
return handleComplexConversion(*this, LHS, RHS, LHSType, RHSType,
|
||||
ACK == ACK_CompAssign);
|
||||
return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType,
|
||||
ACK == ACK_CompAssign);
|
||||
|
||||
// Now handle "real" floating types (i.e. float, double, long double).
|
||||
if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType())
|
||||
|
@ -8155,6 +8158,23 @@ static bool checkCondition(Sema &S, Expr *Cond, SourceLocation QuestionLoc) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// Handle when one or both operands are void type.
|
||||
static QualType checkConditionalVoidType(Sema &S, ExprResult &LHS,
|
||||
ExprResult &RHS) {
|
||||
Expr *LHSExpr = LHS.get();
|
||||
Expr *RHSExpr = RHS.get();
|
||||
|
||||
if (!LHSExpr->getType()->isVoidType())
|
||||
S.Diag(RHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
|
||||
<< RHSExpr->getSourceRange();
|
||||
if (!RHSExpr->getType()->isVoidType())
|
||||
S.Diag(LHSExpr->getBeginLoc(), diag::ext_typecheck_cond_one_void)
|
||||
<< LHSExpr->getSourceRange();
|
||||
LHS = S.ImpCastExprToType(LHS.get(), S.Context.VoidTy, CK_ToVoid);
|
||||
RHS = S.ImpCastExprToType(RHS.get(), S.Context.VoidTy, CK_ToVoid);
|
||||
return S.Context.VoidTy;
|
||||
}
|
||||
|
||||
/// Return false if the NullExpr can be promoted to PointerTy,
|
||||
/// true otherwise.
|
||||
static bool checkConditionalNullPointer(Sema &S, ExprResult &NullExpr,
|
||||
|
@ -8178,7 +8198,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
|
|||
|
||||
if (S.Context.hasSameType(LHSTy, RHSTy)) {
|
||||
// Two identical pointers types are always compatible.
|
||||
return S.Context.getCommonSugaredType(LHSTy, RHSTy);
|
||||
return LHSTy;
|
||||
}
|
||||
|
||||
QualType lhptee, rhptee;
|
||||
|
@ -8680,7 +8700,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
|
||||
// And if they're both bfloat (which isn't arithmetic), that's fine too.
|
||||
if (LHSTy->isBFloat16Type() && RHSTy->isBFloat16Type()) {
|
||||
return Context.getCommonSugaredType(LHSTy, RHSTy);
|
||||
return LHSTy;
|
||||
}
|
||||
|
||||
// If both operands are the same structure or union type, the result is that
|
||||
|
@ -8690,29 +8710,14 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
if (LHSRT->getDecl() == RHSRT->getDecl())
|
||||
// "If both the operands have structure or union type, the result has
|
||||
// that type." This implies that CV qualifiers are dropped.
|
||||
return Context.getCommonSugaredType(LHSTy.getUnqualifiedType(),
|
||||
RHSTy.getUnqualifiedType());
|
||||
return LHSTy.getUnqualifiedType();
|
||||
// FIXME: Type of conditional expression must be complete in C mode.
|
||||
}
|
||||
|
||||
// C99 6.5.15p5: "If both operands have void type, the result has void type."
|
||||
// The following || allows only one side to be void (a GCC-ism).
|
||||
if (LHSTy->isVoidType() || RHSTy->isVoidType()) {
|
||||
QualType ResTy;
|
||||
if (LHSTy->isVoidType() && RHSTy->isVoidType()) {
|
||||
ResTy = Context.getCommonSugaredType(LHSTy, RHSTy);
|
||||
} else if (RHSTy->isVoidType()) {
|
||||
ResTy = RHSTy;
|
||||
Diag(RHS.get()->getBeginLoc(), diag::ext_typecheck_cond_one_void)
|
||||
<< RHS.get()->getSourceRange();
|
||||
} else {
|
||||
ResTy = LHSTy;
|
||||
Diag(LHS.get()->getBeginLoc(), diag::ext_typecheck_cond_one_void)
|
||||
<< LHS.get()->getSourceRange();
|
||||
}
|
||||
LHS = ImpCastExprToType(LHS.get(), ResTy, CK_ToVoid);
|
||||
RHS = ImpCastExprToType(RHS.get(), ResTy, CK_ToVoid);
|
||||
return ResTy;
|
||||
return checkConditionalVoidType(*this, LHS, RHS);
|
||||
}
|
||||
|
||||
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
|
||||
|
@ -8751,7 +8756,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
// Allow ?: operations in which both operands have the same
|
||||
// built-in sizeless type.
|
||||
if (LHSTy->isSizelessBuiltinType() && Context.hasSameType(LHSTy, RHSTy))
|
||||
return Context.getCommonSugaredType(LHSTy, RHSTy);
|
||||
return LHSTy;
|
||||
|
||||
// Emit a better diagnostic if one of the expressions is a null pointer
|
||||
// constant and the other is not a pointer type. In this case, the user most
|
||||
|
@ -10422,7 +10427,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
|
|||
|
||||
// If the vector types are identical, return.
|
||||
if (Context.hasSameType(LHSType, RHSType))
|
||||
return Context.getCommonSugaredType(LHSType, RHSType);
|
||||
return LHSType;
|
||||
|
||||
// If we have compatible AltiVec and GCC vector types, use the AltiVec type.
|
||||
if (LHSVecType && RHSVecType &&
|
||||
|
@ -13140,7 +13145,7 @@ QualType Sema::CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
|
|||
assert((LHSMatType || RHSMatType) && "At least one operand must be a matrix");
|
||||
|
||||
if (Context.hasSameType(LHSType, RHSType))
|
||||
return Context.getCommonSugaredType(LHSType, RHSType);
|
||||
return LHSType;
|
||||
|
||||
// Type conversion may change LHS/RHS. Keep copies to the original results, in
|
||||
// case we have to return InvalidOperands.
|
||||
|
@ -13184,19 +13189,13 @@ QualType Sema::CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
|
|||
if (LHSMatType->getNumColumns() != RHSMatType->getNumRows())
|
||||
return InvalidOperands(Loc, LHS, RHS);
|
||||
|
||||
if (Context.hasSameType(LHSMatType, RHSMatType))
|
||||
return Context.getCommonSugaredType(
|
||||
LHS.get()->getType().getUnqualifiedType(),
|
||||
RHS.get()->getType().getUnqualifiedType());
|
||||
|
||||
QualType LHSELTy = LHSMatType->getElementType(),
|
||||
RHSELTy = RHSMatType->getElementType();
|
||||
if (!Context.hasSameType(LHSELTy, RHSELTy))
|
||||
if (!Context.hasSameType(LHSMatType->getElementType(),
|
||||
RHSMatType->getElementType()))
|
||||
return InvalidOperands(Loc, LHS, RHS);
|
||||
|
||||
return Context.getConstantMatrixType(
|
||||
Context.getCommonSugaredType(LHSELTy, RHSELTy),
|
||||
LHSMatType->getNumRows(), RHSMatType->getNumColumns());
|
||||
return Context.getConstantMatrixType(LHSMatType->getElementType(),
|
||||
LHSMatType->getNumRows(),
|
||||
RHSMatType->getNumColumns());
|
||||
}
|
||||
return CheckMatrixElementwiseOperands(LHS, RHS, Loc, IsCompAssign);
|
||||
}
|
||||
|
|
|
@ -6216,7 +6216,7 @@ QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
|
|||
<< LHSType << RHSType;
|
||||
return {};
|
||||
}
|
||||
ResultType = Context.getCommonSugaredType(LHSType, RHSType);
|
||||
ResultType = LHSType;
|
||||
} else if (LHSVT || RHSVT) {
|
||||
ResultType = CheckVectorOperands(
|
||||
LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true,
|
||||
|
@ -6227,13 +6227,15 @@ QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
|
|||
return {};
|
||||
} else {
|
||||
// Both are scalar.
|
||||
LHSType = LHSType.getUnqualifiedType();
|
||||
RHSType = RHSType.getUnqualifiedType();
|
||||
QualType ResultElementTy =
|
||||
Context.hasSameType(LHSType, RHSType)
|
||||
? Context.getCommonSugaredType(LHSType, RHSType)
|
||||
: UsualArithmeticConversions(LHS, RHS, QuestionLoc,
|
||||
ACK_Conditional);
|
||||
QualType ResultElementTy;
|
||||
LHSType = LHSType.getCanonicalType().getUnqualifiedType();
|
||||
RHSType = RHSType.getCanonicalType().getUnqualifiedType();
|
||||
|
||||
if (Context.hasSameType(LHSType, RHSType))
|
||||
ResultElementTy = LHSType;
|
||||
else
|
||||
ResultElementTy =
|
||||
UsualArithmeticConversions(LHS, RHS, QuestionLoc, ACK_Conditional);
|
||||
|
||||
if (ResultElementTy->isEnumeralType()) {
|
||||
Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
|
||||
|
@ -6453,7 +6455,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
// -- Both the second and third operands have type void; the result is of
|
||||
// type void and is a prvalue.
|
||||
if (LVoid && RVoid)
|
||||
return Context.getCommonSugaredType(LTy, RTy);
|
||||
return Context.VoidTy;
|
||||
|
||||
// Neither holds, error.
|
||||
Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
|
||||
|
@ -6559,7 +6561,21 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
if (LHS.get()->getObjectKind() == OK_BitField ||
|
||||
RHS.get()->getObjectKind() == OK_BitField)
|
||||
OK = OK_BitField;
|
||||
return Context.getCommonSugaredType(LTy, RTy);
|
||||
|
||||
// If we have function pointer types, unify them anyway to unify their
|
||||
// exception specifications, if any.
|
||||
if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) {
|
||||
Qualifiers Qs = LTy.getQualifiers();
|
||||
LTy = FindCompositePointerType(QuestionLoc, LHS, RHS,
|
||||
/*ConvertArgs*/false);
|
||||
LTy = Context.getQualifiedType(LTy, Qs);
|
||||
|
||||
assert(!LTy.isNull() && "failed to find composite pointer type for "
|
||||
"canonically equivalent function ptr types");
|
||||
assert(Context.hasSameType(LTy, RTy) && "bad composite pointer type");
|
||||
}
|
||||
|
||||
return LTy;
|
||||
}
|
||||
|
||||
// C++11 [expr.cond]p5
|
||||
|
@ -6589,23 +6605,36 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
|||
// is a prvalue temporary of the result type, which is
|
||||
// copy-initialized from either the second operand or the third
|
||||
// operand depending on the value of the first operand.
|
||||
if (Context.hasSameType(LTy, RTy)) {
|
||||
if (Context.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) {
|
||||
if (LTy->isRecordType()) {
|
||||
// The operands have class type. Make a temporary copy.
|
||||
ExprResult LHSCopy = PerformCopyInitialization(
|
||||
InitializedEntity::InitializeTemporary(LTy), SourceLocation(), LHS);
|
||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
|
||||
|
||||
ExprResult LHSCopy = PerformCopyInitialization(Entity,
|
||||
SourceLocation(),
|
||||
LHS);
|
||||
if (LHSCopy.isInvalid())
|
||||
return QualType();
|
||||
|
||||
ExprResult RHSCopy = PerformCopyInitialization(
|
||||
InitializedEntity::InitializeTemporary(RTy), SourceLocation(), RHS);
|
||||
ExprResult RHSCopy = PerformCopyInitialization(Entity,
|
||||
SourceLocation(),
|
||||
RHS);
|
||||
if (RHSCopy.isInvalid())
|
||||
return QualType();
|
||||
|
||||
LHS = LHSCopy;
|
||||
RHS = RHSCopy;
|
||||
}
|
||||
return Context.getCommonSugaredType(LTy, RTy);
|
||||
|
||||
// If we have function pointer types, unify them anyway to unify their
|
||||
// exception specifications, if any.
|
||||
if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) {
|
||||
LTy = FindCompositePointerType(QuestionLoc, LHS, RHS);
|
||||
assert(!LTy.isNull() && "failed to find composite pointer type for "
|
||||
"canonically equivalent function ptr types");
|
||||
}
|
||||
|
||||
return LTy;
|
||||
}
|
||||
|
||||
// Extension: conditional operator involving vector types.
|
||||
|
@ -7019,7 +7048,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
|
|||
Steps[I].Quals.addConst();
|
||||
|
||||
// Rebuild the composite type.
|
||||
QualType Composite = Context.getCommonSugaredType(Composite1, Composite2);
|
||||
QualType Composite = Composite1;
|
||||
for (auto &S : llvm::reverse(Steps))
|
||||
Composite = S.rebuild(Context, Composite);
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ float func_15(float x, float y) {
|
|||
// CHECK: FunctionDecl {{.*}} func_14 'float (float, float)'
|
||||
// CHECK: CompoundStmt
|
||||
// CHECK-NEXT: ReturnStmt
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'float':'float' '+' ConstRoundingMode=towardzero
|
||||
// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=towardzero
|
||||
|
||||
float func_16(float x, float y) {
|
||||
#pragma STDC FENV_ROUND FE_TOWARDZERO
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [22 x i8] } { i16 0, i16 11, [22 x i8] c"'int32_t' (aka 'int')\00" }
|
||||
// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
|
||||
// CHECK: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]]
|
||||
// CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [32 x i8] } { i16 0, i16 10, [32 x i8] c"'uint32_t' (aka 'unsigned int')\00" }
|
||||
// CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [15 x i8] } { i16 0, i16 10, [15 x i8] c"'unsigned int'\00" }
|
||||
// CHECK: @[[LINE_200:.*]] = private unnamed_addr global {{.*}}, i32 200, i32 5 {{.*}} @[[UINT]]
|
||||
// CHECK: @[[LINE_300:.*]] = private unnamed_addr global {{.*}}, i32 300, i32 5 {{.*}} @[[INT]]
|
||||
|
||||
|
|
|
@ -11,9 +11,6 @@ int aa = 1 + 1.0iF;
|
|||
int bb = 0;
|
||||
bb += 1i;
|
||||
|
||||
typedef __complex__ float ComplexFloat;
|
||||
int cc = 1 + (ComplexFloat)(1.0iF);
|
||||
|
||||
result = arr*ii;
|
||||
result = ii*brr;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ void matrix_matrix_multiply(sx10x10_t a, sx5x10_t b, ix10x5_t c, ix10x10_t d, fl
|
|||
a *= b;
|
||||
// expected-error@-1 {{invalid operands to binary expression ('sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))') and 'sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))'))}}
|
||||
b = a * a;
|
||||
// expected-error@-1 {{assigning to 'sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}}
|
||||
// expected-error@-1 {{assigning to 'sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') from incompatible type 'float __attribute__((matrix_type(10, 10)))'}}
|
||||
|
||||
// Check element type mismatches.
|
||||
a = b * c;
|
||||
|
@ -64,10 +64,10 @@ void matrix_matrix_multiply(sx10x10_t a, sx5x10_t b, ix10x5_t c, ix10x10_t d, fl
|
|||
b *= c;
|
||||
// expected-error@-1 {{invalid operands to binary expression ('sx5x10_t' (aka 'float __attribute__((matrix_type(5, 10)))') and 'ix10x5_t' (aka 'int __attribute__((matrix_type(10, 5)))'))}}
|
||||
d = a * a;
|
||||
// expected-error@-1 {{assigning to 'ix10x10_t' (aka 'int __attribute__((matrix_type(10, 10)))') from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}}
|
||||
// expected-error@-1 {{assigning to 'ix10x10_t' (aka 'int __attribute__((matrix_type(10, 10)))') from incompatible type 'float __attribute__((matrix_type(10, 10)))'}}
|
||||
|
||||
p = a * a;
|
||||
// expected-error@-1 {{assigning to 'char *' from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}}
|
||||
// expected-error@-1 {{assigning to 'char *' from incompatible type 'float __attribute__((matrix_type(10, 10)))'}}
|
||||
}
|
||||
|
||||
void mat_scalar_multiply(sx10x10_t a, sx5x10_t b, float sf, char *p) {
|
||||
|
|
|
@ -167,7 +167,7 @@ void conditional_expr(int c) {
|
|||
|
||||
p = c ? nonnullP2 : nonnullP2;
|
||||
p = c ? nonnullP2 : nullableP2; // expected-warning{{implicit conversion from nullable pointer 'IntP _Nullable' (aka 'int *') to non-nullable pointer type 'int * _Nonnull'}}
|
||||
p = c ? nullableP2 : nonnullP2; // expected-warning{{implicit conversion from nullable pointer 'IntP _Nullable' (aka 'int *') to non-nullable pointer type 'int * _Nonnull'}}
|
||||
p = c ? nullableP2 : nonnullP2; // expected-warning{{implicit conversion from nullable pointer 'NullableIntP1' (aka 'int *') to non-nullable pointer type 'int * _Nonnull'}}
|
||||
p = c ? nullableP2 : nullableP2; // expected-warning{{implicit conversion from nullable pointer 'NullableIntP1' (aka 'int *') to non-nullable pointer type 'int * _Nonnull'}}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c99 -triple aarch64-arm-none-eabi -target-feature +bf16 -target-feature +sve
|
||||
|
||||
typedef struct N {} N;
|
||||
|
||||
typedef int B1;
|
||||
typedef B1 X1;
|
||||
typedef B1 Y1;
|
||||
|
||||
typedef void B2;
|
||||
typedef B2 X2;
|
||||
typedef B2 Y2;
|
||||
|
||||
typedef struct B3 {} B3;
|
||||
typedef B3 X3;
|
||||
typedef B3 Y3;
|
||||
|
||||
typedef struct B4 {} *B4;
|
||||
typedef B4 X4;
|
||||
typedef B4 Y4;
|
||||
|
||||
typedef __bf16 B5;
|
||||
typedef B5 X5;
|
||||
typedef B5 Y5;
|
||||
|
||||
typedef __SVInt8_t B6;
|
||||
typedef B6 X6;
|
||||
typedef B6 Y6;
|
||||
|
||||
N t1 = 0 ? (X1)0 : (Y1)0; // expected-error {{incompatible type 'B1'}}
|
||||
N t2 = 0 ? (X2)0 : 0; // expected-error {{incompatible type 'X2'}}
|
||||
N t3 = 0 ? 0 : (Y2)0; // expected-error {{incompatible type 'Y2'}}
|
||||
N t4 = 0 ? (X2)0 : (Y2)0; // expected-error {{incompatible type 'B2'}}
|
||||
N t5 = 0 ? (X3){} : (Y3){}; // expected-error {{incompatible type 'B3'}}
|
||||
N t6 = 0 ? (X4)0 : (Y4)0; // expected-error {{incompatible type 'B4'}}
|
||||
|
||||
X5 x5;
|
||||
Y5 y5;
|
||||
N t7 = 0 ? x5 : y5; // expected-error {{incompatible type 'B5'}}
|
||||
|
||||
void f8() {
|
||||
X6 x6;
|
||||
Y6 y6;
|
||||
N t8 = 0 ? x6 : y6; // expected-error {{incompatible type 'B6'}}
|
||||
}
|
|
@ -15,8 +15,4 @@ void func(float Real, _Complex float Complex) {
|
|||
|
||||
// Conversion to bool doesn't actually discard the imaginary part.
|
||||
take<bool>(Complex);
|
||||
|
||||
using B = _Complex double;
|
||||
B c;
|
||||
c *= double();
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ void test_subtract_template(unsigned *Ptr1, float *Ptr2) {
|
|||
template <typename EltTy0, unsigned R0, unsigned C0, typename EltTy1, unsigned R1, unsigned C1, typename EltTy2, unsigned R2, unsigned C2>
|
||||
typename MyMatrix<EltTy2, R2, C2>::matrix_t multiply(MyMatrix<EltTy0, R0, C0> &A, MyMatrix<EltTy1, R1, C1> &B) {
|
||||
char *v1 = A.value * B.value;
|
||||
// expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))')}}
|
||||
// expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}}
|
||||
// expected-error@-2 {{invalid operands to binary expression ('matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(3, 3)))'))}}
|
||||
// expected-error@-3 {{invalid operands to binary expression ('matrix_t' (aka 'float __attribute__((matrix_type(2, 2)))') and 'matrix_t' (aka 'unsigned int __attribute__((matrix_type(2, 2)))'))}}
|
||||
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++20 -fenable-matrix
|
||||
|
||||
enum class N {};
|
||||
|
||||
using B1 = int;
|
||||
using X1 = B1;
|
||||
using Y1 = B1;
|
||||
|
||||
using B2 = void;
|
||||
using X2 = B2;
|
||||
using Y2 = B2;
|
||||
|
||||
using A3 = char __attribute__((vector_size(4)));
|
||||
using B3 = A3;
|
||||
using X3 = B3;
|
||||
using Y3 = B3;
|
||||
|
||||
using A4 = float;
|
||||
using B4 = A4 __attribute__((matrix_type(4, 4)));
|
||||
using X4 = B4;
|
||||
using Y4 = B4;
|
||||
|
||||
using X5 = A4 __attribute__((matrix_type(3, 4)));
|
||||
using Y5 = A4 __attribute__((matrix_type(4, 3)));
|
||||
|
||||
N t1 = 0 ? X1() : Y1(); // expected-error {{rvalue of type 'B1'}}
|
||||
N t2 = 0 ? X2() : Y2(); // expected-error {{rvalue of type 'B2'}}
|
||||
|
||||
const X1 &xt3 = 0;
|
||||
const Y1 &yt3 = 0;
|
||||
N t3 = 0 ? xt3 : yt3; // expected-error {{lvalue of type 'const B1'}}
|
||||
|
||||
N t4 = X3() + Y3(); // expected-error {{rvalue of type 'B3'}}
|
||||
|
||||
N t5 = A3() ? X3() : Y3(); // expected-error {{rvalue of type 'B3'}}
|
||||
N t6 = A3() ? X1() : Y1(); // expected-error {{vector condition type 'A3' (vector of 4 'char' values) and result type '__attribute__((__vector_size__(4 * sizeof(B1)))) B1' (vector of 4 'B1' values) do not have elements of the same size}}
|
||||
|
||||
N t7 = X4() + Y4(); // expected-error {{rvalue of type 'B4'}}
|
||||
N t8 = X4() * Y4(); // expected-error {{rvalue of type 'B4'}}
|
||||
N t9 = X5() * Y5(); // expected-error {{rvalue of type 'A4 __attribute__((matrix_type(3, 3)))'}}
|
|
@ -157,7 +157,7 @@ auto t7(fp3 a, fp4 b) {
|
|||
return true ? a : b;
|
||||
if (false)
|
||||
return a;
|
||||
return N(); // expected-error {{but deduced as 'Virus (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
|
||||
return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -268,7 +268,7 @@ void testByValueObjectInFormat(Foo *obj) {
|
|||
|
||||
// <rdar://problem/13557053>
|
||||
void testTypeOf(NSInteger dW, NSInteger dH) {
|
||||
NSLog(@"dW %d dH %d",({ __typeof__(dW) __a = (dW); __a < 0 ? -__a : __a; }),({ __typeof__(dH) __a = (dH); __a < 0 ? -__a : __a; })); // expected-warning 2 {{values of type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
|
||||
NSLog(@"dW %d dH %d",({ __typeof__(dW) __a = (dW); __a < 0 ? -__a : __a; }),({ __typeof__(dH) __a = (dH); __a < 0 ? -__a : __a; })); // expected-warning 2 {{format specifies type 'int' but the argument has type 'long'}}
|
||||
}
|
||||
|
||||
void testUnicode(void) {
|
||||
|
|
|
@ -18,7 +18,7 @@ int main() {
|
|||
|
||||
#ifdef ADD_I64
|
||||
(void)(int64_t(8000000000000000000ll) + int64_t(2000000000000000000ll));
|
||||
// CHECK-ADD_I64: 8000000000000000000 + 2000000000000000000 cannot be represented in type '{{int64_t|long( long)?}}'
|
||||
// CHECK-ADD_I64: 8000000000000000000 + 2000000000000000000 cannot be represented in type '{{long( long)?}}'
|
||||
#endif
|
||||
|
||||
#ifdef ADD_I128
|
||||
|
@ -27,6 +27,6 @@ int main() {
|
|||
# else
|
||||
puts("__int128 not supported");
|
||||
# endif
|
||||
// CHECK-ADD_I128: {{0x40000000000000000000000000000000 \+ 0x40000000000000000000000000000000 cannot be represented in type '__int128_t'|__int128 not supported}}
|
||||
// CHECK-ADD_I128: {{0x40000000000000000000000000000000 \+ 0x40000000000000000000000000000000 cannot be represented in type '__int128'|__int128 not supported}}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ int main() {
|
|||
// ABORT: no-recover.cpp:[[@LINE-2]]:5: runtime error: unsigned integer overflow: 2271560481 + 3989547399 cannot be represented in type 'unsigned int'
|
||||
|
||||
(void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
|
||||
// RECOVER: 10000000000000000000 + 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}'
|
||||
// RECOVER: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}'
|
||||
// SILENT-RECOVER-NOT: runtime error
|
||||
// ABORT-NOT: runtime error
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ int main() {
|
|||
|
||||
#ifdef SUB_I32
|
||||
(void)(int32_t(-2) - int32_t(0x7fffffff));
|
||||
// CHECK-SUB_I32: sub-overflow.cpp:[[@LINE-1]]:22: runtime error: signed integer overflow: -2 - 2147483647 cannot be represented in type '{{int32_t|int}}'
|
||||
// CHECK-SUB_I32: sub-overflow.cpp:[[@LINE-1]]:22: runtime error: signed integer overflow: -2 - 2147483647 cannot be represented in type 'int'
|
||||
#endif
|
||||
|
||||
#ifdef SUB_I64
|
||||
(void)(int64_t(-8000000000000000000ll) - int64_t(2000000000000000000ll));
|
||||
// CHECK-SUB_I64: -8000000000000000000 - 2000000000000000000 cannot be represented in type '{{int64_t|long( long)?}}'
|
||||
// CHECK-SUB_I64: -8000000000000000000 - 2000000000000000000 cannot be represented in type '{{long( long)?}}'
|
||||
#endif
|
||||
|
||||
#ifdef SUB_I128
|
||||
|
@ -26,6 +26,6 @@ int main() {
|
|||
# else
|
||||
puts("__int128 not supported");
|
||||
# endif
|
||||
// CHECK-SUB_I128: {{0x80000000000000000000000000000000 - 1 cannot be represented in type '__int128_t'|__int128 not supported}}
|
||||
// CHECK-SUB_I128: {{0x80000000000000000000000000000000 - 1 cannot be represented in type '__int128'|__int128 not supported}}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ int main() {
|
|||
|
||||
#ifdef ADD_I64
|
||||
(void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull));
|
||||
// CHECK-ADD_I64: 10000000000000000000 + 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}'
|
||||
// CHECK-ADD_I64: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}'
|
||||
#endif
|
||||
|
||||
#ifdef ADD_I128
|
||||
|
@ -27,6 +27,6 @@ int main() {
|
|||
# else
|
||||
puts("__int128 not supported");
|
||||
# endif
|
||||
// CHECK-ADD_I128: {{0x80000000000000000000000000000000 \+ 0x80000000000000000000000000000000 cannot be represented in type '__uint128_t'|__int128 not supported}}
|
||||
// CHECK-ADD_I128: {{0x80000000000000000000000000000000 \+ 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128'|__int128 not supported}}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ int main() {
|
|||
(void)(uint16_t(0xffff) * uint16_t(0x8001));
|
||||
|
||||
(void)(uint32_t(0xffffffff) * uint32_t(0x2));
|
||||
// CHECK: umul-overflow.cpp:15:31: runtime error: unsigned integer overflow: 4294967295 * 2 cannot be represented in type '{{uint32_t|unsigned int}}'
|
||||
// CHECK: umul-overflow.cpp:15:31: runtime error: unsigned integer overflow: 4294967295 * 2 cannot be represented in type 'unsigned int'
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -12,12 +12,12 @@ int main() {
|
|||
|
||||
#ifdef SUB_I32
|
||||
(void)(uint32_t(1) - uint32_t(2));
|
||||
// CHECK-SUB_I32: usub-overflow.cpp:[[@LINE-1]]:22: runtime error: unsigned integer overflow: 1 - 2 cannot be represented in type '{{uint32_t|unsigned int}}'
|
||||
// CHECK-SUB_I32: usub-overflow.cpp:[[@LINE-1]]:22: runtime error: unsigned integer overflow: 1 - 2 cannot be represented in type 'unsigned int'
|
||||
#endif
|
||||
|
||||
#ifdef SUB_I64
|
||||
(void)(uint64_t(8000000000000000000ll) - uint64_t(9000000000000000000ll));
|
||||
// CHECK-SUB_I64: 8000000000000000000 - 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}'
|
||||
// CHECK-SUB_I64: 8000000000000000000 - 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}'
|
||||
#endif
|
||||
|
||||
#ifdef SUB_I128
|
||||
|
@ -26,6 +26,6 @@ int main() {
|
|||
# else
|
||||
puts("__int128 not supported\n");
|
||||
# endif
|
||||
// CHECK-SUB_I128: {{0x40000000000000000000000000000000 - 0x80000000000000000000000000000000 cannot be represented in type '__uint128_t'|__int128 not supported}}
|
||||
// CHECK-SUB_I128: {{0x40000000000000000000000000000000 - 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128'|__int128 not supported}}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ void func_1(void)
|
|||
struct S0 l_19;
|
||||
l_19.f2 = 419;
|
||||
uint32_t l_4037 = 4294967295UL;
|
||||
l_19.f2 = g_463; //%self.expect("expr ((l_4037 % (-(g_463))) | l_19.f2)", substrs=['(uint32_t) $0 = 358717883'])
|
||||
l_19.f2 = g_463; //%self.expect("expr ((l_4037 % (-(g_463))) | l_19.f2)", substrs=['(unsigned int) $0 = 358717883'])
|
||||
}
|
||||
int main()
|
||||
{
|
||||
|
|
|
@ -3,6 +3,6 @@ int main(void)
|
|||
__int128_t n = 1;
|
||||
n = n + n;
|
||||
return n; //%self.expect("p n", substrs=['(__int128_t) $0 = 2'])
|
||||
//%self.expect("p n + 6", substrs=['(__int128_t) $1 = 8'])
|
||||
//%self.expect("p n + n", substrs=['(__int128_t) $2 = 4'])
|
||||
//%self.expect("p n + 6", substrs=['(__int128) $1 = 8'])
|
||||
//%self.expect("p n + n", substrs=['(__int128) $2 = 4'])
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue