[v2] : testcases for "ICE for unknown parameter to constexpr'd switch-statement, PR113545"
Checks
Commit Message
> Date: Wed, 7 Feb 2024 16:32:57 -0500
> From: Jason Merrill <jason@redhat.com>
> Incidentally, these testcases seem to require C++14; you can't have a
> switch in a constexpr function in C++11.
Update, v2 (from v1 that had a few requests from Marek
resolved from v0 that was posted together with my patch^Whack):
Move from cpp0x to cpp1y. Qualify with c++14 instead of
c++11. Add a one-liner commit-message.
I checked that these DTRT. Currently:
Using "make check-gcc-c++ RUNTESTFLAGS=dg.exp=constexpr-reinterpret\*":
Running /x/gcc/gcc/testsuite/g++.dg/dg.exp ...
=== g++ Summary ===
# of expected passes 33
# of expected failures 3
# of unresolved testcases 3
# of unsupported tests 4
...and that there's an XPASS when a ICE-resolving patch is
applied, testing each of my hack and Jason's, both yield:
Using /x/gcc/gcc/testsuite/config/default.exp as tool-and-target-specific interface file.
Running /x/gcc/gcc/testsuite/g++.dg/dg.exp ...
XPASS: g++.dg/cpp1y/constexpr-reinterpret3.C -std=c++14 (internal compiler error)
XPASS: g++.dg/cpp1y/constexpr-reinterpret3.C -std=c++17 (internal compiler error)
XPASS: g++.dg/cpp1y/constexpr-reinterpret3.C -std=c++20 (internal compiler error)
And (since it appears the benefit isn't obvious) why commit
a test-cases before the fix? Well, I'm not dead sure the
fix both gets there soon, and that it then stays there.
Even if it does so within decent time, as an exception
(IIUC) because we're in stage 4 and the bug is not a
regression, it could easily be reverted if it'd uncover some
other wart that's not sufficiently easily resolved.
Also, the fix seems to me sufficiently remote to the
gcc_assert, that the execution path leading to it could be
diverted; hidden or resolved while fixing something else,
and then it'd be nice to know that it fixed *this* bug too.
To wit: More dg-ice test-cases! Don't fear adding xfails or
dg-ices! Marek, you write that dg-ice support. Thank you!
Ok to commit?
-- >8 --
gcc/testsuite:
Test-cases, with constexpr-reinterpret3.C dg-ice:ing the PR c++/113545 bug.
PR c++/113545
* g++.dg/cpp1y/constexpr-reinterpret3.C,
g++.dg/cpp1y/constexpr-reinterpret4.C: New tests.
---
.../g++.dg/cpp1y/constexpr-reinterpret3.C | 55 +++++++++++++++++++
.../g++.dg/cpp1y/constexpr-reinterpret4.C | 54 ++++++++++++++++++
2 files changed, 109 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-reinterpret3.C
create mode 100644 gcc/testsuite/g++.dg/cpp1y/constexpr-reinterpret4.C
new file mode 100644
@@ -0,0 +1,55 @@
+// PR c++/113545
+// { dg-do run { target c++14 } }
+// { dg-ice "PR112545 - constexpr function with switch called for reinterpret_cast" }
+
+char foo;
+
+// This one caught a call to gcc_unreachable in
+// cp/constexpr.cc:label_matches, when passed a convert_expr from the
+// cast in the call.
+constexpr unsigned char swbar(__UINTPTR_TYPE__ baz)
+{
+ switch (baz)
+ {
+ case 13:
+ return 11;
+ case 14:
+ return 78;
+ case 2048:
+ return 13;
+ default:
+ return 42;
+ }
+}
+
+// For reference, the equivalent* if-statements.
+constexpr unsigned char ifbar(__UINTPTR_TYPE__ baz)
+{
+ if (baz == 13)
+ return 11;
+ else if (baz == 14)
+ return 78;
+ else if (baz == 2048)
+ return 13;
+ else
+ return 42;
+}
+
+__attribute__ ((__noipa__))
+void xyzzy(int x)
+{
+ if (x != 42)
+ __builtin_abort ();
+}
+
+int main()
+{
+ unsigned const char c = swbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo));
+ xyzzy(c);
+ unsigned const char d = ifbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo));
+ xyzzy(d);
+ unsigned const char e = swbar((__UINTPTR_TYPE__) &foo);
+ xyzzy(e);
+ unsigned const char f = ifbar((__UINTPTR_TYPE__) &foo);
+ xyzzy(f);
+}
new file mode 100644
@@ -0,0 +1,54 @@
+// PR c++/113545
+// { dg-do compile { target c++14 } }
+
+char foo;
+
+// This one caught a call to gcc_unreachable in
+// cp/constexpr.cc:label_matches, when passed a convert_expr from the
+// cast in the call.
+constexpr unsigned char swbar(__UINTPTR_TYPE__ baz)
+{
+ switch (baz)
+ {
+ case 13:
+ return 11;
+ case 14:
+ return 78;
+ case 2048:
+ return 13;
+ default:
+ return 42;
+ }
+}
+
+// For reference, the equivalent* if-statements.
+constexpr unsigned char ifbar(__UINTPTR_TYPE__ baz)
+{
+ if (baz == 13)
+ return 11;
+ else if (baz == 14)
+ return 78;
+ else if (baz == 2048)
+ return 13;
+ else
+ return 42;
+}
+
+__attribute__ ((__noipa__))
+void xyzzy(int x)
+{
+ if (x != 42)
+ __builtin_abort ();
+}
+
+int main()
+{
+ unsigned constexpr char c = swbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo)); // { dg-error "conversion from pointer type" }
+ xyzzy(c);
+ unsigned constexpr char d = ifbar(reinterpret_cast<__UINTPTR_TYPE__>(&foo)); // { dg-error "conversion from pointer type" }
+ xyzzy(d);
+ unsigned constexpr char e = swbar((__UINTPTR_TYPE__) &foo); // { dg-error "conversion from pointer type" }
+ xyzzy(e);
+ unsigned constexpr char f = ifbar((__UINTPTR_TYPE__) &foo); // { dg-error "conversion from pointer type" }
+ xyzzy(f);
+}