diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bbb22f67a1c..ba552234ac4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 1998-10-04 Mark Mitchell + * call.c (build_over_call): Make pedwarns about dropped qualifiers + into full-fledged errors. + * cvt.c (convert_to_reference): Likewise. + * typeck.c (convert_for_assignment): Likewise. + * search.c (expand_upcast_vtables): In addition to unsetting TREE_READONLY, remove top-level const type qualifier. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index adec61c6014..808c11b4c2e 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3297,8 +3297,8 @@ build_over_call (cand, args, flags) char *p = (dv && dc ? "const and volatile" : dc ? "const" : dv ? "volatile" : ""); - cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s", - TREE_TYPE (argtype), fn, p); + cp_error ("passing `%T' as `this' argument of `%#D' discards %s", + TREE_TYPE (argtype), fn, p); } /* [class.mfct.nonstatic]: If a nonstatic member function of a class X is called for an object that is not of type X, or of a type diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 06c5290c424..f2b41d80b14 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -450,24 +450,34 @@ convert_to_reference (reftype, expr, convtype, flags, decl) tree ttl = TREE_TYPE (reftype); tree ttr = lvalue_type (expr); - if (! real_lvalue_p (expr) && ! TYPE_READONLY (ttl)) + /* [dcl.init.ref] says that if an rvalue is used to + initialize a reference, then the reference must be to a + non-volatile const type. */ + if (! real_lvalue_p (expr) + && (!TYPE_READONLY (ttl) || TYPE_VOLATILE (ttl))) { - if (decl) - /* Ensure semantics of [dcl.init.ref] */ - cp_pedwarn ("initialization of non-const reference `%#T' from rvalue `%T'", - reftype, intype); + char* msg; + + if (TYPE_VOLATILE (ttl) && decl) + msg = "initialization of volatile reference type `%#T'"; + else if (TYPE_VOLATILE (ttl)) + msg = "conversion to volatile reference type `%#T'"; + else if (decl) + msg = "initialization of non-const reference type `%#T'"; else - cp_pedwarn ("conversion to non-const `%T' from rvalue `%T'", - reftype, intype); + msg = "conversion to non-const reference type `%#T'"; + + cp_error (msg, reftype); + cp_error ("from rvalue of type `%T'", intype); } else if (! (convtype & CONV_CONST)) { if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - cp_pedwarn ("conversion from `%T' to `%T' discards const", - ttr, reftype); + cp_error ("conversion from `%T' to `%T' discards const", + ttr, reftype); else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - cp_pedwarn ("conversion from `%T' to `%T' discards volatile", - ttr, reftype); + cp_error ("conversion from `%T' to `%T' discards volatile", + ttr, reftype); } } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index d0be08addad..9e2c1232743 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6808,20 +6808,20 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) { if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards const", - rhstype, parmnum, fndecl); + cp_error ("passing `%T' as argument %P of `%D' discards const", + rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards const", - errtype, type, rhstype); + cp_error ("%s to `%T' from `%T' discards const", + errtype, type, rhstype); } if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) { if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile", - rhstype, parmnum, fndecl); + cp_error ("passing `%T' as argument %P of `%D' discards volatile", + rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards volatile", - errtype, type, rhstype); + cp_error ("%s to `%T' from `%T' discards volatile", + errtype, type, rhstype); } } @@ -6874,19 +6874,19 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) if (string_conv_p (type, rhs, 1)) /* converting from string constant to char *, OK. */; else if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards const", - rhstype, parmnum, fndecl); + cp_error ("passing `%T' as argument %P of `%D' discards const", + rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards const", + cp_error ("%s to `%T' from `%T' discards const", errtype, type, rhstype); } else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) { if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile", + cp_error ("passing `%T' as argument %P of `%D' discards volatile", rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards volatile", + cp_error ("%s to `%T' from `%T' discards volatile", errtype, type, rhstype); } else if (TREE_CODE (ttl) == TREE_CODE (ttr) @@ -6948,20 +6948,20 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum) if (const_parity) { if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards const", - rhstype, parmnum, fndecl); + cp_error ("passing `%T' as argument %P of `%D' discards const", + rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards const", + cp_error ("%s to `%T' from `%T' discards const", errtype, type, rhstype); } if (volatile_parity) { if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards volatile", - rhstype, parmnum, fndecl); + cp_error ("passing `%T' as argument %P of `%D' discards volatile", + rhstype, parmnum, fndecl); else - cp_pedwarn ("%s to `%T' from `%T' discards volatile", - errtype, type, rhstype); + cp_error ("%s to `%T' from `%T' discards volatile", + errtype, type, rhstype); } if (unsigned_parity > 0) { diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash39.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash39.C index 67f5538756b..a19187295ec 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/crash39.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash39.C @@ -29,5 +29,5 @@ public: #include class foo {public: foo () {}}; -class bar {public: bar (foo& dflt);}; +class bar {public: bar (const foo& dflt);}; class baz: public bar {public: baz (): bar (foo ()) {}}; diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/reference1.C b/gcc/testsuite/g++.old-deja/g++.brendan/reference1.C index 2a0c2939e4f..84ad6f4bf20 100644 --- a/gcc/testsuite/g++.old-deja/g++.brendan/reference1.C +++ b/gcc/testsuite/g++.old-deja/g++.brendan/reference1.C @@ -12,10 +12,10 @@ extern "C" void printf (char *, ...); struct base { - int data_member; + mutable int data_member; base () {} - void function_member (); + void function_member () const; }; base base_object; @@ -26,7 +26,7 @@ int call_count = 0; int main () { - base& base_ref = base_returning_function (); + const base& base_ref = base_returning_function (); base_ref.function_member (); base_ref.function_member (); @@ -48,6 +48,6 @@ base base_returning_function () return local_base_object; } -void base::function_member () +void base::function_member () const { } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p785.C b/gcc/testsuite/g++.old-deja/g++.mike/p785.C index 2188707cade..7d61b093edd 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/p785.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/p785.C @@ -6883,7 +6883,8 @@ and this notice must be preserved on all copies. typedef void (*GctNameRefProcedure)(GctNameRef&); typedef GctNameRef (*GctNameRefMapper)(GctNameRef&); -typedef GctNameRef (*GctNameRefCombiner)(GctNameRef&, GctNameRef&); +typedef GctNameRef& (*GctNameRefCombiner)(const GctNameRef&, + const GctNameRef&); typedef int (*GctNameRefPredicate)(GctNameRef&); typedef int (*GctNameRefComparator)(GctNameRef&, GctNameRef&); @@ -6916,11 +6917,11 @@ public: GctNameRefList(); GctNameRefList(GctNameRef& head); GctNameRefList(GctNameRef& head, GctNameRefList& tl); - GctNameRefList(GctNameRefList& a); + GctNameRefList(const GctNameRefList& a); GctNameRefList(Pix p); ~GctNameRefList(); - GctNameRefList& operator = (GctNameRefList& a); + GctNameRefList& operator = (const GctNameRefList& a); int null(); int valid(); @@ -7003,11 +7004,11 @@ inline void dereference(GctNameRefListNode* p) } -inline GctNameRefListNode* newGctNameRefListNode(GctNameRef& h) +inline GctNameRefListNode* newGctNameRefListNode(const GctNameRef& h) { GctNameRefListNode* p = new GctNameRefListNode; p->ref = 1; - p->hd = h; + p->hd = (GctNameRef&) h; return p; } @@ -7048,9 +7049,10 @@ inline GctNameRefList::GctNameRefList(GctNameRef& head, GctNameRefList& tl) reference(P->tl); } -inline GctNameRefList::GctNameRefList(GctNameRefList& a) +inline GctNameRefList::GctNameRefList(const GctNameRefList& a) { - reference(a.P); + GctNameRefList& gl = (GctNameRefList&) a; + reference(gl.P); P = a.P; } @@ -7151,7 +7153,7 @@ public: static init_NilGctNameRefListNode NilGctNameRefListNode_initializer; -GctNameRefList& GctNameRefList::operator = (GctNameRefList& a) +GctNameRefList& GctNameRefList::operator = (const GctNameRefList& a) { reference(a.P); dereference(P); diff --git a/gcc/testsuite/g++.old-deja/g++.other/ref1.C b/gcc/testsuite/g++.old-deja/g++.other/ref1.C new file mode 100644 index 00000000000..b6d82aa25ca --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/ref1.C @@ -0,0 +1,10 @@ +// Build don't link: + +int f(); + +void g() +{ + const int& i = f(); // OK + int& j = f(); // ERROR - initialization of non-const reference + const volatile int& k = f(); // ERROR - initialization of volatile ref +}