[clang] use getCommonSugar in an assortment of places

For this patch, a simple search was performed for patterns where there are
two types (usually an LHS and an RHS) which are structurally the same, and there
is some result type which is resolved as either one of them (typically LHS for
consistency).

We change those cases to resolve as the common sugared type between those two,
utilizing the new infrastructure created for this purpose.

Depends on D111283

Signed-off-by: Matheus Izvekov <mizvekov@gmail.com>

Differential Revision: https://reviews.llvm.org/D111509
This commit is contained in:
Matheus Izvekov 2021-10-10 15:28:37 +02:00
parent d200db3863
commit d42122cd5d
No known key found for this signature in database
GPG Key ID: 22C080C6DC4E70F8
21 changed files with 170 additions and 113 deletions

View File

@ -330,7 +330,7 @@ TEST_F(ExtractVariableTest, Test) {
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 @@ TEST_F(ExtractVariableTest, Test) {
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) {

View File

@ -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 '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 @@ void narrowing_size_method_binary_expr() {
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 @@ 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 '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.
}

View File

@ -1539,18 +1539,16 @@ QualType Sema::UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS,
// 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<AtomicType>())
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 +1566,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 (LHSType == RHSType)
return LHSType;
if (Context.hasSameType(LHSType, RHSType))
return Context.getCommonSugaredType(LHSType, RHSType);
// At this point, we have two different arithmetic types.
@ -8158,23 +8156,6 @@ 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,
@ -8198,7 +8179,7 @@ static QualType checkConditionalPointerCompatibility(Sema &S, ExprResult &LHS,
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 +8681,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 LHSTy;
return Context.getCommonSugaredType(LHSTy, RHSTy);
}
// If both operands are the same structure or union type, the result is that
@ -8710,14 +8691,29 @@ 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 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 +8752,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 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 +10423,7 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
// 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 +13141,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 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 +13185,19 @@ QualType Sema::CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS,
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);
}

View File

@ -6215,7 +6215,7 @@ QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
<< LHSType << RHSType;
return {};
}
ResultType = LHSType;
ResultType = Context.getCommonSugaredType(LHSType, RHSType);
} else if (LHSVT || RHSVT) {
ResultType = CheckVectorOperands(
LHS, RHS, QuestionLoc, /*isCompAssign*/ false, /*AllowBothBool*/ true,
@ -6226,15 +6226,13 @@ QualType Sema::CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS,
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)
@ -6454,7 +6452,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.VoidTy;
return Context.getCommonSugaredType(LTy, RTy);
// Neither holds, error.
Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
@ -6560,21 +6558,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
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
@ -6604,36 +6588,23 @@ 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.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.
@ -7047,7 +7018,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
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);

View File

@ -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' '+' ConstRoundingMode=towardzero
// CHECK-NEXT: BinaryOperator {{.*}} 'float':'float' '+' ConstRoundingMode=towardzero
float func_16(float x, float y) {
#pragma STDC FENV_ROUND FE_TOWARDZERO

View File

@ -3,9 +3,9 @@
#include <stdint.h>
// 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]]

View File

@ -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 '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 @@ 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 '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) {

View File

@ -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 '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'}}
}

View File

@ -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'}}
}

View File

@ -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 '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)))'))}}

View File

@ -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)))'}}

View File

@ -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 '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

View File

@ -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 {{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) {

View File

@ -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 '{{long( long)?}}'
// CHECK-ADD_I64: 8000000000000000000 + 2000000000000000000 cannot be represented in type '{{int64_t|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'|__int128 not supported}}
// CHECK-ADD_I128: {{0x40000000000000000000000000000000 \+ 0x40000000000000000000000000000000 cannot be represented in type '__int128_t'|__int128 not supported}}
#endif
}

View File

@ -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 '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
}

View File

@ -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 '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 @@ int main() {
# 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
}

View File

@ -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 '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 @@ int main() {
# 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
}

View File

@ -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 '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;
}

View File

@ -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 '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 @@ int main() {
# 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
}

View File

@ -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=['(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()
{

View File

@ -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) $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'])
}