[clang] d3dc7d0 - [Sema][NFC] Improve test coverage of builtin operators.

Clement Courbet via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 4 07:47:35 PDT 2021


Author: Clement Courbet
Date: 2021-11-04T15:43:32+01:00
New Revision: d3dc7d077f1d9c9478813a34ed38abbcb4fc1ef5

URL: https://github.com/llvm/llvm-project/commit/d3dc7d077f1d9c9478813a34ed38abbcb4fc1ef5
DIFF: https://github.com/llvm/llvm-project/commit/d3dc7d077f1d9c9478813a34ed38abbcb4fc1ef5.diff

LOG: [Sema][NFC] Improve test coverage of builtin operators.

In preparation for D112453.

Fix numbering of tests for [over.built]: 15->16, 16->17.

Added: 
    clang/test/CXX/over/over.built/ast.cpp
    clang/test/CXX/over/over.built/p17.cpp
    clang/test/CXX/over/over.built/p18.cpp
    clang/test/CXX/over/over.built/p19.cpp
    clang/test/CXX/over/over.built/p20.cpp
    clang/test/CXX/over/over.built/p21.cpp
    clang/test/CXX/over/over.built/p22.cpp
    clang/test/CXX/over/over.built/p26.cpp

Modified: 
    clang/test/CXX/over/over.built/p15.cpp
    clang/test/CXX/over/over.built/p16.cpp
    clang/test/CXX/over/over.built/p23.cpp
    clang/test/CXX/over/over.built/p24.cpp
    clang/test/CXX/over/over.built/p25.cpp

Removed: 
    clang/test/CXX/over/over.built/p7-ast.cpp


################################################################################
diff  --git a/clang/test/CXX/over/over.built/p7-ast.cpp b/clang/test/CXX/over/over.built/ast.cpp
similarity index 64%
rename from clang/test/CXX/over/over.built/p7-ast.cpp
rename to clang/test/CXX/over/over.built/ast.cpp
index f3c44cff3951f..f76606b1f9869 100644
--- a/clang/test/CXX/over/over.built/p7-ast.cpp
+++ b/clang/test/CXX/over/over.built/ast.cpp
@@ -2,8 +2,8 @@
 
 struct A{};
 
-template <typename T>
-auto Test(T* pt) {
+template <typename T, typename U>
+auto Test(T* pt, U* pu) {
   // CHECK: UnaryOperator {{.*}} '<dependent type>' prefix '*'
   // CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
   (void)*pt;
@@ -24,7 +24,18 @@ auto Test(T* pt) {
   // CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
   // CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
   // CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
-  (void)(pt -pt);
+  (void)(pt - pt);
+
+  // CHECK: BinaryOperator {{.*}} '<dependent type>' '-'
+  // CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
+  // CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
+  (void)(pt - pu);
+
+  // CHECK: BinaryOperator {{.*}} '<dependent type>' '=='
+  // CHECK-NEXT: DeclRefExpr {{.*}} 'T *' lvalue ParmVar {{.*}} 'pt' 'T *'
+  // CHECK-NEXT: DeclRefExpr {{.*}} 'U *' lvalue ParmVar {{.*}} 'pu' 'U *'
+  (void)(pt == pu);
+
 }
 
 

diff  --git a/clang/test/CXX/over/over.built/p15.cpp b/clang/test/CXX/over/over.built/p15.cpp
index 9b223bcbc24d5..680ffa9a3dcb7 100644
--- a/clang/test/CXX/over/over.built/p15.cpp
+++ b/clang/test/CXX/over/over.built/p15.cpp
@@ -1,75 +1,12 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
 
-struct A { operator decltype(nullptr)(); }; // expected-note 16{{implicitly converted}}
-struct B { operator const int *(); }; // expected-note 8{{implicitly converted}}
-void f(A a, B b, volatile int *pi) {
-  (void)(a == a);
-  (void)(a != a);
-  (void)(a < a); // expected-error {{invalid operands}}
-  (void)(a > a); // expected-error {{invalid operands}}
-  (void)(a <= a); // expected-error {{invalid operands}}
-  (void)(a >= a); // expected-error {{invalid operands}}
-
-  (void)(a == b);
-  (void)(a != b);
-  (void)(a < b); // expected-error {{invalid operands}}
-  (void)(a > b); // expected-error {{invalid operands}}
-  (void)(a <= b); // expected-error {{invalid operands}}
-  (void)(a >= b); // expected-error {{invalid operands}}
-
-  (void)(b == a);
-  (void)(b != a);
-  (void)(b < a); // expected-error {{invalid operands}}
-  (void)(b > a); // expected-error {{invalid operands}}
-  (void)(b <= a); // expected-error {{invalid operands}}
-  (void)(b >= a); // expected-error {{invalid operands}}
-
-  (void)(a == pi);
-  (void)(a != pi);
-  (void)(a < pi); // expected-error {{invalid operands}}
-  (void)(a > pi); // expected-error {{invalid operands}}
-  (void)(a <= pi); // expected-error {{invalid operands}}
-  (void)(a >= pi); // expected-error {{invalid operands}}
-
-  (void)(pi == a);
-  (void)(pi != a);
-  (void)(pi < a); // expected-error {{invalid operands}}
-  (void)(pi > a); // expected-error {{invalid operands}}
-  (void)(pi <= a); // expected-error {{invalid operands}}
-  (void)(pi >= a); // expected-error {{invalid operands}}
-
-  (void)(b == pi);
-  (void)(b != pi);
-  (void)(b < pi);
-  (void)(b > pi);
-  (void)(b <= pi);
-  (void)(b >= pi);
-
-  (void)(pi == b);
-  (void)(pi != b);
-  (void)(pi < b);
-  (void)(pi > b);
-  (void)(pi <= b);
-  (void)(pi >= b);
-
-  (void)(b == b);
-  (void)(b != b);
-  (void)(b < b);
-  (void)(b > b);
-  (void)(b <= b);
-  (void)(b >= b);
-
-  (void)(pi == pi);
-  (void)(pi != pi);
-  (void)(pi < pi);
-  (void)(pi > pi);
-  (void)(pi <= pi);
-  (void)(pi >= pi);
-}
-
-// FIXME: This is wrong: the type T = 'const volatile int * const * const *'
-// would work here, and there exists a builtin candidate for that type.
-struct C { operator const int ***(); };
-void g(C c, volatile int ***p) {
-  (void)(c < p); // expected-error {{invalid operands}}
+template <typename T, typename U>
+void f(int* pi, float* pf, T* pt, U* pu, T t) {
+  (void)(pi - pi);
+  (void)(pi - pf);  // expected-error {{not pointers to compatible types}}
+  (void)(pi - pt);
+  (void)(pu - pi);
+  (void)(pu - pt);
+  (void)(pu - t);
+  (void)(pi - t);
 }

diff  --git a/clang/test/CXX/over/over.built/p16.cpp b/clang/test/CXX/over/over.built/p16.cpp
index 139e864475244..9b223bcbc24d5 100644
--- a/clang/test/CXX/over/over.built/p16.cpp
+++ b/clang/test/CXX/over/over.built/p16.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
 
-struct A { operator decltype(nullptr)(); };
-struct B { operator int A::*(); };
-void f(A a, B b, int A::*pi) {
+struct A { operator decltype(nullptr)(); }; // expected-note 16{{implicitly converted}}
+struct B { operator const int *(); }; // expected-note 8{{implicitly converted}}
+void f(A a, B b, volatile int *pi) {
   (void)(a == a);
   (void)(a != a);
   (void)(a < a); // expected-error {{invalid operands}}
@@ -40,36 +40,36 @@ void f(A a, B b, int A::*pi) {
 
   (void)(b == pi);
   (void)(b != pi);
-  (void)(b < pi); // expected-error {{invalid operands}}
-  (void)(b > pi); // expected-error {{invalid operands}}
-  (void)(b <= pi); // expected-error {{invalid operands}}
-  (void)(b >= pi); // expected-error {{invalid operands}}
+  (void)(b < pi);
+  (void)(b > pi);
+  (void)(b <= pi);
+  (void)(b >= pi);
 
   (void)(pi == b);
   (void)(pi != b);
-  (void)(pi < b); // expected-error {{invalid operands}}
-  (void)(pi > b); // expected-error {{invalid operands}}
-  (void)(pi <= b); // expected-error {{invalid operands}}
-  (void)(pi >= b); // expected-error {{invalid operands}}
+  (void)(pi < b);
+  (void)(pi > b);
+  (void)(pi <= b);
+  (void)(pi >= b);
 
   (void)(b == b);
   (void)(b != b);
-  (void)(b < b); // expected-error {{invalid operands}}
-  (void)(b > b); // expected-error {{invalid operands}}
-  (void)(b <= b); // expected-error {{invalid operands}}
-  (void)(b >= b); // expected-error {{invalid operands}}
+  (void)(b < b);
+  (void)(b > b);
+  (void)(b <= b);
+  (void)(b >= b);
 
   (void)(pi == pi);
   (void)(pi != pi);
-  (void)(pi < pi); // expected-error {{invalid operands}}
-  (void)(pi > pi); // expected-error {{invalid operands}}
-  (void)(pi <= pi); // expected-error {{invalid operands}}
-  (void)(pi >= pi); // expected-error {{invalid operands}}
+  (void)(pi < pi);
+  (void)(pi > pi);
+  (void)(pi <= pi);
+  (void)(pi >= pi);
 }
 
-// FIXME: This is wrong: type T = 'const volatile int * const A::* const B::*'
+// FIXME: This is wrong: the type T = 'const volatile int * const * const *'
 // would work here, and there exists a builtin candidate for that type.
-struct C { operator const int *A::*B::*(); };
-void g(C c, volatile int *A::*B::*p) {
-  (void)(c == p); // expected-error {{invalid operands}}
+struct C { operator const int ***(); };
+void g(C c, volatile int ***p) {
+  (void)(c < p); // expected-error {{invalid operands}}
 }

diff  --git a/clang/test/CXX/over/over.built/p17.cpp b/clang/test/CXX/over/over.built/p17.cpp
new file mode 100644
index 0000000000000..139e864475244
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p17.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+struct A { operator decltype(nullptr)(); };
+struct B { operator int A::*(); };
+void f(A a, B b, int A::*pi) {
+  (void)(a == a);
+  (void)(a != a);
+  (void)(a < a); // expected-error {{invalid operands}}
+  (void)(a > a); // expected-error {{invalid operands}}
+  (void)(a <= a); // expected-error {{invalid operands}}
+  (void)(a >= a); // expected-error {{invalid operands}}
+
+  (void)(a == b);
+  (void)(a != b);
+  (void)(a < b); // expected-error {{invalid operands}}
+  (void)(a > b); // expected-error {{invalid operands}}
+  (void)(a <= b); // expected-error {{invalid operands}}
+  (void)(a >= b); // expected-error {{invalid operands}}
+
+  (void)(b == a);
+  (void)(b != a);
+  (void)(b < a); // expected-error {{invalid operands}}
+  (void)(b > a); // expected-error {{invalid operands}}
+  (void)(b <= a); // expected-error {{invalid operands}}
+  (void)(b >= a); // expected-error {{invalid operands}}
+
+  (void)(a == pi);
+  (void)(a != pi);
+  (void)(a < pi); // expected-error {{invalid operands}}
+  (void)(a > pi); // expected-error {{invalid operands}}
+  (void)(a <= pi); // expected-error {{invalid operands}}
+  (void)(a >= pi); // expected-error {{invalid operands}}
+
+  (void)(pi == a);
+  (void)(pi != a);
+  (void)(pi < a); // expected-error {{invalid operands}}
+  (void)(pi > a); // expected-error {{invalid operands}}
+  (void)(pi <= a); // expected-error {{invalid operands}}
+  (void)(pi >= a); // expected-error {{invalid operands}}
+
+  (void)(b == pi);
+  (void)(b != pi);
+  (void)(b < pi); // expected-error {{invalid operands}}
+  (void)(b > pi); // expected-error {{invalid operands}}
+  (void)(b <= pi); // expected-error {{invalid operands}}
+  (void)(b >= pi); // expected-error {{invalid operands}}
+
+  (void)(pi == b);
+  (void)(pi != b);
+  (void)(pi < b); // expected-error {{invalid operands}}
+  (void)(pi > b); // expected-error {{invalid operands}}
+  (void)(pi <= b); // expected-error {{invalid operands}}
+  (void)(pi >= b); // expected-error {{invalid operands}}
+
+  (void)(b == b);
+  (void)(b != b);
+  (void)(b < b); // expected-error {{invalid operands}}
+  (void)(b > b); // expected-error {{invalid operands}}
+  (void)(b <= b); // expected-error {{invalid operands}}
+  (void)(b >= b); // expected-error {{invalid operands}}
+
+  (void)(pi == pi);
+  (void)(pi != pi);
+  (void)(pi < pi); // expected-error {{invalid operands}}
+  (void)(pi > pi); // expected-error {{invalid operands}}
+  (void)(pi <= pi); // expected-error {{invalid operands}}
+  (void)(pi >= pi); // expected-error {{invalid operands}}
+}
+
+// FIXME: This is wrong: type T = 'const volatile int * const A::* const B::*'
+// would work here, and there exists a builtin candidate for that type.
+struct C { operator const int *A::*B::*(); };
+void g(C c, volatile int *A::*B::*p) {
+  (void)(c == p); // expected-error {{invalid operands}}
+}

diff  --git a/clang/test/CXX/over/over.built/p18.cpp b/clang/test/CXX/over/over.built/p18.cpp
new file mode 100644
index 0000000000000..698a943cdab93
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p18.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+template <typename T, typename U>
+void f(int i, float f, bool b, int* pi, T* pt, T t) {
+  (void)(i % 3);
+  (void)(f % 3);  // expected-error {{invalid operands}}
+  (void)(b % 3);
+  (void)(pi % 3); // expected-error {{invalid operands}}
+  (void)(pt % 3); // FIXME
+  (void)(t % 3);
+  (void)(3 % i);
+  (void)(3 % f);  // expected-error {{invalid operands}}
+  (void)(3 % b);
+  (void)(3 % pi); // expected-error {{invalid operands}}
+  (void)(3 % pt); // FIXME
+  (void)(3 % t);
+
+  (void)(i & 3);
+  (void)(f & 3);  // expected-error {{invalid operands}}
+  (void)(b & 3);
+  (void)(pi & 3); // expected-error {{invalid operands}}
+  (void)(pt & 3); // FIXME
+  (void)(t & 3);
+  (void)(3 & i);
+  (void)(3 & f);  // expected-error {{invalid operands}}
+  (void)(3 & b);
+  (void)(3 & pi); // expected-error {{invalid operands}}
+  (void)(3 & pt); // FIXME
+  (void)(3 & t);
+
+  (void)(i ^ 3);
+  (void)(f ^ 3);  // expected-error {{invalid operands}}
+  (void)(b ^ 3);
+  (void)(pi ^ 3); // expected-error {{invalid operands}}
+  (void)(pt ^ 3); // FIXME
+  (void)(t ^ 3);
+  (void)(3 ^ i);
+  (void)(3 ^ f);  // expected-error {{invalid operands}}
+  (void)(3 ^ b);
+  (void)(3 ^ pi); // expected-error {{invalid operands}}
+  (void)(3 ^ pt); // FIXME
+  (void)(3 ^ t);
+
+  (void)(i | 3);
+  (void)(f | 3);  // expected-error {{invalid operands}}
+  (void)(b | 3);
+  (void)(pi | 3); // expected-error {{invalid operands}}
+  (void)(pt | 3); // FIXME
+  (void)(t | 3);
+  (void)(3 | i);
+  (void)(3 | f);  // expected-error {{invalid operands}}
+  (void)(3 | b);
+  (void)(3 | pi); // expected-error {{invalid operands}}
+  (void)(3 | pt); // FIXME
+  (void)(3 | t);
+
+  (void)(i << 3);
+  (void)(f << 3);  // expected-error {{invalid operands}}
+  (void)(b << 3);
+  (void)(pi << 3); // expected-error {{invalid operands}}
+  (void)(pt << 3); // FIXME
+  (void)(t << 3);
+  (void)(3 << i);
+  (void)(3 << f);  // expected-error {{invalid operands}}
+  (void)(3 << b);
+  (void)(3 << pi); // expected-error {{invalid operands}}
+  (void)(3 << pt); // FIXME
+  (void)(3 << t);
+
+  (void)(i >> 3);
+  (void)(f >> 3);  // expected-error {{invalid operands}}
+  (void)(b >> 3);
+  (void)(pi >> 3); // expected-error {{invalid operands}}
+  (void)(pt >> 3); // FIXME
+  (void)(t >> 3);
+  (void)(3 >> i);
+  (void)(3 >> f);  // expected-error {{invalid operands}}
+  (void)(3 >> b);
+  (void)(3 >> pi); // expected-error {{invalid operands}}
+  (void)(3 >> pt); // FIXME
+  (void)(3 >> t);
+}

diff  --git a/clang/test/CXX/over/over.built/p19.cpp b/clang/test/CXX/over/over.built/p19.cpp
new file mode 100644
index 0000000000000..0317f6b45a58d
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p19.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+template <typename T>
+void f(int i, float f, int* pi, T* pt, T t) {
+  i = i;
+  i *= i;
+  i /= i;
+  i += i;
+  i -= i;
+  i -= f;
+  i -= pi; // expected-error {{invalid operands}}
+  i -= pt; // FIXME
+  i -= t;
+
+  f = f;
+  f *= f;
+  f /= f;
+  f += f;
+  f -= f;
+  f -= i;
+  f -= pi; // expected-error {{invalid operands}}
+  f -= pt; // FIXME
+  f -= t;
+}

diff  --git a/clang/test/CXX/over/over.built/p20.cpp b/clang/test/CXX/over/over.built/p20.cpp
new file mode 100644
index 0000000000000..92ba118ee7345
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p20.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+template <typename T, typename U>
+void f(int* pi, float* pf, T* pt, U* pu, T t) {
+  pi = pi;
+  pi = pf; // expected-error {{incompatible pointer types}}
+  pi = pt;
+  pu = pi;
+  pu = pt;
+  pi = t;
+  pu = t;
+}

diff  --git a/clang/test/CXX/over/over.built/p21.cpp b/clang/test/CXX/over/over.built/p21.cpp
new file mode 100644
index 0000000000000..33db6647627b9
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p21.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+struct A {
+};
+
+template <typename T>
+void f(int A::* pi, float A::* pf, int T::* pt, T A::* pu, T t) {
+  pi = pi;
+  pi = pf; // expected-error {{assigning to 'int A::*' from incompatible type 'float A::*'}}
+  pi = pt;
+  pi = pu;
+  pi = t;
+}

diff  --git a/clang/test/CXX/over/over.built/p22.cpp b/clang/test/CXX/over/over.built/p22.cpp
new file mode 100644
index 0000000000000..330f1c9231407
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p22.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+template <typename T>
+void f(int* pi, T* pt, T t) {
+  pi += 3;
+  pi += pi; // expected-error {{invalid operands}}
+  pt += 3;
+  pi += t;
+  pi += pt; // FIXME
+  pt += pi; //FIXME
+  pt += pt; //FIXME
+}

diff  --git a/clang/test/CXX/over/over.built/p23.cpp b/clang/test/CXX/over/over.built/p23.cpp
index a1c0d4f3f612a..dfea85906f305 100644
--- a/clang/test/CXX/over/over.built/p23.cpp
+++ b/clang/test/CXX/over/over.built/p23.cpp
@@ -1,26 +1,46 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
-// expected-no-diagnostics
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
 
-struct Variant {
-  template <typename T> operator T();
-};
+template <typename T, typename U>
+void f(int i, float f, bool b, int* pi, T* pt, T t) {
+  i %= 3;
+  f %= 3;  // expected-error {{invalid operands}}
+  b %= 3;
+  pi %= 3; // expected-error {{invalid operands}}
+  pt %= 3; // FIXME
+  t %= 3;
 
-Variant getValue();
+  i &= 3;
+  f &= 3;  // expected-error {{invalid operands}}
+  b &= 3;
+  pi &= 3; // expected-error {{invalid operands}}
+  pt &= 3; // FIXME
+  t &= 3;
 
-void testVariant() {
-  bool ret1 = getValue() || getValue(); 
-  bool ret2 = getValue() && getValue(); 
-  bool ret3 = !getValue();
-}
+  i ^= 3;
+  f ^= 3;  // expected-error {{invalid operands}}
+  b ^= 3;
+  pi ^= 3; // expected-error {{invalid operands}}
+  pt ^= 3; // FIXME
+  t ^= 3;
 
-struct ExplicitVariant {
-  template <typename T> explicit operator T();
-};
+  i |= 3;
+  f |= 3;  // expected-error {{invalid operands}}
+  b |= 3;
+  pi |= 3; // expected-error {{invalid operands}}
+  pt |= 3; // FIXME
+  t |= 3;
 
-ExplicitVariant getExplicitValue();
+  i <<= 3;
+  f <<= 3;  // expected-error {{invalid operands}}
+  b <<= 3;
+  pi <<= 3; // expected-error {{invalid operands}}
+  pt <<= 3; // FIXME
+  t <<= 3;
 
-void testExplicitVariant() {
-  bool ret1 = getExplicitValue() || getExplicitValue(); 
-  bool ret2 = getExplicitValue() && getExplicitValue(); 
-  bool ret3 = !getExplicitValue();
+  i >>= 3;
+  f >>= 3;  // expected-error {{invalid operands}}
+  b >>= 3;
+  pi >>= 3; // expected-error {{invalid operands}}
+  pt >>= 3; // FIXME
+  t >>= 3;
 }

diff  --git a/clang/test/CXX/over/over.built/p24.cpp b/clang/test/CXX/over/over.built/p24.cpp
index 3c48dcd9aa673..a1c0d4f3f612a 100644
--- a/clang/test/CXX/over/over.built/p24.cpp
+++ b/clang/test/CXX/over/over.built/p24.cpp
@@ -1,12 +1,26 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
-
-template <typename T>
-void f(int i, float f, bool b, char c, int* pi, T* pt) {
-  (void)!i;
-  (void)!f;
-  (void)!b;
-  (void)!c;
-  (void)!pi;
-  (void)!pt;
-}
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 // expected-no-diagnostics
+
+struct Variant {
+  template <typename T> operator T();
+};
+
+Variant getValue();
+
+void testVariant() {
+  bool ret1 = getValue() || getValue(); 
+  bool ret2 = getValue() && getValue(); 
+  bool ret3 = !getValue();
+}
+
+struct ExplicitVariant {
+  template <typename T> explicit operator T();
+};
+
+ExplicitVariant getExplicitValue();
+
+void testExplicitVariant() {
+  bool ret1 = getExplicitValue() || getExplicitValue(); 
+  bool ret2 = getExplicitValue() && getExplicitValue(); 
+  bool ret3 = !getExplicitValue();
+}

diff  --git a/clang/test/CXX/over/over.built/p25.cpp b/clang/test/CXX/over/over.built/p25.cpp
index 09e550ddc0ec3..3c48dcd9aa673 100644
--- a/clang/test/CXX/over/over.built/p25.cpp
+++ b/clang/test/CXX/over/over.built/p25.cpp
@@ -1,16 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
-
-enum class Color { Red, Green, Blue };
-
-struct ConvertsToColorA {
-  operator Color();
-};
-
-struct ConvertsToColorB {
-  operator Color();
-};
-
-Color foo(bool cond, ConvertsToColorA ca, ConvertsToColorB cb) {
-  return cond? ca : cb;
+// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
+
+template <typename T>
+void f(int i, float f, bool b, char c, int* pi, T* pt) {
+  (void)!i;
+  (void)!f;
+  (void)!b;
+  (void)!c;
+  (void)!pi;
+  (void)!pt;
 }
+// expected-no-diagnostics

diff  --git a/clang/test/CXX/over/over.built/p26.cpp b/clang/test/CXX/over/over.built/p26.cpp
new file mode 100644
index 0000000000000..09e550ddc0ec3
--- /dev/null
+++ b/clang/test/CXX/over/over.built/p26.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+enum class Color { Red, Green, Blue };
+
+struct ConvertsToColorA {
+  operator Color();
+};
+
+struct ConvertsToColorB {
+  operator Color();
+};
+
+Color foo(bool cond, ConvertsToColorA ca, ConvertsToColorB cb) {
+  return cond? ca : cb;
+}


        


More information about the cfe-commits mailing list