diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp --- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp @@ -330,7 +330,7 @@ void bar() { int (*placeholder)(int) = foo('c'); (void)placeholder; })cpp"}, - // Arithmetic on typedef types yields plain integer types + // Arithmetic on typedef types preserves typedef types {R"cpp(typedef long NSInteger; void varDecl() { NSInteger a = 2 * 5; @@ -339,7 +339,7 @@ R"cpp(typedef long NSInteger; void varDecl() { NSInteger a = 2 * 5; - long placeholder = a * 7; NSInteger b = placeholder + 3; + NSInteger placeholder = a * 7; NSInteger b = placeholder + 3; })cpp"}, }; for (const auto &IO : InputOutputs) { diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp @@ -42,7 +42,7 @@ // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. i = j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // 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] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -51,7 +51,7 @@ int j; vector v; i = j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // 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] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } @@ -63,7 +63,7 @@ // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. i += j + v.size(); - // CHECK-MESSAGES-DEFAULT: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions] + // 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] // IGNORED: Warning is disabled with IgnoreConversionFromTypes=global_size_t. } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1088,7 +1088,7 @@ if (IntTy->isComplexType() || IntTy->isRealFloatingType()) return true; if (SkipCast) return false; if (IntTy->isIntegerType()) { - QualType fpTy = cast(ComplexTy)->getElementType(); + QualType fpTy = ComplexTy->castAs()->getElementType(); IntExpr = S.ImpCastExprToType(IntExpr.get(), fpTy, CK_IntegralToFloating); IntExpr = S.ImpCastExprToType(IntExpr.get(), ComplexTy, CK_FloatingRealToComplex); @@ -1100,60 +1100,59 @@ 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(LongerType.getCanonicalType()); + QualType Result = + LongerIsComplex ? LongerType : S.Context.getComplexType(LongerType); + + if (PromotePrecision) { + if (isa(ShorterType.getCanonicalType())) { + Shorter = + S.ImpCastExprToType(Shorter.get(), Result, CK_FloatingComplexCast); + } else { + if (LongerIsComplex) + LongerType = LongerType->castAs()->getElementType(); + Shorter = S.ImpCastExprToType(Shorter.get(), LongerType, CK_FloatingCast); + } + } + return Result; +} + /// Handle arithmetic conversion with complex types. Helper function of /// UsualArithmeticConversions() -static QualType handleComplexFloatConversion(Sema &S, ExprResult &LHS, - ExprResult &RHS, QualType LHSType, - QualType RHSType, - bool IsCompAssign) { +static QualType handleComplexConversion(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); - - auto *LHSComplexType = dyn_cast(LHSType); - auto *RHSComplexType = dyn_cast(RHSType); - QualType LHSElementType = - LHSComplexType ? LHSComplexType->getElementType() : LHSType; - QualType RHSElementType = - RHSComplexType ? RHSComplexType->getElementType() : RHSType; - - QualType ResultType = S.Context.getComplexType(LHSElementType); - if (Order < 0) { + if (Order < 0) // Promote the precision of the LHS if not an assignment. - 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; + 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); } /// Handle arithmetic conversion from integer to float. Helper function @@ -1539,18 +1538,16 @@ // For conversion purposes, we ignore any qualifiers. // For example, "const float" and "float" are equivalent. - QualType LHSType = - Context.getCanonicalType(LHS.get()->getType()).getUnqualifiedType(); - QualType RHSType = - Context.getCanonicalType(RHS.get()->getType()).getUnqualifiedType(); + QualType LHSType = LHS.get()->getType().getUnqualifiedType(); + QualType RHSType = RHS.get()->getType().getUnqualifiedType(); // For conversion purposes, we ignore any atomic qualifier on the LHS. if (const AtomicType *AtomicLHS = LHSType->getAs()) LHSType = AtomicLHS->getValueType(); // If both types are identical, no conversion is needed. - if (LHSType == RHSType) - return LHSType; + if (Context.hasSameType(LHSType, RHSType)) + return Context.getCommonSugaredType(LHSType, RHSType); // 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). @@ -1568,8 +1565,8 @@ LHS = ImpCastExprToType(LHS.get(), LHSType, CK_IntegralCast); // If both types are identical, no conversion is needed. - if (LHSType == RHSType) - return LHSType; + if (Context.hasSameType(LHSType, RHSType)) + return Context.getCommonSugaredType(LHSType, RHSType); // At this point, we have two different arithmetic types. @@ -1580,8 +1577,8 @@ // Handle complex types first (C99 6.3.1.8p1). if (LHSType->isComplexType() || RHSType->isComplexType()) - return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType, - ACK == ACK_CompAssign); + return handleComplexConversion(*this, LHS, RHS, LHSType, RHSType, + ACK == ACK_CompAssign); // Now handle "real" floating types (i.e. float, double, long double). if (LHSType->isRealFloatingType() || RHSType->isRealFloatingType()) @@ -8158,23 +8155,6 @@ 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, @@ -8198,7 +8178,7 @@ if (S.Context.hasSameType(LHSTy, RHSTy)) { // Two identical pointers types are always compatible. - return LHSTy; + return S.Context.getCommonSugaredType(LHSTy, RHSTy); } QualType lhptee, rhptee; @@ -8700,7 +8680,7 @@ // And if they're both bfloat (which isn't arithmetic), that's fine too. if (LHSTy->isBFloat16Type() && RHSTy->isBFloat16Type()) { - return LHSTy; + return Context.getCommonSugaredType(LHSTy, RHSTy); } // If both operands are the same structure or union type, the result is that @@ -8710,14 +8690,29 @@ 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 LHSTy.getUnqualifiedType(); + return Context.getCommonSugaredType(LHSTy.getUnqualifiedType(), + RHSTy.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()) { - return checkConditionalVoidType(*this, LHS, RHS); + 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; } // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has @@ -8756,7 +8751,7 @@ // Allow ?: operations in which both operands have the same // built-in sizeless type. if (LHSTy->isSizelessBuiltinType() && Context.hasSameType(LHSTy, RHSTy)) - return LHSTy; + return Context.getCommonSugaredType(LHSTy, RHSTy); // 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 @@ -10427,7 +10422,7 @@ // If the vector types are identical, return. if (Context.hasSameType(LHSType, RHSType)) - return LHSType; + return Context.getCommonSugaredType(LHSType, RHSType); // If we have compatible AltiVec and GCC vector types, use the AltiVec type. if (LHSVecType && RHSVecType && @@ -13145,7 +13140,7 @@ assert((LHSMatType || RHSMatType) && "At least one operand must be a matrix"); if (Context.hasSameType(LHSType, RHSType)) - return LHSType; + return Context.getCommonSugaredType(LHSType, RHSType); // Type conversion may change LHS/RHS. Keep copies to the original results, in // case we have to return InvalidOperands. @@ -13189,13 +13184,19 @@ if (LHSMatType->getNumColumns() != RHSMatType->getNumRows()) return InvalidOperands(Loc, LHS, RHS); - if (!Context.hasSameType(LHSMatType->getElementType(), - RHSMatType->getElementType())) + 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)) return InvalidOperands(Loc, LHS, RHS); - return Context.getConstantMatrixType(LHSMatType->getElementType(), - LHSMatType->getNumRows(), - RHSMatType->getNumColumns()); + return Context.getConstantMatrixType( + Context.getCommonSugaredType(LHSELTy, RHSELTy), + LHSMatType->getNumRows(), RHSMatType->getNumColumns()); } return CheckMatrixElementwiseOperands(LHS, RHS, Loc, IsCompAssign); } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6216,7 +6216,7 @@ << LHSType << RHSType; return {}; } - ResultType = LHSType; + ResultType = Context.getCommonSugaredType(LHSType, RHSType); } else if (LHSVT || RHSVT) { ResultType = CheckVectorOperands( LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true, @@ -6227,15 +6227,13 @@ return {}; } else { // Both are scalar. - 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); + LHSType = LHSType.getUnqualifiedType(); + RHSType = RHSType.getUnqualifiedType(); + QualType ResultElementTy = + Context.hasSameType(LHSType, RHSType) + ? Context.getCommonSugaredType(LHSType, RHSType) + : UsualArithmeticConversions(LHS, RHS, QuestionLoc, + ACK_Conditional); if (ResultElementTy->isEnumeralType()) { Diag(QuestionLoc, diag::err_conditional_vector_operand_type) @@ -6455,7 +6453,7 @@ // -- Both the second and third operands have type void; the result is of // type void and is a prvalue. if (LVoid && RVoid) - return Context.VoidTy; + return Context.getCommonSugaredType(LTy, RTy); // Neither holds, error. Diag(QuestionLoc, diag::err_conditional_void_nonvoid) @@ -6561,21 +6559,7 @@ if (LHS.get()->getObjectKind() == OK_BitField || RHS.get()->getObjectKind() == OK_BitField) OK = OK_BitField; - - // 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; + return Context.getCommonSugaredType(LTy, RTy); } // C++11 [expr.cond]p5 @@ -6605,36 +6589,23 @@ // 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.getCanonicalType(LTy) == Context.getCanonicalType(RTy)) { + if (Context.hasSameType(LTy, RTy)) { if (LTy->isRecordType()) { // The operands have class type. Make a temporary copy. - InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy); - - ExprResult LHSCopy = PerformCopyInitialization(Entity, - SourceLocation(), - LHS); + ExprResult LHSCopy = PerformCopyInitialization( + InitializedEntity::InitializeTemporary(LTy), SourceLocation(), LHS); if (LHSCopy.isInvalid()) return QualType(); - ExprResult RHSCopy = PerformCopyInitialization(Entity, - SourceLocation(), - RHS); + ExprResult RHSCopy = PerformCopyInitialization( + InitializedEntity::InitializeTemporary(RTy), SourceLocation(), RHS); if (RHSCopy.isInvalid()) return QualType(); LHS = LHSCopy; RHS = RHSCopy; } - - // 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; + return Context.getCommonSugaredType(LTy, RTy); } // Extension: conditional operator involving vector types. @@ -7048,7 +7019,7 @@ Steps[I].Quals.addConst(); // Rebuild the composite type. - QualType Composite = Composite1; + QualType Composite = Context.getCommonSugaredType(Composite1, Composite2); for (auto &S : llvm::reverse(Steps)) Composite = S.rebuild(Context, Composite); diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -140,7 +140,7 @@ // CHECK: FunctionDecl {{.*}} func_14 'float (float, float)' // CHECK: CompoundStmt // CHECK-NEXT: ReturnStmt -// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=towardzero +// CHECK-NEXT: BinaryOperator {{.*}} 'float':'float' '+' ConstRoundingMode=towardzero float func_16(float x, float y) { #pragma STDC FENV_ROUND FE_TOWARDZERO diff --git a/clang/test/CodeGen/compound-assign-overflow.c b/clang/test/CodeGen/compound-assign-overflow.c --- a/clang/test/CodeGen/compound-assign-overflow.c +++ b/clang/test/CodeGen/compound-assign-overflow.c @@ -3,9 +3,9 @@ #include -// CHECK: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" } +// 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: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}} @[[INT]] -// CHECK: @[[UINT:.*]] = private unnamed_addr constant { i16, i16, [15 x i8] } { i16 0, i16 10, [15 x i8] c"'unsigned int'\00" } +// 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: @[[LINE_200:.*]] = private unnamed_addr global {{.*}}, i32 200, i32 5 {{.*}} @[[UINT]] // CHECK: @[[LINE_300:.*]] = private unnamed_addr global {{.*}}, i32 300, i32 5 {{.*}} @[[INT]] diff --git a/clang/test/Sema/complex-int.c b/clang/test/Sema/complex-int.c --- a/clang/test/Sema/complex-int.c +++ b/clang/test/Sema/complex-int.c @@ -11,6 +11,9 @@ int bb = 0; bb += 1i; +typedef __complex__ float ComplexFloat; +int cc = 1 + (ComplexFloat)(1.0iF); + result = arr*ii; result = ii*brr; diff --git a/clang/test/Sema/matrix-type-operators.c b/clang/test/Sema/matrix-type-operators.c --- a/clang/test/Sema/matrix-type-operators.c +++ b/clang/test/Sema/matrix-type-operators.c @@ -56,7 +56,7 @@ 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 'float __attribute__((matrix_type(10, 10)))'}} + // 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)))')}} // Check element type mismatches. a = b * c; @@ -64,10 +64,10 @@ 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 'float __attribute__((matrix_type(10, 10)))'}} + // 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)))')}} p = a * a; - // expected-error@-1 {{assigning to 'char *' from incompatible type 'float __attribute__((matrix_type(10, 10)))'}} + // expected-error@-1 {{assigning to 'char *' from incompatible type 'sx10x10_t' (aka 'float __attribute__((matrix_type(10, 10)))')}} } void mat_scalar_multiply(sx10x10_t a, sx5x10_t b, float sf, char *p) { diff --git a/clang/test/Sema/nullability.c b/clang/test/Sema/nullability.c --- a/clang/test/Sema/nullability.c +++ b/clang/test/Sema/nullability.c @@ -167,7 +167,7 @@ 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 'NullableIntP1' (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 : nullableP2; // expected-warning{{implicit conversion from nullable pointer 'NullableIntP1' (aka 'int *') to non-nullable pointer type 'int * _Nonnull'}} } diff --git a/clang/test/Sema/sugar-common-types.c b/clang/test/Sema/sugar-common-types.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/sugar-common-types.c @@ -0,0 +1,44 @@ +// 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'}} +} diff --git a/clang/test/SemaCXX/complex-conversion.cpp b/clang/test/SemaCXX/complex-conversion.cpp --- a/clang/test/SemaCXX/complex-conversion.cpp +++ b/clang/test/SemaCXX/complex-conversion.cpp @@ -15,4 +15,8 @@ // Conversion to bool doesn't actually discard the imaginary part. take(Complex); + + using B = _Complex double; + B c; + c *= double(); } diff --git a/clang/test/SemaCXX/matrix-type-operators.cpp b/clang/test/SemaCXX/matrix-type-operators.cpp --- a/clang/test/SemaCXX/matrix-type-operators.cpp +++ b/clang/test/SemaCXX/matrix-type-operators.cpp @@ -68,7 +68,7 @@ template typename MyMatrix::matrix_t multiply(MyMatrix &A, MyMatrix &B) { char *v1 = A.value * B.value; - // expected-error@-1 {{cannot initialize a variable of type 'char *' with an rvalue of type 'unsigned int __attribute__((matrix_type(2, 2)))'}} + // 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@-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)))'))}} diff --git a/clang/test/SemaCXX/sugar-common-types.cpp b/clang/test/SemaCXX/sugar-common-types.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/sugar-common-types.cpp @@ -0,0 +1,40 @@ +// 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)))'}} diff --git a/clang/test/SemaCXX/sugared-auto.cpp b/clang/test/SemaCXX/sugared-auto.cpp --- a/clang/test/SemaCXX/sugared-auto.cpp +++ b/clang/test/SemaCXX/sugared-auto.cpp @@ -157,7 +157,7 @@ return true ? a : b; if (false) return a; - return N(); // expected-error {{but deduced as 'SARS (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}} + return N(); // expected-error {{but deduced as 'Virus (*)() throw(Man, Vibrio)' (aka 'void (*)() throw(Man, Vibrio)')}} } #endif diff --git a/clang/test/SemaObjC/format-strings-objc.m b/clang/test/SemaObjC/format-strings-objc.m --- a/clang/test/SemaObjC/format-strings-objc.m +++ b/clang/test/SemaObjC/format-strings-objc.m @@ -268,7 +268,7 @@ // 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 {{format specifies type 'int' but the argument has type 'long'}} + 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}} } void testUnicode(void) { diff --git a/compiler-rt/test/ubsan/TestCases/Integer/add-overflow.cpp b/compiler-rt/test/ubsan/TestCases/Integer/add-overflow.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/add-overflow.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/add-overflow.cpp @@ -18,7 +18,7 @@ #ifdef ADD_I64 (void)(int64_t(8000000000000000000ll) + int64_t(2000000000000000000ll)); - // CHECK-ADD_I64: 8000000000000000000 + 2000000000000000000 cannot be represented in type '{{long( long)?}}' + // CHECK-ADD_I64: 8000000000000000000 + 2000000000000000000 cannot be represented in type '{{int64_t|long( long)?}}' #endif #ifdef ADD_I128 @@ -27,6 +27,6 @@ # else puts("__int128 not supported"); # endif - // CHECK-ADD_I128: {{0x40000000000000000000000000000000 \+ 0x40000000000000000000000000000000 cannot be represented in type '__int128'|__int128 not supported}} + // CHECK-ADD_I128: {{0x40000000000000000000000000000000 \+ 0x40000000000000000000000000000000 cannot be represented in type '__int128_t'|__int128 not supported}} #endif } diff --git a/compiler-rt/test/ubsan/TestCases/Integer/no-recover.cpp b/compiler-rt/test/ubsan/TestCases/Integer/no-recover.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/no-recover.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/no-recover.cpp @@ -20,7 +20,7 @@ // 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 'unsigned {{long( long)?}}' + // RECOVER: 10000000000000000000 + 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}' // SILENT-RECOVER-NOT: runtime error // ABORT-NOT: runtime error } diff --git a/compiler-rt/test/ubsan/TestCases/Integer/sub-overflow.cpp b/compiler-rt/test/ubsan/TestCases/Integer/sub-overflow.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/sub-overflow.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/sub-overflow.cpp @@ -12,12 +12,12 @@ #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 'int' + // CHECK-SUB_I32: sub-overflow.cpp:[[@LINE-1]]:22: runtime error: signed integer overflow: -2 - 2147483647 cannot be represented in type '{{int32_t|int}}' #endif #ifdef SUB_I64 (void)(int64_t(-8000000000000000000ll) - int64_t(2000000000000000000ll)); - // CHECK-SUB_I64: -8000000000000000000 - 2000000000000000000 cannot be represented in type '{{long( long)?}}' + // CHECK-SUB_I64: -8000000000000000000 - 2000000000000000000 cannot be represented in type '{{int64_t|long( long)?}}' #endif #ifdef SUB_I128 @@ -26,6 +26,6 @@ # else puts("__int128 not supported"); # endif - // CHECK-SUB_I128: {{0x80000000000000000000000000000000 - 1 cannot be represented in type '__int128'|__int128 not supported}} + // CHECK-SUB_I128: {{0x80000000000000000000000000000000 - 1 cannot be represented in type '__int128_t'|__int128 not supported}} #endif } diff --git a/compiler-rt/test/ubsan/TestCases/Integer/uadd-overflow.cpp b/compiler-rt/test/ubsan/TestCases/Integer/uadd-overflow.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/uadd-overflow.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/uadd-overflow.cpp @@ -18,7 +18,7 @@ #ifdef ADD_I64 (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull)); - // CHECK-ADD_I64: 10000000000000000000 + 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}' + // CHECK-ADD_I64: 10000000000000000000 + 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}' #endif #ifdef ADD_I128 @@ -27,6 +27,6 @@ # else puts("__int128 not supported"); # endif - // CHECK-ADD_I128: {{0x80000000000000000000000000000000 \+ 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128'|__int128 not supported}} + // CHECK-ADD_I128: {{0x80000000000000000000000000000000 \+ 0x80000000000000000000000000000000 cannot be represented in type '__uint128_t'|__int128 not supported}} #endif } diff --git a/compiler-rt/test/ubsan/TestCases/Integer/umul-overflow.cpp b/compiler-rt/test/ubsan/TestCases/Integer/umul-overflow.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/umul-overflow.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/umul-overflow.cpp @@ -13,7 +13,7 @@ (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 'unsigned int' + // CHECK: umul-overflow.cpp:15:31: runtime error: unsigned integer overflow: 4294967295 * 2 cannot be represented in type '{{uint32_t|unsigned int}}' return 0; } diff --git a/compiler-rt/test/ubsan/TestCases/Integer/usub-overflow.cpp b/compiler-rt/test/ubsan/TestCases/Integer/usub-overflow.cpp --- a/compiler-rt/test/ubsan/TestCases/Integer/usub-overflow.cpp +++ b/compiler-rt/test/ubsan/TestCases/Integer/usub-overflow.cpp @@ -12,12 +12,12 @@ #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 'unsigned int' + // 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}}' #endif #ifdef SUB_I64 (void)(uint64_t(8000000000000000000ll) - uint64_t(9000000000000000000ll)); - // CHECK-SUB_I64: 8000000000000000000 - 9000000000000000000 cannot be represented in type 'unsigned {{long( long)?}}' + // CHECK-SUB_I64: 8000000000000000000 - 9000000000000000000 cannot be represented in type '{{uint64_t|unsigned long( long)?}}' #endif #ifdef SUB_I128 @@ -26,6 +26,6 @@ # else puts("__int128 not supported\n"); # endif - // CHECK-SUB_I128: {{0x40000000000000000000000000000000 - 0x80000000000000000000000000000000 cannot be represented in type 'unsigned __int128'|__int128 not supported}} + // CHECK-SUB_I128: {{0x40000000000000000000000000000000 - 0x80000000000000000000000000000000 cannot be represented in type '__uint128_t'|__int128 not supported}} #endif } diff --git a/lldb/test/API/commands/expression/rdar42038760/main.c b/lldb/test/API/commands/expression/rdar42038760/main.c --- a/lldb/test/API/commands/expression/rdar42038760/main.c +++ b/lldb/test/API/commands/expression/rdar42038760/main.c @@ -10,7 +10,7 @@ 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=['(unsigned int) $0 = 358717883']) + l_19.f2 = g_463; //%self.expect("expr ((l_4037 % (-(g_463))) | l_19.f2)", substrs=['(uint32_t) $0 = 358717883']) } int main() { diff --git a/lldb/test/API/commands/expression/rdar44436068/main.c b/lldb/test/API/commands/expression/rdar44436068/main.c --- a/lldb/test/API/commands/expression/rdar44436068/main.c +++ b/lldb/test/API/commands/expression/rdar44436068/main.c @@ -3,6 +3,6 @@ __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) $1 = 8']) - //%self.expect("p n + n", substrs=['(__int128) $2 = 4']) + //%self.expect("p n + 6", substrs=['(__int128_t) $1 = 8']) + //%self.expect("p n + n", substrs=['(__int128_t) $2 = 4']) }