aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2023-05-07 10:24:49 -0400
committerPatrick Palka <ppalka@redhat.com>2023-05-07 10:24:49 -0400
commit7f4840ddef9746ab591c78ecdd750e3b18aa1ce6 (patch)
tree3f5d8e64336e092b7f95b9ca3d9e7bbdb7b11328 /gcc
parentb05b529125fa51e24b35ef9ac13b875521c9b052 (diff)
downloadgcc-7f4840ddef9746ab591c78ecdd750e3b18aa1ce6.zip
gcc-7f4840ddef9746ab591c78ecdd750e3b18aa1ce6.tar.gz
gcc-7f4840ddef9746ab591c78ecdd750e3b18aa1ce6.tar.bz2
c++: potentiality of templated memfn call [PR109480]
Here we're incorrectly deeming the templated call a.g() inside b's initializer as potentially constant, despite g being non-constexpr, which leads to us needlessly instantiating the initializer ahead of time and which subsequently triggers a bug in access checking deferral (to be fixed by the follow-up patch). This patch fixes this by calling get_fns earlier during CALL_EXPR potentiality checking so that when we extract a FUNCTION_DECL out of a templated member function call (whose overall callee is typically a COMPONENT_REF) we do the usual constexpr-eligibility checking for it. In passing, I noticed the nearby special handling of the object argument of a non-static member function call is effectively the same as the generic argument handling a few lines below. So this patch just gets rid of this special handling; otherwise we'd have to adapt it to handle templated versions of such calls. PR c++/109480 gcc/cp/ChangeLog: * constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Reorganize to call get_fns sooner. Remove special handling of the object argument of a non-static member function call. Remove dead store to 'fun'. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/noexcept59.C: Make e() constexpr so that the expected "without object" diagnostic isn't replaced by a "call to non-constexpr function" diagnostic. * g++.dg/template/non-dependent25.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/constexpr.cc32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept59.C2
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent25.C14
3 files changed, 21 insertions, 27 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 70dd6cf..987a536 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9135,6 +9135,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
if (fun && is_overloaded_fn (fun))
{
+ if (!RECUR (fun, true))
+ return false;
+ fun = get_fns (fun);
+
if (TREE_CODE (fun) == FUNCTION_DECL)
{
if (builtin_valid_in_constant_expr_p (fun))
@@ -9165,36 +9169,12 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
explain_invalid_constexpr_fn (fun);
return false;
}
- /* A call to a non-static member function takes the address
- of the object as the first argument. But in a constant
- expression the address will be folded away, so look
- through it now. */
- if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun)
- && !DECL_CONSTRUCTOR_P (fun))
- {
- tree x = get_nth_callarg (t, 0);
- if (is_this_parameter (x))
- return true;
- /* Don't require an immediately constant value, as
- constexpr substitution might not use the value. */
- bool sub_now = false;
- if (!potential_constant_expression_1 (x, rval, strict,
- sub_now, fundef_p,
- flags, jump_target))
- return false;
- i = 1;
- }
- }
- else
- {
- if (!RECUR (fun, true))
- return false;
- fun = get_first_fn (fun);
}
+
+ fun = OVL_FIRST (fun);
/* Skip initial arguments to base constructors. */
if (DECL_BASE_CONSTRUCTOR_P (fun))
i = num_artificial_parms_for (fun);
- fun = DECL_ORIGIN (fun);
}
else if (fun)
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept59.C b/gcc/testsuite/g++.dg/cpp0x/noexcept59.C
index c752601..1dc826d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/noexcept59.C
+++ b/gcc/testsuite/g++.dg/cpp0x/noexcept59.C
@@ -3,7 +3,7 @@
template <class ...Ts> class A
{
- void e ();
+ constexpr bool e () { return true; };
bool f (int() noexcept(this->e())); // { dg-error "this" }
bool g (int() noexcept(e())); // { dg-error "without object" }
};
diff --git a/gcc/testsuite/g++.dg/template/non-dependent25.C b/gcc/testsuite/g++.dg/template/non-dependent25.C
new file mode 100644
index 0000000..c00e445
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent25.C
@@ -0,0 +1,14 @@
+// PR c++/109480
+
+template<class T>
+struct A {
+ void f() {
+ A<int> a;
+ const bool b = a.g(); // { dg-bogus "private" }
+ }
+
+private:
+ bool g() const;
+};
+
+template struct A<int>;