aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2018-04-11 13:10:16 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2018-04-11 13:10:16 +0000
commitfe0604d349c4d9eb18b17dd018383d591eed67c7 (patch)
treed7f57dd15cf204ad849d48116e131e9bfa30ab5e
parent3c7b865120aa05bb23a825e46597c85279fc5761 (diff)
downloadgcc-fe0604d349c4d9eb18b17dd018383d591eed67c7.zip
gcc-fe0604d349c4d9eb18b17dd018383d591eed67c7.tar.gz
gcc-fe0604d349c4d9eb18b17dd018383d591eed67c7.tar.bz2
re PR c++/85032 (Wrong non-constant condition for static assertion)
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr51225.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if21.C22
5 files changed, 54 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 78e7ed7..e9a32b0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 3cc196b..75f56df 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8deaeb9..186986a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr51225.C b/gcc/testsuite/g++.dg/cpp0x/pr51225.C
index f80bd0e..5b4e432 100644
--- a/gcc/testsuite/g++.dg/cpp0x/pr51225.C
+++ b/gcc/testsuite/g++.dg/cpp0x/pr51225.C
@@ -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
index 0000000..56e108b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if21.C
@@ -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>();
+}