This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: C++: taking address of const object with non-const operator&


On May 17, 2002, Jason Merrill <jason@redhat.com> wrote:

>>>>>> "Alexandre" == Alexandre Oliva <aoliva@redhat.com> writes:
>> Yet another error condition whose testcase I'm not allowed to
>> contribute :-(

> If you can't contribute the original testcase, then create a new
> one.  Or if you're worried about contamination, ask someone else to.

This is exactly what I'm doing by posting the description.  Sorry if
this was not clear.

> Here, I'll write you a new testcase for this bug:

Thanks.  I've included it in the patch below.

> No, -fpermissive should not change behavior.

I see.

> Rather, we should always reject bad candidates for op&, op-> and
> op,.

I don't see the point of rejecting candidates for `op->'.  It's not
like there would ever be a built-in operand that would match, so it
appears to me that the extension is safe in this case.  Am I missing
anything, or is this patch ok to install?  Tested on
athlon-pc-linux-gnu.

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>
	* call.c (any_strictly_viable): New.
	(build_new_op): Use it for COMPOUND_EXPR and ADDR_EXPRs.

Index: gcc/cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.318
diff -u -p -r1.318 call.c
--- gcc/cp/call.c 19 Apr 2002 06:22:13 -0000 1.318
+++ gcc/cp/call.c 19 May 2002 09:10:21 -0000
@@ -62,6 +62,7 @@ static void print_z_candidates PARAMS ((
 static tree build_this PARAMS ((tree));
 static struct z_candidate * splice_viable PARAMS ((struct z_candidate *));
 static int any_viable PARAMS ((struct z_candidate *));
+static int any_strictly_viable PARAMS ((struct z_candidate *));
 static struct z_candidate * add_template_candidate
 	PARAMS ((struct z_candidate *, tree, tree, tree, tree, tree, int,
 	       unification_kind_t));
@@ -2319,6 +2320,16 @@ any_viable (cands)
   return 0;
 }
 
+static int
+any_strictly_viable (cands)
+     struct z_candidate *cands;
+{
+  for (; cands; cands = cands->next)
+    if (cands->viable == 1)
+      return 1;
+  return 0;
+}
+
 static struct z_candidate *
 splice_viable (cands)
      struct z_candidate *cands;
@@ -3228,6 +3239,7 @@ build_new_op (code, flags, arg1, arg2, a
   enum tree_code code2 = NOP_EXPR;
   tree templates = NULL_TREE;
   tree conv;
+  bool viable_candidates;
 
   if (arg1 == error_mark_node
       || arg2 == error_mark_node
@@ -3392,7 +3404,25 @@ build_new_op (code, flags, arg1, arg2, a
       (candidates, code, code2, fnname, args, flags);
   }
 
-  if (! any_viable (candidates))
+  switch (code)
+    {
+    case COMPOUND_EXPR:
+    case ADDR_EXPR:
+      /* For these, the built-in candidates set is empty
+	 [over.match.oper]/3.  We don't want non-strict matches
+	 because exact matches are always possible with built-in
+	 operators.  The built-in candidate set for COMPONENT_REF
+	 would be empty too, but since there are no such built-in
+	 operators, we accept non-strict matches for them.  */
+      viable_candidates = any_strictly_viable (candidates);
+      break;
+
+    default:
+      viable_candidates = any_viable (candidates);
+      break;
+    }      
+
+  if (! viable_candidates)
     {
       switch (code)
 	{
Index: gcc/testsuite/ChangeLog
2002-05-19  Jason Merrill  <jason2redhat.com>

	* g++.dg/ext/oper1.C: New test.

from  David Billinghurst <David.Billinghurst@riotinto.com>
Index: gcc/testsuite/g++.dg/ext/oper1.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/oper1.C
diff -N gcc/testsuite/g++.dg/ext/oper1.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/testsuite/g++.dg/ext/oper1.C 19 May 2002 09:10:27 -0000
@@ -0,0 +1,19 @@
+// { dg-do run }
+
+// Copyright 2002 Free Software Foundation
+// Contributed by Jason Merrill <jason@redhat.com>
+
+// Make sure the GNU extension of accepting dropping cv-qualifiers for
+// the implicit this argument does not kick in when taking the address
+// of an object, since this extension would change the meaning of a
+// well-defined program.
+
+struct A {
+  A* operator&() { return 0; }
+};
+
+int main ()
+{
+  const A a = {};
+  return (&a == 0);
+}

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]