public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Simon Martin <simartin@users.sourceforge.net>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH] Fix PR c++/26698: g++ accepts const-incorrect code due to  conversion function
Date: Sun, 07 Oct 2007 19:49:00 -0000	[thread overview]
Message-ID: <4709385D.6020202@users.sourceforge.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 1359 bytes --]

Hi all.

This PR was opened because we would not handle the following snippet
properly:

=== cut here ===
struct X {
        int x;
        X ( int i = 0 )
          : x ( i )
        {}
        operator X & ( void ) const {
          return ( *this );
        }
};
void add_one ( X & ref ) {
        ++ ref.x;
}
int main ( void ) {
        X const a ( 2 );
        add_one( a );
}
=== cut here ===

At the time this PR was opened, we would accept it without complaining,
while there are two problems:
       1. The body of "operator X&" is invalid because it returns a
non-const reference to the const object it's called on.
       2. This operator should not be considered when calling add_one,
because the standard states that "A conversion function is never used to
convert a (possibly cv-qualified) object to the (possibly cv-qualified)
same object type (or a reference to it), to a (possibly cv-qualified)
base class of that type (or a reference to it)".

The first point is now properly rejected, but the second one is still
present.

The attached patch modifies build_user_type_conversion_1 so that
conversion operators are not considered when they should not according
to the standard.

I have successfully regtested it on i386-apple-darwin8.10.1. Is it OK
for the mainline? For 4.2 after 4.2.2 is released?

Best regards,
Simon

:ADDPATCH c++:






[-- Attachment #2: CL_26698 --]
[-- Type: text/plain, Size: 354 bytes --]

2007-10-07  Simon Martin  <simartin@users.sourceforge.net>

	PR c++/26698
	* call.c (build_user_type_conversion_1): Do not consider conversion
	functions to convert a (possibly cv-qualified) object to the (possibly
	cv-qualified) same object type (or a reference to it), to a (possibly
	cv-qualified) base class of that type (or a reference to it).






[-- Attachment #3: pr26698.patch --]
[-- Type: text/plain, Size: 1065 bytes --]

Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 129069)
+++ gcc/cp/call.c	(working copy)
@@ -2601,7 +2601,22 @@ build_user_type_conversion_1 (tree totyp
     ctors = lookup_fnfields (totype, complete_ctor_identifier, 0);
 
   if (IS_AGGR_TYPE (fromtype))
-    conv_fns = lookup_conversions (fromtype);
+    {
+      tree to_main = TYPE_MAIN_VARIANT (non_reference (totype));
+      tree from_main = TYPE_MAIN_VARIANT (fromtype);
+      if (same_type_p (to_main, from_main) ||
+	  (CLASS_TYPE_P (to_main) && CLASS_TYPE_P (from_main)
+	   && DERIVED_FROM_P (to_main, from_main)))
+	{
+	  /* [class.conv.fct] A conversion function is never used to
+	     convert a (possibly cv-qualified) object to the (possibly
+	     cv-qualified) same object type (or a reference to it), to a
+	     (possibly cv-qualified) base class of that type (or a
+	     reference to it)...  */
+	}
+      else
+	conv_fns = lookup_conversions (fromtype);
+    }
 
   candidates = 0;
   flags |= LOOKUP_NO_CONVERSION;






[-- Attachment #4: CL_26698_testsuite --]
[-- Type: text/plain, Size: 117 bytes --]

2007-10-07  Simon Martin  <simartin@users.sourceforge.net>

	PR c++/26698
	* g++.dg/conversion/op4.C: New test.






[-- Attachment #5: op4.C --]
[-- Type: text/plain, Size: 348 bytes --]

/* PR c++/26698 */
/* { dg-do "compile" } */

struct X {
  int x;
  X (int i = 0) : x (i) {}
  operator X& (void) const {
    return *(new X);
  }
};

void add_one (X & ref) { /* { dg-error "in passing argument" } */
  ++ ref.x;
}

void foo() {
  X const a (2);
  add_one(a); /* { dg-error "invalid initialization of reference of type" } */
}






             reply	other threads:[~2007-10-07 19:49 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-07 19:49 Simon Martin [this message]
2007-10-10 17:04 ` Mark Mitchell
2007-10-12 18:48   ` Simon Martin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4709385D.6020202@users.sourceforge.net \
    --to=simartin@users.sourceforge.net \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).