]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/20332 (poor diagnostic when bind non lvalue to a reference for default...
authorJason Merrill <jason@redhat.com>
Wed, 14 May 2014 16:48:07 +0000 (12:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 14 May 2014 16:48:07 +0000 (12:48 -0400)
PR c++/20332
PR c++/21631
* call.c (reference_binding): Treat lvalue/rvalue mismatch and
dropped cv-quals as a bad conversion.
(convert_like_real) [ck_ref_bind]: Explain them.
(compare_ics): Check badness before stripping reference
bindings.  Handle comparing bad reference bindings.
* typeck.c (comp_cv_qualification): Add overload that just takes
integers.
* cp-tree.h: Declare it.

From-SVN: r210436

37 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/typeck.c
gcc/testsuite/g++.dg/conversion/op4.C
gcc/testsuite/g++.dg/cpp0x/diag2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/overloadn.C
gcc/testsuite/g++.dg/diagnostic/ref1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/ref2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/expr/cond9.C
gcc/testsuite/g++.dg/init/synth2.C
gcc/testsuite/g++.dg/lookup/two-stage4.C
gcc/testsuite/g++.dg/overload/arg3.C
gcc/testsuite/g++.dg/overload/conv-op1.C
gcc/testsuite/g++.dg/overload/copy1.C
gcc/testsuite/g++.dg/overload/volatile1.C
gcc/testsuite/g++.dg/rtti/dyncast6.C
gcc/testsuite/g++.dg/template/copy1.C
gcc/testsuite/g++.old-deja/g++.benjamin/15800-1.C
gcc/testsuite/g++.old-deja/g++.brendan/cvt3.C
gcc/testsuite/g++.old-deja/g++.bugs/900514_03.C
gcc/testsuite/g++.old-deja/g++.eh/ctor1.C
gcc/testsuite/g++.old-deja/g++.jason/temporary2.C
gcc/testsuite/g++.old-deja/g++.law/cvt20.C
gcc/testsuite/g++.old-deja/g++.law/enum4.C
gcc/testsuite/g++.old-deja/g++.law/init8.C
gcc/testsuite/g++.old-deja/g++.law/operators9.C
gcc/testsuite/g++.old-deja/g++.mike/net8.C
gcc/testsuite/g++.old-deja/g++.mike/p1989.C
gcc/testsuite/g++.old-deja/g++.mike/p2431.C
gcc/testsuite/g++.old-deja/g++.mike/p438.C
gcc/testsuite/g++.old-deja/g++.mike/p701.C
gcc/testsuite/g++.old-deja/g++.other/crash24.C
gcc/testsuite/g++.old-deja/g++.other/volatile1.C
gcc/testsuite/g++.old-deja/g++.pt/auto_ptr.C
gcc/testsuite/g++.old-deja/g++.pt/t05.C
libstdc++-v3/testsuite/20_util/forward/1_neg.cc

index bffe8bebf67c9112e1b86a7694374d9aa1fbe9e6..b24a7c112b4ffd661957203d3b279544247f0d66 100644 (file)
@@ -1,5 +1,16 @@
 2014-05-14  Jason Merrill  <jason@redhat.com>
 
+       PR c++/20332
+       PR c++/21631
+       * call.c (reference_binding): Treat lvalue/rvalue mismatch and
+       dropped cv-quals as a bad conversion.
+       (convert_like_real) [ck_ref_bind]: Explain them.
+       (compare_ics): Check badness before stripping reference
+       bindings.  Handle comparing bad reference bindings.
+       * typeck.c (comp_cv_qualification): Add overload that just takes
+       integers.
+       * cp-tree.h: Declare it.
+
        * call.c (struct conversion_info): Rename 'from_type' to 'from'.
        (arg_conversion_rejection, bad_arg_conversion_rejection)
        (explicit_conversion_rejection, template_conversion_rejection): Adjust.
index 1d9a15ce94ef66024f5f5442ad75718bce3ddff9..23fad8fc70b34f58708fc29805a6608a71880297 100644 (file)
@@ -1540,15 +1540,11 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
      [8.5.3/5 dcl.init.ref] is changed to also require direct bindings for
      const and rvalue references to rvalues of compatible class type.
      We should also do direct bindings for non-class xvalues.  */
-  if (compatible_p
-      && (is_lvalue
-         || (((CP_TYPE_CONST_NON_VOLATILE_P (to)
-               && !(flags & LOOKUP_NO_RVAL_BIND))
-              || TYPE_REF_IS_RVALUE (rto))
-             && (gl_kind
-                 || (!(flags & LOOKUP_NO_TEMP_BIND)
-                     && (CLASS_TYPE_P (from)
-                         || TREE_CODE (from) == ARRAY_TYPE))))))
+  if (related_p
+      && (gl_kind
+         || (!(flags & LOOKUP_NO_TEMP_BIND)
+             && (CLASS_TYPE_P (from)
+                 || TREE_CODE (from) == ARRAY_TYPE))))
     {
       /* [dcl.init.ref]
 
@@ -1603,6 +1599,16 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
           && !(flags & LOOKUP_PREFER_RVALUE))
        conv->bad_p = true;
 
+      /* Nor the reverse.  */
+      if (!is_lvalue && !TYPE_REF_IS_RVALUE (rto)
+         && (!CP_TYPE_CONST_NON_VOLATILE_P (to)
+             || (flags & LOOKUP_NO_RVAL_BIND))
+         && TREE_CODE (to) != FUNCTION_TYPE)
+       conv->bad_p = true;
+
+      if (!compatible_p)
+       conv->bad_p = true;
+
       return conv;
     }
   /* [class.conv.fct] A conversion function is never used to convert a
@@ -1647,24 +1653,6 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
      difference in top-level cv-qualification is subsumed by the
      initialization itself and does not constitute a conversion.  */
 
-  /* [dcl.init.ref]
-
-     Otherwise, the reference shall be an lvalue reference to a
-     non-volatile const type, or the reference shall be an rvalue
-     reference.  */
-  if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto))
-    return NULL;
-
-  /* [dcl.init.ref]
-
-     Otherwise, a temporary of type "cv1 T1" is created and
-     initialized from the initializer expression using the rules for a
-     non-reference copy initialization.  If T1 is reference-related to
-     T2, cv1 must be the same cv-qualification as, or greater
-     cv-qualification than, cv2; otherwise, the program is ill-formed.  */
-  if (related_p && !at_least_as_qualified_p (to, from))
-    return NULL;
-
   /* We're generating a temporary now, but don't bind any more in the
      conversion (specifically, don't slice the temporary returned by a
      conversion operator).  */
@@ -1710,6 +1698,24 @@ reference_binding (tree rto, tree rfrom, tree expr, bool c_cast_p, int flags,
   conv->need_temporary_p = true;
   conv->rvaluedness_matches_p = TYPE_REF_IS_RVALUE (rto);
 
+  /* [dcl.init.ref]
+
+     Otherwise, the reference shall be an lvalue reference to a
+     non-volatile const type, or the reference shall be an rvalue
+     reference.  */
+  if (!CP_TYPE_CONST_NON_VOLATILE_P (to) && !TYPE_REF_IS_RVALUE (rto))
+    conv->bad_p = true;
+
+  /* [dcl.init.ref]
+
+     Otherwise, a temporary of type "cv1 T1" is created and
+     initialized from the initializer expression using the rules for a
+     non-reference copy initialization.  If T1 is reference-related to
+     T2, cv1 must be the same cv-qualification as, or greater
+     cv-qualification than, cv2; otherwise, the program is ill-formed.  */
+  if (related_p && !at_least_as_qualified_p (to, from))
+    conv->bad_p = true;
+
   return conv;
 }
 
@@ -6334,12 +6340,20 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
 
        if (convs->bad_p && !next_conversion (convs)->bad_p)
          {
-           gcc_assert (TYPE_REF_IS_RVALUE (ref_type)
-                       && (real_lvalue_p (expr)
-                           || next_conversion(convs)->kind == ck_rvalue));
-
-           error_at (loc, "cannot bind %qT lvalue to %qT",
-                     TREE_TYPE (expr), totype);
+           tree extype = TREE_TYPE (expr);
+           if (TYPE_REF_IS_RVALUE (ref_type)
+               && real_lvalue_p (expr))
+             error_at (loc, "cannot bind %qT lvalue to %qT",
+                       extype, totype);
+           else if (!TYPE_REF_IS_RVALUE (ref_type) && !real_lvalue_p (expr)
+                    && !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
+             error_at (loc, "invalid initialization of non-const reference of "
+                       "type %qT from an rvalue of type %qT", totype, extype);
+           else if (!reference_compatible_p (TREE_TYPE (totype), extype))
+             error_at (loc, "binding %qT to reference of type %qT "
+                       "discards qualifiers", extype, totype);
+           else
+             gcc_unreachable ();
            maybe_print_user_conv_context (convs);
            if (fn)
              inform (input_location,
@@ -8230,6 +8244,12 @@ compare_ics (conversion *ics1, conversion *ics2)
   conversion *ref_conv1;
   conversion *ref_conv2;
 
+  /* Compare badness before stripping the reference conversion.  */
+  if (ics1->bad_p > ics2->bad_p)
+    return -1;
+  else if (ics1->bad_p < ics2->bad_p)
+    return 1;
+
   /* Handle implicit object parameters.  */
   maybe_handle_implicit_object (&ics1);
   maybe_handle_implicit_object (&ics2);
@@ -8258,31 +8278,19 @@ compare_ics (conversion *ics1, conversion *ics2)
      --a user-defined conversion sequence (_over.ics.user_) is a
        better conversion sequence than an ellipsis conversion sequence
        (_over.ics.ellipsis_).  */
-  rank1 = CONVERSION_RANK (ics1);
-  rank2 = CONVERSION_RANK (ics2);
+  /* Use BAD_CONVERSION_RANK because we already checked for a badness
+     mismatch.  If both ICS are bad, we try to make a decision based on
+     what would have happened if they'd been good.  This is not an
+     extension, we'll still give an error when we build up the call; this
+     just helps us give a more helpful error message.  */
+  rank1 = BAD_CONVERSION_RANK (ics1);
+  rank2 = BAD_CONVERSION_RANK (ics2);
 
   if (rank1 > rank2)
     return -1;
   else if (rank1 < rank2)
     return 1;
 
-  if (rank1 == cr_bad)
-    {
-      /* Both ICS are bad.  We try to make a decision based on what would
-        have happened if they'd been good.  This is not an extension,
-        we'll still give an error when we build up the call; this just
-        helps us give a more helpful error message.  */
-      rank1 = BAD_CONVERSION_RANK (ics1);
-      rank2 = BAD_CONVERSION_RANK (ics2);
-
-      if (rank1 > rank2)
-       return -1;
-      else if (rank1 < rank2)
-       return 1;
-
-      /* We couldn't make up our minds; try to figure it out below.  */
-    }
-
   if (ics1->ellipsis_p)
     /* Both conversions are ellipsis conversions.  */
     return 0;
@@ -8602,13 +8610,30 @@ compare_ics (conversion *ics1, conversion *ics2)
              || (TYPE_REF_IS_RVALUE (ref_conv1->type)
                  != TYPE_REF_IS_RVALUE (ref_conv2->type))))
        {
+         if (ref_conv1->bad_p
+             && !same_type_p (TREE_TYPE (ref_conv1->type),
+                              TREE_TYPE (ref_conv2->type)))
+           /* Don't prefer a bad conversion that drops cv-quals to a bad
+              conversion with the wrong rvalueness.  */
+           return 0;
          return (ref_conv1->rvaluedness_matches_p
                  - ref_conv2->rvaluedness_matches_p);
        }
 
       if (same_type_ignoring_top_level_qualifiers_p (to_type1, to_type2))
-       return comp_cv_qualification (TREE_TYPE (ref_conv2->type),
-                                     TREE_TYPE (ref_conv1->type));
+       {
+         int q1 = cp_type_quals (TREE_TYPE (ref_conv1->type));
+         int q2 = cp_type_quals (TREE_TYPE (ref_conv2->type));
+         if (ref_conv1->bad_p)
+           {
+             /* Prefer the one that drops fewer cv-quals.  */
+             tree ftype = next_conversion (ref_conv1)->type;
+             int fquals = cp_type_quals (ftype);
+             q1 ^= fquals;
+             q2 ^= fquals;
+           }
+         return comp_cv_qualification (q2, q1);
+       }
     }
 
   /* Neither conversion sequence is better than the other.  */
index ed8d099bda88b21c4f8416be37e3c5deab5d86c6..f3788a72d5ccf4bf015c498480816709a9ed5817 100644 (file)
@@ -6034,6 +6034,7 @@ extern bool comptypes                             (tree, tree, int);
 extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree);
 extern bool compparms                          (const_tree, const_tree);
 extern int comp_cv_qualification               (const_tree, const_tree);
+extern int comp_cv_qualification               (int, int);
 extern int comp_cv_qual_signature              (tree, tree);
 extern tree cxx_sizeof_or_alignof_expr         (tree, enum tree_code, bool);
 extern tree cxx_sizeof_or_alignof_type         (tree, enum tree_code, bool);
index b933b96fc3e53ef93c706cc579cbb45bc45a28dd..7420da42ede5f732a4dd5b9d2a7a235f24292b48 100644 (file)
@@ -1452,11 +1452,8 @@ at_least_as_qualified_p (const_tree type1, const_tree type2)
    more cv-qualified that TYPE1, and 0 otherwise.  */
 
 int
-comp_cv_qualification (const_tree type1, const_tree type2)
+comp_cv_qualification (int q1, int q2)
 {
-  int q1 = cp_type_quals (type1);
-  int q2 = cp_type_quals (type2);
-
   if (q1 == q2)
     return 0;
 
@@ -1468,6 +1465,14 @@ comp_cv_qualification (const_tree type1, const_tree type2)
   return 0;
 }
 
+int
+comp_cv_qualification (const_tree type1, const_tree type2)
+{
+  int q1 = cp_type_quals (type1);
+  int q2 = cp_type_quals (type2);
+  return comp_cv_qualification (q1, q2);
+}
+
 /* Returns 1 if the cv-qualification signature of TYPE1 is a proper
    subset of the cv-qualification signature of TYPE2, and the types
    are similar.  Returns -1 if the other way 'round, and 0 otherwise.  */
index 7ef4b6a0c6d16f699abda34ecc973110d16e2023..cb99a380b43215dd1e9a9489a5699b831673c755 100644 (file)
@@ -9,11 +9,11 @@ struct X {
   }
 };
 
-void add_one (X & ref) { /* { dg-message "in passing argument" } */
+void add_one (X & ref) { /* { dg-message "argument" } */
   ++ ref.x;
 }
 
 void foo() {
   X const a (2);
-  add_one(a); /* { dg-error "invalid initialization of reference of type" } */
+  add_one(a); /* { dg-error "discards qualifiers" } */
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/diag2.C b/gcc/testsuite/g++.dg/cpp0x/diag2.C
new file mode 100644 (file)
index 0000000..0d01b1d
--- /dev/null
@@ -0,0 +1,19 @@
+// { dg-do compile { target c++11 } }
+
+struct A {};
+
+// We shouldn't arbitarily choose which of these is better.
+void f (A&);
+void f (const A&&);
+
+// But do prefer the lvalue overload here.
+void g (A&);
+void g (A&&);
+int main()
+{
+  const A a;
+  f(a);                                // { dg-error "no match" }
+  // { dg-error "qualifiers" "" { target *-*-* } 15 }
+  // { dg-error "lvalue" "" { target *-*-* } 15 }
+  g(a);                                // { dg-error "qualifiers" }
+}
index 16c39a9ed372ebbb242e9f08a2609365b206601a..243f83be73e9d3c5730c2ed852a33a0b63d3dd39 100644 (file)
@@ -543,9 +543,9 @@ void ucr1111(const S&&) {}
 
 int main()
 {
-  l0001(l); // { dg-error "lvalue" }
-  l0010(l); // { dg-error "lvalue" }
-  l0011(l); // { dg-error "lvalue" }
+  l0001(l); // { dg-error "" }
+  l0010(l); // { dg-error "" }
+  l0011(l); // { dg-error "" }
   l0100(l);
   l0101(l);
   l0110(l);
@@ -564,8 +564,8 @@ int main()
   cl0101(cl);
   cl0110(cl);
   cl0111(cl);
-  cl1001(cl); // { dg-error "lvalue" }
-  cl1011(cl); // { dg-error "lvalue" }
+  cl1001(cl); // { dg-error "" }
+  cl1011(cl); // { dg-error "" }
   cl1100(cl);
   cl1101(cl);
   cl1110(cl);
@@ -617,8 +617,8 @@ int main()
   ncl0101(ncl);
   ncl0110(ncl);
   ncl0111(ncl);
-  ncl1001(ncl); // { dg-error "lvalue" }
-  ncl1011(ncl); // { dg-error "lvalue" }
+  ncl1001(ncl); // { dg-error "" }
+  ncl1011(ncl); // { dg-error "" }
   ncl1100(ncl);
   ncl1101(ncl);
   ncl1110(ncl);
@@ -644,8 +644,8 @@ int main()
   ncr0101(ncr);
   ncr0110(ncr);
   ncr0111(ncr);
-  ncr1001(ncr); // { dg-error "lvalue" }
-  ncr1011(ncr); // { dg-error "lvalue" }
+  ncr1001(ncr); // { dg-error "" }
+  ncr1011(ncr); // { dg-error "" }
   ncr1100(ncr);
   ncr1101(ncr);
   ncr1110(ncr);
@@ -671,8 +671,8 @@ int main()
   ucl0101(ucl());
   ucl0110(ucl());
   ucl0111(ucl());
-  ucl1001(ucl()); // { dg-error "lvalue" }
-  ucl1011(ucl()); // { dg-error "lvalue" }
+  ucl1001(ucl()); // { dg-error "" }
+  ucl1011(ucl()); // { dg-error "" }
   ucl1100(ucl());
   ucl1101(ucl());
   ucl1110(ucl());
diff --git a/gcc/testsuite/g++.dg/diagnostic/ref1.C b/gcc/testsuite/g++.dg/diagnostic/ref1.C
new file mode 100644 (file)
index 0000000..36368de
--- /dev/null
@@ -0,0 +1,7 @@
+// PR c++/20332
+
+struct bar {};
+void foo1() {
+  bar& b = bar();              // { dg-error "rvalue" }
+}
+void foo(bar& b = bar()) {}    // { dg-error "rvalue" }
diff --git a/gcc/testsuite/g++.dg/diagnostic/ref2.C b/gcc/testsuite/g++.dg/diagnostic/ref2.C
new file mode 100644 (file)
index 0000000..ded35e0
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/21631
+
+int f(int&);
+int f();
+
+int g(void)
+{
+  return f(1);                 // { dg-error "rvalue" }
+}
index e71a84ba43e22216ea930e1ec3c3f415ec28297c..b344c1f683a1e3c6fda6794f4c51f5243e4f64f7 100644 (file)
@@ -1,10 +1,10 @@
 // PR c++/27666
 
 struct A { // { dg-message "A" }
-  A(int); // { dg-message "A" }
+  A(int);
 };
 
 void foo(volatile A a) { 
-  1 ? a : 0; // { dg-error "match|temporary" }
-  1 ? 0 : a; // { dg-error "match|temporary" }
+  1 ? a : 0; // { dg-error "qualifiers|lvalue|no match" }
+  1 ? 0 : a; // { dg-error "qualifiers|lvalue|no match" }
 } 
index 9e8a08a6ea3bea7eec3e0963828b7073bca61fd5..cc6cce0e4a1b206c05ff7ef1ad590d04c39ec7b5 100644 (file)
@@ -1,7 +1,7 @@
 // PR c++/34180
 
 struct G {
-  G();                         // { dg-message "" "candidate" }
+  G();
   G(G&);                       // { dg-message "" "candidate" }
 };
 
index bbb44afa0d0faf9c89460d1fa075f7d325bf7ed3..7d971094d1a3554f1c3594fc3d04796af8d68cdc 100644 (file)
@@ -3,15 +3,15 @@
 
 template<class T> struct wrap {};
 
-template<typename T> bool& operator==(wrap<T>, wrap<T>);
+template<typename T> bool operator==(wrap<T>, wrap<T>);
 
 template<typename T>
 void g(T, wrap<wrap<int> > x)
 {
-  bool& b = x == x; // { dg-bogus "invalid initialization of reference" "" { xfail *-*-*} }
+  bool b = x == x; // { dg-bogus "" "" { xfail *-*-* } }
 }
 
-template<typename T> int& operator==(wrap<wrap<T> >, wrap<wrap<T> >);
+template<typename T> void operator==(wrap<wrap<T> >, wrap<wrap<T> >);
 
 void h()
 {
index b4fd2b7840a753582e7531197144373d8c667330..1684fccf5c73033e6a21d2078ab438ea2a78c3eb 100644 (file)
@@ -10,7 +10,7 @@ struct A {};
 
 struct B : A
 {
-  B(int); // { dg-message "B::B|no known conversion" "" }
+  B(int);
   B(B&);  // { dg-message "note" "" }
 };
 
@@ -18,5 +18,5 @@ void foo(B);                  // { dg-message "initializing" }
 
 void bar()
 {
-  foo(0); // { dg-error "no matching function" "no matching" }
+  foo(0); // { dg-error "" }
 }
index 6a63cbaeb87d629abab9aa9a0cf3da9aab1474fb..cd8d9f481ec60140d27761242291d62286c2245b 100644 (file)
@@ -11,7 +11,7 @@ void f()
 {
   const int i = 42;
   A()(i);                      // { dg-message "<conversion>" }
+  // { dg-error "qualifiers" "" { target *-*-* } 13 }
 }
 
 // { dg-prune-output "no match" }
-// { dg-prune-output "candidate" }
index f776a06c7ae120ea38a0ce6981c5f472585768f2..5c7922f8330058aba7b90e0c362524b0b70b178c 100644 (file)
@@ -4,7 +4,7 @@ struct A;
 
 struct B
 {
-  B (A const &);               // { dg-message "note" }
+  B (A const &);
   B (B &);                     // { dg-message "note" }
 };
 
@@ -16,5 +16,5 @@ struct A
 B
 f (B const& b)
 {
-  return b;                    // { dg-error "matching" "matching" }
+  return b;                    // { dg-error "" }
 }
index 29f649f3af27a35eb2bbfa5e2ac9c6f2b032134b..0426b8f361d423d61a3dfd481dff42f2b475b93d 100644 (file)
@@ -1,5 +1,4 @@
 // PR c++/48118
-// { dg-prune-output "note" }
 
 struct A { };
 
@@ -9,6 +8,6 @@ void (*g)(A);
 int main()
 {
   volatile A a;
-  f(a);                                // { dg-error "no match" }
-  g(a);                                // { dg-error "no match" }
+  f(a);                                // { dg-error "" }
+  g(a);                                // { dg-error "" }
 }
index a6329e9441c2a1bff1cd5ac75e782c8ffcaa23a3..bfbf5117dd1aae5755a33d7778a88cf3e1243151 100644 (file)
@@ -38,19 +38,19 @@ void r()
   B b;
 
   A& a1 = dynamic_cast<A&>(b);
-  A& a2 = dynamic_cast<const A&>(b);                // { dg-error "invalid" }
-  A& a3 = dynamic_cast<volatile A&>(b);             // { dg-error "invalid" }
-  A& a4 = dynamic_cast<const volatile A&>(b);       // { dg-error "invalid" }
+  A& a2 = dynamic_cast<const A&>(b);                // { dg-error "" }
+  A& a3 = dynamic_cast<volatile A&>(b);             // { dg-error "" }
+  A& a4 = dynamic_cast<const volatile A&>(b);       // { dg-error "" }
 
   const A& ca1 = dynamic_cast<A&>(b);
   const A& ca2 = dynamic_cast<const A&>(b);
-  const A& ca3 = dynamic_cast<volatile A&>(b);       // { dg-error "invalid" }
-  const A& ca4 = dynamic_cast<const volatile A&>(b); // { dg-error "invalid" }
+  const A& ca3 = dynamic_cast<volatile A&>(b);       // { dg-error "" }
+  const A& ca4 = dynamic_cast<const volatile A&>(b); // { dg-error "" }
 
   volatile A& va1 = dynamic_cast<A&>(b);
-  volatile A& va2 = dynamic_cast<const A&>(b);       // { dg-error "invalid" }
+  volatile A& va2 = dynamic_cast<const A&>(b);       // { dg-error "" }
   volatile A& va3 = dynamic_cast<volatile A&>(b);
-  volatile A& va4 = dynamic_cast<const volatile A&>(b);// { dg-error "invalid" }
+  volatile A& va4 = dynamic_cast<const volatile A&>(b);// { dg-error "" }
 
   const volatile A& cva1 = dynamic_cast<A&>(b);
   const volatile A& cva2 = dynamic_cast<const A&>(b);
index 6f5fa00f97cfbefe5fb6e2673a791c23d0069b20..bf5a37ce0ab63404d6dacde50c8ac0ecccfb846e 100644 (file)
@@ -6,9 +6,9 @@
 
 struct A
 {
-  A(A&); // { dg-message "note" }
-  template <class T> A(T);     // { dg-message "note" }
+  A(A&);                       // { dg-message "A::A" }
+  template <class T> A(T);     // { dg-message "A::A" }
 };
 
-A a = 0; // { dg-error "no matching function" }
+A a = 0; // { dg-error "" }
 
index 88d829ded8b6f18fd7000b3d35f8e6b9396edc8e..5f2fe1047cdcf6e851632bc918f5c2b5fee346fb 100644 (file)
@@ -12,6 +12,6 @@ extern panama dig();
 
 void foo() {
    panama obj;
-   obj = dig(); // { dg-error "no match" }
+   obj = dig(); // { dg-error "rvalue" }
 }
 
index 79b001308f00c1e63bdeae355d10e2bc59a24d83..8b253a10a1472e25599c5d5c879a5d72cdcef08b 100644 (file)
@@ -44,5 +44,5 @@ public:
 void
 foo (bar yylval, bar *yyvsp)
 {
-  nnyacc::assign(yylval.valueList, yyvsp[0].valueList);// { dg-error "no matching" } 
+  nnyacc::assign(yylval.valueList, yyvsp[0].valueList);// { dg-error "no matching|rvalue" }
 }
index 64223a45071ef06115c88066f8b4aa50b4e20d67..fc4d2108456fbd4b02b8d692d2c897eb939e6824 100644 (file)
@@ -71,8 +71,8 @@ void t_1_assignment ()
   t_1_st_1 t_1_st_1_obj1;
   t_1_st_1 t_1_st_1_obj2;
 
-  t_1_st_1_obj0 = t_1_st_0_obj0;                       // { dg-error "no match" } 
-  t_1_st_1_obj1 = t_1_st_1 (t_1_st_0_obj0);            // { dg-error "no match" } 
+  t_1_st_1_obj0 = t_1_st_0_obj0;                       // { dg-error "no match|conversion" }
+  t_1_st_1_obj1 = t_1_st_1 (t_1_st_0_obj0);            // { dg-error "no match|rvalue" }
 }
 
 void t_1_local_init ()
index 898f9e2e3e6fbb14faf401c33827dad4608c41f2..9b4adaf0e4a6027aa2ed3b153f90d1db7e92aea8 100644 (file)
@@ -1,7 +1,7 @@
 // { dg-do assemble  }
 struct A
 {
-  A();                         // { dg-message "A::A|candidate expects" } candidate
+  A();
   A(A&);                       // { dg-message "A::A|no known conversion" } referenced below
 };
 
@@ -10,7 +10,7 @@ main ()
 {
   try
     {
-      throw A();               // { dg-error "no matching" "match" } can't copy
+      throw A();               // { dg-error "rvalue" "" } can't copy
 // { dg-error "thrown expression" "expr" { target *-*-* } 13 }
     }
   catch (...) { }
index efd09fd06b18ef6325f7f9ff5601197f14fd3159..e55738477f22e0866cba819687c116552e9f88ee 100644 (file)
@@ -2,7 +2,7 @@
 class X // Indentation has been done so to see the similarities.
 {
 public:
-  X() {}                 // { dg-message "note" } referenced below
+  X() {}
          X(X& x) {x.i=7;} // { dg-message "note" } Both functions modify the
   void bar(X& x) {x.i=7;} // { dg-message "note" } reference parameter x.
   int i;
@@ -12,6 +12,6 @@ X foo() { X x; return x; }
 
 int main() 
 {
-  X   x(foo()); // { dg-error "no match" } Compiler doesn't warn about temporary reference.
-  x.bar(foo()); // { dg-error "no match" } The same mistake is warned about in this case.
+  X   x(foo()); // { dg-error "rvalue" } Compiler doesn't warn about temporary reference.
+  x.bar(foo()); // { dg-error "rvalue" } The same mistake is warned about in this case.
 }
index 9389a107ff7fc0ff0a2dd94bda56cf90cf31c07a..f5c703bccfd4fef190b9a964fb4f4c6d606b4716 100644 (file)
@@ -9,7 +9,7 @@
 
 // Compiles fine with Sun CC 2.1
 
-void f(char *& x) // { dg-message "passing argument" }
+void f(const char *& x) // { dg-message "argument" }
 {
   x++;
 }
index 2c36010107b53aa66910e12f559405e9a53de096..363f11493440407a30f21c2adb4e2e3e38b042f4 100644 (file)
@@ -24,6 +24,6 @@ int main()
   Enum e = enumerator1;
   Struct s;
   int x = funct(e+1);// { dg-error "invalid" }
-  int y = s.getI(e+1);// { dg-error "match|conv" }
+  int y = s.getI(e+1);// { dg-error "invalid" }
   return x+y;
 }
index 5ed619b670d93c10481f72d775dd336baf32deb5..829dd9be5a5f3b07aa569e15ff8d83e1d1c8598c 100644 (file)
@@ -8,7 +8,7 @@
 
 
 const int ic = 1;
-void f(int& arg)  // { dg-message "passing argument 1" }
+void f(int& arg)  // { dg-message "argument 1" }
 {
         if (arg) ;
 }
@@ -16,7 +16,7 @@ const int& icr = ic;
 
 int main(void)
 {
-  f(icr);   // { dg-error "invalid initialization" }
+  f(icr);   // { dg-error "const" }
 
   return 0;
 }
index 6c371636acd7e788ac81d73038831347ccae357c..8d5b686d9aeeb66f741e2e0e2ece674ed11c384c 100644 (file)
@@ -16,5 +16,5 @@ public:
 void
 test(B &b1, const B &b2)
 {
-        b1 = b2;// { dg-error "match" }
+        b1 = b2;// { dg-error "const" }
 }
index d1f6864513b160f9eda7d06e5b369574a706b044..6c2cd7f92dd6a81cd033023ce80c37b62b168933 100644 (file)
@@ -11,14 +11,14 @@ public:
   int bar;
 };
 
-void func(Base&);                      // { dg-message "passing argument 1" } 
+void func(Base&);                      // { dg-message "argument 1" }
 
 void func2(const Derived& d) {
-  func(d);                             // { dg-error "invalid initialization" }
+  func(d);                             // { dg-error "" }
 }
 
 void
-foo (int& a)                           // { dg-message "in passing argument 1" } 
+foo (int& a)                           // { dg-message "argument 1" }
 {
 }
 
@@ -27,6 +27,6 @@ int main ()
   int b;
   const int*const a = &b;
   *a = 10;                             // { dg-error "read-only location" }
-  foo (*a);                            // { dg-error "invalid initialization" }
+  foo (*a);                            // { dg-error "qualifiers" }
   return 0;
 }
index 05b8b1c07df756a0e5f749f3c5c456f98d94fbff..376d1f5a949af1709a8ccb667dc0e8fe4d0d029e 100644 (file)
@@ -196,7 +196,7 @@ Pix
 List_DLS<T>::search(const T& item) const
 {
     for (Pix x=this->first(); 0 != x; this->next(x)) {
-       if (item == this->operator()(x)) // { dg-error "match" } const subversion
+       if (item == this->operator()(x)) // { dg-error "qualifiers" } const subversion
            return x;
     }
     return 0;
@@ -485,8 +485,8 @@ class STRLIdentifier {
     char buf[10];
 };
 
-extern int operator==(vertex<STRLIdentifier*>&, vertex<STRLIdentifier*>&); // { dg-message "note" } const subversion
-extern int operator==(STRLIdentifier&, STRLIdentifier&); // { dg-message "note" } fn ref in err msg
+extern int operator==(vertex<STRLIdentifier*>&, vertex<STRLIdentifier*>&); // { dg-message "argument 1" } const subversion
+extern int operator==(STRLIdentifier&, STRLIdentifier&);
 
 extern int x(List_DLSp<STRLIdentifier *>);
 
index bc272af5c8064c139653271b999a831dfd7b429e..8a7ede660ba3397e74f412a58107bd2274b44e67 100644 (file)
@@ -18,6 +18,6 @@ class C
        C()
        {
                B       b;
-               A a = b;// { dg-error "match" } 
+               A a = b;// { dg-error "rvalue" }
        }
 };
index 1975ebf021eba5241b89f0083ad8e27fa1393f86..18f926775e294a27ddb60415ac52b1987127d1e7 100644 (file)
@@ -19,5 +19,5 @@ void C::test() const
 {
    D d;
 
-   d.a(*this); // { dg-error "match" } *this is const, so should get error
+   d.a(*this); // { dg-error "const" } *this is const, so should get error
 }
index 8e9a345e35a637cdfb19e777d7f2a2fbaf8acce9..99ef1f4d6c85459f79d9c6512444532898501823 100644 (file)
@@ -7,7 +7,7 @@ extern "C"
 }
 
 
-void Munge(int& x)     // { dg-message "passing argument 1" }
+void Munge(int& x)     // { dg-message "argument 1" }
 {
    x = 2;
 }
@@ -24,7 +24,7 @@ class A
 void
 A::Safe() const 
 {
-   Munge(i);           // { dg-error "invalid initialization" }
+   Munge(i);           // { dg-error "const" }
 }
 
 int main()
index d2581f089334bf0699e18891262429815bfd867e..a4d655a796aaf8e02385d9481ccdc126c38eafe7 100644 (file)
@@ -12,7 +12,7 @@ class foo {
 static void iteratorTest(const foo &x)
 {
    foo::const_iterator i = x.begin();          // { dg-error "incomplete type" "incomplete type" } 
-   // { dg-error "no matching|const foo" "no matching" { target *-*-* } 14 }
+   // { dg-error "const foo" "" { target *-*-* } 14 }
    for (; i; ++i)
       *i;
 }
index 5c5872870360f15cef236faa81008c56c83134d2..7d818fbe9e130a5277d306df0b86bf4ee2f50bf8 100644 (file)
@@ -15,6 +15,6 @@ ret_v_f_class()
 int main(void)
 {
   volatile f_class vf;
-  0 ? ret_v_f_class() : vf;    // { dg-error "match" } can't copy volatile lvalue
+  0 ? ret_v_f_class() : vf;    // { dg-error "volatile" } can't copy volatile lvalue
   return 0;
 }
index 08af5fbafdfd3e6bd501c09ff257b29bc7ea073d..4a363a27f30f1e920b5c60348b2f64fd4cd56ce8 100644 (file)
@@ -11,7 +11,7 @@ template<typename X> struct auto_ptr {
    explicit auto_ptr(X* p =0) throw() : px(p) {}
    auto_ptr(auto_ptr& r) throw() : px(r.release()) {} // { dg-message "note" } candidate
    template<typename Y>
-      auto_ptr(auto_ptr<Y>& r) throw() : px(r.release()) {}// { dg-message "note" } candidate
+      auto_ptr(auto_ptr<Y>& r) throw() : px(r.release()) {}
 
    auto_ptr& operator=(auto_ptr& r) throw() { 
       reset(r.release()); 
@@ -30,7 +30,7 @@ template<typename X> struct auto_ptr {
    X* release() throw() { X* p=px; px=0; return p; }
    void reset(X* p=0) throw() { if (px != p) delete px, px = p; }
 
-   auto_ptr(auto_ptr_ref<X> r) throw() : px(r.py) {} // { dg-message "note" } 
+   auto_ptr(auto_ptr_ref<X> r) throw() : px(r.py) {}
    template<typename Y> operator auto_ptr_ref<Y>() throw() {
       return auto_ptr_ref<Y>(release()); 
    }
@@ -51,5 +51,5 @@ int main() {
     auto_ptr<Derived> y(f());
     x = y;
     g(f());
-    h(f());                    // { dg-error "match" "match" } no usable copy ctor
+    h(f());                    // { dg-error "rvalue" "" } no usable copy ctor
 }
index 71fe95864d2d65918b85469d00a157d77ae77390..f1eda15db8351c0f5dfa1fb7cf03c405ce6ea929 100644 (file)
@@ -1,9 +1,9 @@
 // { dg-do assemble  }
 
-template <class A> class B {    // { dg-message "note" } 
+template <class A> class B {
   A a;                          
  public:
   B(A&aa);                     // { dg-message "note" }
   ~B();
 };
-static B<int> b_int (3);       // { dg-error "no matching function" } 
+static B<int> b_int (3);       // { dg-error "no match|rvalue" }
index 06f7bcbdfd758ea75c584733d80ac627ff072fee..f34fc8a5d52cbf0e6935bf3ea2516bcde7e75cd1 100644 (file)
@@ -28,7 +28,7 @@ template<class T, class A1, class A2>
   factory(A1&& a1, A2&& a2)
   {
     return std::shared_ptr<T>(new T(std::forward<A1>(a1),
-                                   std::forward<A2>(a2))); // { dg-error "no matching function" }
+                                   std::forward<A2>(a2))); // { dg-error "rvalue" }
   }
 
 struct A