Sema: disable implicit conversion from _Complex to real types in C++.
authorTim Northover <tnorthover@apple.com>
Tue, 8 Aug 2017 23:18:05 +0000 (23:18 +0000)
committerTim Northover <tnorthover@apple.com>
Tue, 8 Aug 2017 23:18:05 +0000 (23:18 +0000)
Converting a _Complex type to a real one simply discards the imaginary part.
This can easily lead to loss of information so for safety (and GCC
compatibility) this patch disallows that when the conversion would be implicit.

The one exception is bool, which actually compares both real and imaginary
parts and so is safe.

llvm-svn: 310427

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaChecking.cpp
clang/lib/Sema/SemaExpr.cpp
clang/test/CodeGenCXX/stmtexpr.cpp
clang/test/OpenMP/atomic_capture_codegen.cpp
clang/test/OpenMP/atomic_update_codegen.cpp
clang/test/SemaCXX/complex-conversion.cpp [new file with mode: 0644]
clang/test/SemaCXX/complex-overload.cpp
clang/test/SemaCXX/integer-overflow.cpp
clang/test/SemaCXX/warn-absolute-value.cpp

index fb2c0a1..8a5c645 100644 (file)
@@ -3087,6 +3087,8 @@ def warn_impcast_vector_scalar : Warning<
 def warn_impcast_complex_scalar : Warning<
   "implicit conversion discards imaginary component: %0 to %1">,
   InGroup<Conversion>, DefaultIgnore;
+def err_impcast_complex_scalar : Error<
+  "implicit conversion from %0 to %1 is not permitted in C++">;
 def warn_impcast_float_precision : Warning<
   "implicit conversion loses floating-point precision: %0 to %1">,
   InGroup<Conversion>, DefaultIgnore;
index 578dbf0..bbb4b75 100644 (file)
@@ -9431,10 +9431,13 @@ void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
   // Strip complex types.
   if (isa<ComplexType>(Source)) {
     if (!isa<ComplexType>(Target)) {
-      if (S.SourceMgr.isInSystemMacro(CC))
+      if (S.SourceMgr.isInSystemMacro(CC) || Target->isBooleanType())
         return;
 
-      return DiagnoseImpCast(S, E, T, CC, diag::warn_impcast_complex_scalar);
+      return DiagnoseImpCast(S, E, T, CC,
+                             S.getLangOpts().CPlusPlus
+                                 ? diag::err_impcast_complex_scalar
+                                 : diag::warn_impcast_complex_scalar);
     }
 
     Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
index e482337..a1d3967 100644 (file)
@@ -7530,6 +7530,12 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
   if (unsupportedTypeConversion(*this, LHSType, RHSType))
     return Incompatible;
 
+  // Disallow assigning a _Complex to a real type in C++ mode since it simply
+  // discards the imaginary part.
+  if (getLangOpts().CPlusPlus && RHSType->getAs<ComplexType>() &&
+      !LHSType->getAs<ComplexType>())
+    return Incompatible;
+
   // Arithmetic conversions.
   if (LHSType->isArithmeticType() && RHSType->isArithmeticType() &&
       !(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) {
index 5bd9908..4586a3c 100644 (file)
@@ -173,7 +173,7 @@ extern "C" int cleanup_exit_lvalue_local(bool cond) {
 _Complex float bar_complex(A, int);
 extern "C" int cleanup_exit_complex(bool b) {
   _Complex float v = bar_complex(A(1), ({ if (b) return 42; 13; }));
-  return v;
+  return (float)v;
 }
 
 // CHECK-LABEL: define{{.*}} i32 @cleanup_exit_complex({{.*}})
index 0a22e42..72ecdf8 100644 (file)
@@ -611,50 +611,6 @@ int main() {
 // CHECK: store i8 [[DESIRED_I8]], i8* @{{.+}},
 #pragma omp atomic capture
   {bx = civ - bx; bv = bx;}
-// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
-// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float
-// <Skip checks for complex calculations>
-// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
-// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]]
-// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
-// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]]
-// CHECK: [[NEW:%.+]] = fptoui float [[X_RE]] to i16
-// CHECK: store i16 [[NEW]], i16* [[TEMP:%.+]],
-// CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]],
-// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-// CHECK: store i16 [[NEW]], i16* @{{.+}},
-#pragma omp atomic capture
-  usv = usx /= cfv;
-// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double
-// CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]]
-// CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]]
-// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64
-// CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]],
-// CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]],
-// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-// CHECK: store i64 [[EXPECTED]], i64* @{{.+}},
-#pragma omp atomic capture
-  {llv = llx; llx += cdv;}
 // CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}}
 // CHECK: load i8, i8*
 // CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
index 8c02a43..3675671 100644 (file)
@@ -554,48 +554,6 @@ int main() {
 // CHECK: [[EXIT]]
 #pragma omp atomic
   bx = civ - bx;
-// CHECK: [[EXPR_RE:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load float, float* getelementptr inbounds ({ float, float }, { float, float }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i16, i16* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i16 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[CONV:%.+]] = zext i16 [[EXPECTED]] to i32
-// CHECK: [[X_RVAL:%.+]] = sitofp i32 [[CONV]] to float
-// <Skip checks for complex calculations>
-// CHECK: [[X_RE_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP:%.+]], i32 0, i32 0
-// CHECK: [[X_RE:%.+]] = load float, float* [[X_RE_ADDR]]
-// CHECK: [[X_IM_ADDR:%.+]] = getelementptr inbounds { float, float }, { float, float }* [[TEMP]], i32 0, i32 1
-// CHECK: [[X_IM:%.+]] = load float, float* [[X_IM_ADDR]]
-// CHECK: [[DESIRED:%.+]] = fptoui float [[X_RE]] to i16
-// CHECK: store i16 [[DESIRED]], i16* [[TEMP:%.+]]
-// CHECK: [[DESIRED:%.+]] = load i16, i16* [[TEMP]]
-// CHECK: [[RES:%.+]] = cmpxchg i16* [[X_ADDR]], i16 [[EXPECTED]], i16 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i16, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i16, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-#pragma omp atomic update
-  usx /= cfv;
-// CHECK: [[EXPR_RE:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 0)
-// CHECK: [[EXPR_IM:%.+]] = load double, double* getelementptr inbounds ({ double, double }, { double, double }* @{{.+}}, i32 0, i32 1)
-// CHECK: [[X:%.+]] = load atomic i64, i64* [[X_ADDR:@.+]] monotonic
-// CHECK: br label %[[CONT:.+]]
-// CHECK: [[CONT]]
-// CHECK: [[EXPECTED:%.+]] = phi i64 [ [[X]], %{{.+}} ], [ [[OLD_X:%.+]], %[[CONT]] ]
-// CHECK: [[X_RVAL:%.+]] = sitofp i64 [[EXPECTED]] to double
-// CHECK: [[ADD_RE:%.+]] = fadd double [[X_RVAL]], [[EXPR_RE]]
-// CHECK: [[ADD_IM:%.+]] = fadd double 0.000000e+00, [[EXPR_IM]]
-// CHECK: [[DESIRED:%.+]] = fptosi double [[ADD_RE]] to i64
-// CHECK: store i64 [[DESIRED]], i64* [[TEMP:%.+]]
-// CHECK: [[DESIRED:%.+]] = load i64, i64* [[TEMP]]
-// CHECK: [[RES:%.+]] = cmpxchg i64* [[X_ADDR]], i64 [[EXPECTED]], i64 [[DESIRED]] monotonic monotonic
-// CHECK: [[OLD_X]] = extractvalue { i64, i1 } [[RES]], 0
-// CHECK: [[SUCCESS_FAIL:%.+]] = extractvalue { i64, i1 } [[RES]], 1
-// CHECK: br i1 [[SUCCESS_FAIL]], label %[[EXIT:.+]], label %[[CONT]]
-// CHECK: [[EXIT]]
-#pragma omp atomic
-  llx += cdv;
 // CHECK: [[IDX:%.+]] = load i16, i16* @{{.+}}
 // CHECK: load i8, i8*
 // CHECK: [[VEC_ITEM_VAL:%.+]] = zext i1 %{{.+}} to i32
diff --git a/clang/test/SemaCXX/complex-conversion.cpp b/clang/test/SemaCXX/complex-conversion.cpp
new file mode 100644 (file)
index 0000000..e8f0995
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void take(T);
+
+void func(float Real, _Complex float Complex) {
+  Real += Complex; // expected-error {{assigning to 'float' from incompatible type '_Complex float'}}
+  Real += (float)Complex;
+
+  Real = Complex; // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+  Real = (float)Complex;
+
+  take<float>(Complex); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+  take<double>(1.0i); // expected-error {{implicit conversion from '_Complex double' to 'double' is not permitted in C++}}
+  take<_Complex float>(Complex);
+
+  // Conversion to bool doesn't actually discard the imaginary part.
+  take<bool>(Complex);
+}
index 1381968..9373e44 100644 (file)
@@ -4,9 +4,10 @@ char *foo(float);
 void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
   char *cp1 = foo(fv);
   char *cp2 = foo(dv);
-  // Note: GCC and EDG reject these two, but they are valid C99 conversions
-  char *cp3 = foo(fc);
-  char *cp4 = foo(dc);
+  // Note: GCC and EDG reject these two, they are valid C99 conversions but
+  // shouldn't be accepted in C++ because the result is surprising.
+  char *cp3 = foo(fc); // expected-error {{implicit conversion from '_Complex float' to 'float' is not permitted in C++}}
+  char *cp4 = foo(dc); // expected-error {{implicit conversion from '_Complex double' to 'float' is not permitted in C++}}
 }
 
 int *foo(float _Complex);
index a119f0e..6abc956 100644 (file)
@@ -164,7 +164,7 @@ uint64_t check_integer_overflows(int i) { //expected-note {{declared here}}
 // expected-warning@+3 {{array index 536870912 is past the end of the array (which contains 10 elements)}}
 // expected-note@+1 {{array 'a' declared here}}
   uint64_t a[10];
-  a[4608 * 1024 * 1024] = 1i;
+  a[4608 * 1024 * 1024] = 1;
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
index 8a8a6fd..9a23054 100644 (file)
@@ -448,94 +448,16 @@ void test_long_double(long double x) {
 }
 
 void test_complex_float(_Complex float x) {
-  (void)abs(x);
-  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsf"
-  (void)labs(x);
-  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
-  (void)llabs(x);
-  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
-
-  (void)fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
-  (void)fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsf"
-  (void)fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsf"
-
   (void)cabsf(x);
   (void)cabs(x);
   (void)cabsl(x);
 
-  (void)__builtin_abs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsf"
-  (void)__builtin_labs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
-  (void)__builtin_llabs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
-
-  (void)__builtin_fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
-  (void)__builtin_fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsf"
-  (void)__builtin_fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsf' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsf"
-
   (void)__builtin_cabsf(x);
   (void)__builtin_cabs(x);
   (void)__builtin_cabsl(x);
 }
 
 void test_complex_double(_Complex double x) {
-  (void)abs(x);
-  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabs"
-  (void)labs(x);
-  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
-  (void)llabs(x);
-  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
-
-  (void)fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
-  (void)fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabs"
-  (void)fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabs"
-
   (void)cabsf(x);
   // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
   // expected-note@-2 {{use function 'cabs' instead}}
@@ -543,31 +465,6 @@ void test_complex_double(_Complex double x) {
   (void)cabs(x);
   (void)cabsl(x);
 
-  (void)__builtin_abs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabs"
-  (void)__builtin_labs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
-  (void)__builtin_llabs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
-
-  (void)__builtin_fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
-  (void)__builtin_fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabs"
-  (void)__builtin_fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabs' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabs"
 
   (void)__builtin_cabsf(x);
   // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex double' but has parameter of type '_Complex float' which may cause truncation of value}}
@@ -578,32 +475,6 @@ void test_complex_double(_Complex double x) {
 }
 
 void test_complex_long_double(_Complex long double x) {
-  (void)abs(x);
-  // expected-warning@-1 {{using integer absolute value function 'abs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:12}:"cabsl"
-  (void)labs(x);
-  // expected-warning@-1 {{using integer absolute value function 'labs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
-  (void)llabs(x);
-  // expected-warning@-1 {{using integer absolute value function 'llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
-
-  (void)fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
-  (void)fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
-  (void)fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function 'fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function 'cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:14}:"cabsl"
-
   (void)cabsf(x);
   // expected-warning@-1 {{absolute value function 'cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
   // expected-note@-2 {{use function 'cabsl' instead}}
@@ -614,32 +485,6 @@ void test_complex_long_double(_Complex long double x) {
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:13}:"cabsl"
   (void)cabsl(x);
 
-  (void)__builtin_abs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_abs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:22}:"__builtin_cabsl"
-  (void)__builtin_labs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_labs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
-  (void)__builtin_llabs(x);
-  // expected-warning@-1 {{using integer absolute value function '__builtin_llabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
-
-  (void)__builtin_fabsf(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsf' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
-  (void)__builtin_fabs(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabs' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:23}:"__builtin_cabsl"
-  (void)__builtin_fabsl(x);
-  // expected-warning@-1 {{using floating point absolute value function '__builtin_fabsl' when argument is of complex type}}
-  // expected-note@-2 {{use function '__builtin_cabsl' instead}}
-  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:9-[[@LINE-3]]:24}:"__builtin_cabsl"
-
   (void)__builtin_cabsf(x);
   // expected-warning@-1 {{absolute value function '__builtin_cabsf' given an argument of type '_Complex long double' but has parameter of type '_Complex float' which may cause truncation of value}}
   // expected-note@-2 {{use function '__builtin_cabsl' instead}}