for more information.
-* New flags -Wsign-promo, -Wno-pmf-conversion.
+* New flags -Wsign-promo (warn about potentially confusing promotions in
+ overload resolution), -Wno-pmf-conversion (don't warn about converting
+ from a bound member function pointer to function pointer).
* local static variables in extern inline functions will be shared between
translation units.
already has virtual functions, only if they override a virtual destructor
in a base class. The compiler will warn if this affects your code.
-* The g++ driver no longer links with libg++ by default; it is now
+* The g++ driver now only links against libstdc++, not libg++; it is
functionally identical to the c++ driver.
* (void *)0 is no longer considered a null pointer constant; NULL in
+ Syntax errors in templates that are never instantiated will now be
diagnosed.
+ Still not supported:
+
+ + Member templates.
+ + Template template parameters.
+
* Synthesized methods are now emitted in any translation units that need
an out-of-line copy. They are no longer affected by #pragma interface
or #pragma implementation.
if (t == null_node
|| integer_zerop (t) && INTEGRAL_TYPE_P (TREE_TYPE (t)))
return 1;
- /* Remove this eventually. */
- if (! pedantic && TREE_TYPE (t) == ptr_type_node && integer_zerop (t))
- return 1;
return 0;
}
{
tree c1 = TREE_TYPE (type1);
tree c2 = (TYPE_PTRMEMFUNC_P (type2)
- ? TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2))
+ ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2)))
: TYPE_OFFSET_BASETYPE (TREE_TYPE (type2)));
if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1)
if (TYPE_PTRMEMFUNC_P (to1))
{
- to1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to1));
- from1 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from1));
+ to1 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to1)));
+ from1 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from1)));
}
else if (TREE_CODE (main1) != BASE_CONV)
{
if (TYPE_PTRMEMFUNC_P (to2))
{
- to2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (to2));
- from2 = TYPE_METHOD_BASETYPE (TYPE_PTRMEMFUNC_FN_TYPE (from2));
+ to2 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to2)));
+ from2 = TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from2)));
}
else if (TREE_CODE (main1) != BASE_CONV)
{
return 0;
}
+static tree
+source_type (t)
+ tree t;
+{
+ for (;; t = TREE_OPERAND (t, 0))
+ {
+ if (TREE_CODE (t) == USER_CONV
+ || TREE_CODE (t) == AMBIG_CONV
+ || TREE_CODE (t) == IDENTITY_CONV)
+ return TREE_TYPE (t);
+ }
+ my_friendly_abort (1823);
+}
+
/* Compare two candidates for overloading as described in
[over.match.best]. Return values:
}
}
+ /* warn about confusing overload resolution */
+ if (winner && cand1->second_conv
+ && ! DECL_CONSTRUCTOR_P (cand1->fn)
+ && ! DECL_CONSTRUCTOR_P (cand2->fn))
+ {
+ int comp = compare_ics (cand1->second_conv, cand2->second_conv);
+ if (comp && comp != winner)
+ {
+ struct z_candidate *w, *l;
+ if (winner == 1)
+ w = cand1, l = cand2;
+ else
+ w = cand2, l = cand1;
+ cp_warning ("choosing `%D' over `%D'", w->fn, l->fn);
+ cp_warning (" for conversion from `%T' to `%T'",
+ TREE_TYPE (source_type (TREE_VEC_ELT (w->convs, 0))),
+ TREE_TYPE (w->second_conv));
+ cp_warning (" because conversion sequence for `this' argument is better");
+ }
+ }
+
if (winner)
return winner;