re PR c++/3624 (Internal error: Segmentation fault)
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 26 Jul 2001 08:12:00 +0000 (08:12 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 26 Jul 2001 08:12:00 +0000 (08:12 +0000)
cp:
PR c++/3624
* call.c (resolve_args): Simplify, call
convert_from_reference.
(build_new_op): Resolve and convert from reference ARG1
earlier. Adjust ARG2 & ARG3 resolve and conversion.
testsuite:
* g++.old-deja/g++.pt/crash68.C: New test.

From-SVN: r44388

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.pt/crash68.C [new file with mode: 0644]

index 70c9bd3..949dd82 100644 (file)
@@ -1,5 +1,13 @@
 2001-07-26  Nathan Sidwell  <nathan@codesourcery.com>
 
+       PR c++/3624
+       * call.c (resolve_args): Simplify, call
+       convert_from_reference.
+       (build_new_op): Resolve and convert from reference ARG1
+       earlier. Adjust ARG2 & ARG3 resolve and conversion.
+
+2001-07-26  Nathan Sidwell  <nathan@codesourcery.com>
+
        * decl.c (last_function_parm_tags): Remove.
        (current_function_parm_tags): Remove.
        (init_decl_processing): Adjust.
index 268cc27..bbe6c48 100644 (file)
@@ -2556,15 +2556,19 @@ resolve_args (args)
   tree t;
   for (t = args; t; t = TREE_CHAIN (t))
     {
-      if (TREE_VALUE (t) == error_mark_node)
+      tree arg = TREE_VALUE (t);
+      
+      if (arg == error_mark_node)
        return error_mark_node;
-      else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE)
+      else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
          error ("invalid use of void expression");
          return error_mark_node;
        }
-      else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF)
-       TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t));
+      else if (TREE_CODE (arg) == OFFSET_REF)
+       arg = resolve_offset_ref (arg);
+      arg = convert_from_reference (arg);
+      TREE_VALUE (t) = arg;
     }
   return args;
 }
@@ -3220,6 +3224,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
   else
     fnname = ansi_opname (code);
 
+  if (TREE_CODE (arg1) == OFFSET_REF)
+    arg1 = resolve_offset_ref (arg1);
+  arg1 = convert_from_reference (arg1);
+  
   switch (code)
     {
     case NEW_EXPR:
@@ -3236,19 +3244,18 @@ build_new_op (code, flags, arg1, arg2, arg3)
       break;
     }
 
-  /* The comma operator can have void args.  */
-  if (TREE_CODE (arg1) == OFFSET_REF)
-    arg1 = resolve_offset_ref (arg1);
-  if (arg2 && TREE_CODE (arg2) == OFFSET_REF)
-    arg2 = resolve_offset_ref (arg2);
-  if (arg3 && TREE_CODE (arg3) == OFFSET_REF)
-    arg3 = resolve_offset_ref (arg3);
-
-  arg1 = convert_from_reference (arg1);
   if (arg2)
-    arg2 = convert_from_reference (arg2);
+    {
+      if (TREE_CODE (arg2) == OFFSET_REF)
+       arg2 = resolve_offset_ref (arg2);
+      arg2 = convert_from_reference (arg2);
+    }
   if (arg3)
-    arg3 = convert_from_reference (arg3);
+    {
+      if (TREE_CODE (arg3) == OFFSET_REF)
+       arg3 = resolve_offset_ref (arg3);
+      arg3 = convert_from_reference (arg3);
+    }
   
   if (code == COND_EXPR)
     {
index c06c779..55f597f 100644 (file)
@@ -1,5 +1,9 @@
 2001-07-26  Nathan Sidwell  <nathan@codesourcery.com>
 
+       * g++.old-deja/g++.pt/crash68.C: New test.
+
+2001-07-26  Nathan Sidwell  <nathan@codesourcery.com>
+
        * g++.old-deja/g++.other/crash42.C: New test.
 
 2001-07-26  Neil Booth  <neil@cat.daikokuya.demon.co.uk>
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash68.C b/gcc/testsuite/g++.old-deja/g++.pt/crash68.C
new file mode 100644 (file)
index 0000000..b856f22
--- /dev/null
@@ -0,0 +1,70 @@
+// Build don't link:
+// 
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 25 Jul 2001 <nathan@codesourcery.com>
+
+// Origin: gustavo@geneura.ugr.es
+// Bug 3624. Template instantiation of a reference type was not
+// converted from reference when doing a call.
+
+#include <iostream>
+
+using namespace std;
+
+template <class A, class B, class C, C& c, bool d> class eo: public A
+{
+public:
+  eo() 
+  {
+    cout << this->x << " " << this->y << " "
+        << c(*this) << " "
+        << ((d)?"true":"false") << endl;
+  }
+  
+private:
+  B b;
+};
+
+struct XY
+{
+  float x, y;
+
+  XY(): x(1), y(0.1) {}
+};
+
+float fitness(const XY& a)
+{
+  return a.x + a.y;
+}
+
+struct fitness2
+{
+  float operator()(const XY& a)
+  {
+    return a.x - a.y;
+  }
+  
+  float f(const XY& a)
+  {
+    return a.x - a.y;
+  }
+};
+
+struct fitness3
+{
+  float operator()(const XY& a)
+  {
+    return a.x / a.y;
+  }
+};
+
+fitness2 f2;
+fitness3 f3;
+
+int main()
+{
+  eo<XY, float, fitness2, f2, true> eo2;
+  eo<XY, float, fitness3, f3, true> eo3;
+
+  return 0;
+}