re PR c++/85032 (Wrong non-constant condition for static assertion)
authorMarek Polacek <polacek@redhat.com>
Wed, 11 Apr 2018 13:10:16 +0000 (13:10 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Wed, 11 Apr 2018 13:10:16 +0000 (13:10 +0000)
PR c++/85032
* constexpr.c (potential_constant_expression_1): Consider conversions
from classes to literal types potentially constant.

* g++.dg/cpp0x/pr51225.C: Adjust error message.
* g++.dg/cpp1z/constexpr-if21.C: New test.

From-SVN: r259318

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/pr51225.C
gcc/testsuite/g++.dg/cpp1z/constexpr-if21.C [new file with mode: 0644]

index 78e7ed77b454e990b7a06350fcbb2fb92f7b57f1..e9a32b0d204006225c165d9f1994e122b8325686 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-11  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/85032
+       * constexpr.c (potential_constant_expression_1): Consider conversions
+       from classes to literal types potentially constant.
+
 2018-04-10  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/70808
index 3cc196b4d17abec7673b2c046ed8479cce972de7..75f56df4465e26c91e6145e3a7df52c4155fd376 100644 (file)
@@ -5777,6 +5777,25 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
                      TREE_TYPE (t));
          return false;
        }
+      /* This might be a conversion from a class to a (potentially) literal
+        type.  Let's consider it potentially constant since the conversion
+        might be a constexpr user-defined conversion.  */
+      else if (cxx_dialect >= cxx11
+              && (dependent_type_p (TREE_TYPE (t))
+                  || !COMPLETE_TYPE_P (TREE_TYPE (t))
+                  || literal_type_p (TREE_TYPE (t)))
+              && TREE_OPERAND (t, 0))
+       {
+         tree type = TREE_TYPE (TREE_OPERAND (t, 0));
+         /* If this is a dependent type, it could end up being a class
+            with conversions.  */
+         if (type == NULL_TREE || WILDCARD_TYPE_P (type))
+           return true;
+         /* Or a non-dependent class which has conversions.  */
+         else if (CLASS_TYPE_P (type)
+                  && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
+           return true;
+       }
 
       return (RECUR (TREE_OPERAND (t, 0),
                     TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE));
index 8deaeb959746ba4fb7ac614c80c7acf41efacdee..186986aafe4f231c21dae3b958d277aad794950d 100644 (file)
@@ -1,3 +1,9 @@
+2018-04-11  Marek Polacek  <polacek@redhat.com>
+
+       PR c++/85032
+       * g++.dg/cpp0x/pr51225.C: Adjust error message.
+       * g++.dg/cpp1z/constexpr-if21.C: New test.
+
 2018-04-11  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/85281
index f80bd0e778e76fbfcf6e919a60818e432f52abc7..5b4e432f7edad849340c8be5cd46b51e08b91705 100644 (file)
@@ -5,7 +5,7 @@ template<int> struct A {};
 
 template<typename> void foo()
 {
-  A<int(x)> a; // { dg-error "not declared|invalid type" }
+  A<int(x)> a; // { dg-error "not declared|could not convert" }
 }
 
 template<typename> struct bar
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if21.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if21.C
new file mode 100644 (file)
index 0000000..56e108b
--- /dev/null
@@ -0,0 +1,22 @@
+// PR c++/85032
+// { dg-options -std=c++17 }
+
+struct A
+{
+  constexpr operator bool () { return true; }
+  int i;
+};
+
+A a;
+
+template <class T>
+void f()
+{
+  constexpr bool b = a;
+  static_assert (a);
+}
+
+int main()
+{
+  f<int>();
+}