Patchwork [C++] Fix c++/56243

login
register
mail settings
Submitter Jason Merrill
Date Feb. 28, 2013, 3:58 p.m.
Message ID <512F7EBA.4010704@redhat.com>
Download mbox | patch
Permalink /patch/224112/
State New
Headers show

Comments

Jason Merrill - Feb. 28, 2013, 3:58 p.m.
On 02/25/2013 06:25 PM, Jason Merrill wrote:
> On 02/25/2013 06:24 PM, Jason Merrill wrote:
>> I think my preference would be to avoid calling fixed_type_or_null at
>> all when we're in a template.  I already changed
>> resolves_to_fixed_type_p that way, now we need to fix build_vtbl_ref_1.
>
> Oops, now I see the discussion on the PR.  I'll take a look.

I'm applying this patch.  When we're in fold_non_dependent_expr we care 
about doing the right thing for possible constant-expressions, but a 
virtual function call can't be part of a constant-expression, so we 
don't need to worry about virtual lookup.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 8d561a71fbe141ad4d5b4f1ff9160e4f4c81a061
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Feb 26 10:06:31 2013 -0500

    	PR c++/56243
    	* call.c (build_over_call): Avoid virtual lookup in a template.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7c41421..4eb38ec 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7033,7 +7033,10 @@  build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
   if (!already_used)
     mark_used (fn);
 
-  if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0)
+  if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
+      /* Don't mess with virtual lookup in fold_non_dependent_expr; virtual
+	 functions can't be constexpr.  */
+      && !in_template_function ())
     {
       tree t;
       tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (argarray[0])),
diff --git a/gcc/testsuite/g++.dg/template/virtual4.C b/gcc/testsuite/g++.dg/template/virtual4.C
new file mode 100644
index 0000000..a2c7420b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/virtual4.C
@@ -0,0 +1,30 @@ 
+// PR c++/56243
+
+struct A
+{
+  virtual int String ();
+};
+
+struct F: A { };
+
+struct G
+{
+  F value;
+};
+
+struct D
+{
+  template <int>
+  void Verify()
+  {
+    G x;
+    F& name = x.value;
+    name.String();
+  }
+};
+
+int main()
+{
+  D d;
+  d.Verify<42>();
+}