[clang] use getCommonSugar in an assortment of places
authorMatheus Izvekov <mizvekov@gmail.com>
Sun, 10 Oct 2021 13:28:37 +0000 (15:28 +0200)
committerMatheus Izvekov <mizvekov@gmail.com>
Thu, 8 Sep 2022 17:17:53 +0000 (19:17 +0200)
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

21 files changed:
clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/narrowing-conversions-ignoreconversionfromtypes-option.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/test/AST/ast-dump-fpfeatures.cpp
clang/test/CodeGen/compound-assign-overflow.c
clang/test/Sema/matrix-type-operators.c
clang/test/Sema/nullability.c
clang/test/Sema/sugar-common-types.c [new file with mode: 0644]
clang/test/SemaCXX/matrix-type-operators.cpp
clang/test/SemaCXX/sugar-common-types.cpp [new file with mode: 0644]
clang/test/SemaCXX/sugared-auto.cpp
clang/test/SemaObjC/format-strings-objc.m
compiler-rt/test/ubsan/TestCases/Integer/add-overflow.cpp
compiler-rt/test/ubsan/TestCases/Integer/no-recover.cpp
compiler-rt/test/ubsan/TestCases/Integer/sub-overflow.cpp
compiler-rt/test/ubsan/TestCases/Integer/uadd-overflow.cpp
compiler-rt/test/ubsan/TestCases/Integer/umul-overflow.cpp
compiler-rt/test/ubsan/TestCases/Integer/usub-overflow.cpp
lldb/test/API/commands/expression/rdar42038760/main.c
lldb/test/API/commands/expression/rdar44436068/main.c

index 70ecc202d0b28854dd8550c5c26db2f683e67695..6e38ea77ad68d153d85d2edbf6290bd3e339df42 100644 (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) {
index 2fc5621c2fb8fa81c778b21e7c686fbf5b198fac..34da420fd0cc539a88f370f067581945e447049b 100644 (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.
 }
 
index 43c27c0ddd5e9e477471d33f9080924d02c47470..4a4abcb03a76d9a6031a417f74ae66ebbb95f74c 100644 (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);
 }
index 375e1285f8af89781ee087528f9af14585a515ef..947d0d7b532e1f29c71b2f1b9c7441e667df7dff 100644 (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);
 
index da0011602a728e12508f32e6379e877e855b29be..9228b6e7238be770d866d00571c4aacb1827b56d 100644 (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
index 30f9138f735289e35b9d939f9f8028d759d6229d..37ec63801168d217377a51a58cded71aa2a01756 100644 (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]]
 
index 7307918b6f8d69933e42ec2e062858255e5d490b..c83685fc7c640204c367dd12ca05eb4bbb0256bf 100644 (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) {
index 29b4955f926b9d49ad6a27e9d16ffcf52504fe51..7d193bea46771ff2f38d9f31dc4dc8f90e8348ba 100644 (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'}}
 }
 
diff --git a/clang/test/Sema/sugar-common-types.c b/clang/test/Sema/sugar-common-types.c
new file mode 100644 (file)
index 0000000..567659d
--- /dev/null
@@ -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'}}
+}
index c81b9b92628724bdd8125568a6976ea1915b7b7e..3809e82e8c0ba70bfadf93af99efe869fbafb25c 100644 (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)))'))}}
 
diff --git a/clang/test/SemaCXX/sugar-common-types.cpp b/clang/test/SemaCXX/sugar-common-types.cpp
new file mode 100644 (file)
index 0000000..8c18d8a
--- /dev/null
@@ -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)))'}}
index 15bcf3616464abfb341432c2e66c239cd5468dbe..4d6cabba6af1b23b5dca929b6f2cba4926e4b6f5 100644 (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
 
index 51638f9fa4a08867d2ef9dbb8b689fc2ed713cc6..8eb350fc194d568098330aeb7667c1db5fba43eb 100644 (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) {
index 301941b852b40c98bc825c7be7b5574841811fb8..2f6e699525887d5d526bd23e59cc3f41524ef4e6 100644 (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
 }
index 45aeb9e7524110006f2eecd811e3a79a22c60026..05382ca5065ab58178b39672dd364bbf51646357 100644 (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
 }
index 54ec4b5cd3c662ad8912feeeb415848eb7f213b6..f198800c06ec6baf5ae1414d368be25ee5bc6b3d 100644 (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
 }
index 8ef8983b56e0cb646799813126d7f88603ab539a..252b205f070b092c146e4e31726507f0b5d00e8e 100644 (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
 }
index ad5d1bd0d13c4250df6c042c6e56fe63dca7e9e3..dd17ff6272c13bea53fea55db46438ed7b6a98ee 100644 (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;
 }
index fb671b003af75327a37e230d294d105a022c16e4..093bc6d8cbf2737b6fc548cfe5f21743c0befb8b 100644 (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
 }
index 2ce1e4ee9aacc30d744ff69187c9f58bd1a8c757..69f5ffc6a7ae2cb9cf8f3bfa394065421b715ed2 100644 (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()
 {
index 156dbf04a1b70a35b64b858fb8d629cd342024e0..092913d8a9056642b60532f9d780fba45542ec90 100644 (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'])
 }