else
rval = init;
+ if (location_t loc = EXPR_LOCATION (init))
+ SET_EXPR_LOCATION (rval, loc);
+
return rval;
}
tree
dependent_name (tree x)
{
+ /* FIXME a dependent name must be unqualified, but this function doesn't
+ distinguish between qualified and unqualified identifiers. */
if (identifier_p (x))
return x;
if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
cp_walk_tree (&t, verify_stmt_tree_r, &statements, NULL);
}
-/* Check if the type T depends on a type with no linkage and if so, return
- it. If RELAXED_P then do not consider a class type declared within
- a vague-linkage function to have no linkage. */
+/* Check if the type T depends on a type with no linkage and if so,
+ return it. If RELAXED_P then do not consider a class type declared
+ within a vague-linkage function to have no linkage. Remember:
+ no-linkage is not the same as internal-linkage*/
tree
no_linkage_check (tree t, bool relaxed_p)
fix it up later if not. We need to check this even in templates so
that we properly handle a lambda-expression in the signature. */
if (LAMBDA_TYPE_P (t)
- && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node
- && LAMBDA_TYPE_EXTRA_SCOPE (t) == NULL_TREE)
- return t;
+ && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node)
+ {
+ tree extra = LAMBDA_TYPE_EXTRA_SCOPE (t);
+ if (!extra)
+ return t;
+ }
/* Otherwise there's no point in checking linkage on template functions; we
can't know their complete types. */
a PLACEHOLDER_EXPR has been encountered. */
tree
-replace_placeholders (tree exp, tree obj, bool *seen_p)
+replace_placeholders (tree exp, tree obj, bool *seen_p /*= NULL*/)
{
/* This is only relevant for C++14. */
if (cxx_dialect < cxx14)
/* If the object isn't a (member of a) class, do nothing. */
tree op0 = obj;
- while (TREE_CODE (op0) == COMPONENT_REF)
+ while (handled_component_p (op0))
op0 = TREE_OPERAND (op0, 0);
if (!CLASS_TYPE_P (strip_array_types (TREE_TYPE (op0))))
return exp;
if (name1 != name2)
return false;
+ /* FIXME dependent_name currently returns an unqualified name regardless
+ of whether the function was named with a qualified- or unqualified-id.
+ Until that's fixed, check that we aren't looking at overload sets from
+ different scopes. */
+ if (is_overloaded_fn (t1) && is_overloaded_fn (t2)
+ && (DECL_CONTEXT (get_first_fn (t1))
+ != DECL_CONTEXT (get_first_fn (t2))))
+ return false;
+
if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
targs1 = TREE_OPERAND (t1, 1);
if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
{
tree arg1, arg2;
call_expr_arg_iterator iter1, iter2;
- if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
+ if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2)
+ || !called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
return false;
for (arg1 = first_call_expr_arg (t1, &iter1),
arg2 = first_call_expr_arg (t2, &iter2);
up for expressions that involve 'this' in a member function
template. */
- if (comparing_specializations && !CONSTRAINT_VAR_P (t1))
+ if (comparing_specializations
+ && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
/* When comparing hash table entries, only an exact match is
good enough; we don't want to replace 'this' with the
version from another function. But be more flexible
- with local parameters in a requires-expression. */
+ with parameters with identical contexts. */
return false;
if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
if (SIZEOF_EXPR_TYPE_P (t2))
o2 = TREE_TYPE (o2);
}
+
if (TREE_CODE (o1) != TREE_CODE (o2))
return false;
- if (TYPE_P (o1))
+
+ if (ARGUMENT_PACK_P (o1))
+ return template_args_equal (o1, o2);
+ else if (TYPE_P (o1))
return same_type_p (o1, o2);
else
return cp_tree_equal (o1, o2);
DEFERRED_NOEXCEPT_PATTERN (t2))
&& comp_template_args (DEFERRED_NOEXCEPT_ARGS (t1),
DEFERRED_NOEXCEPT_ARGS (t2)));
- break;
case LAMBDA_EXPR:
/* Two lambda-expressions are never considered equivalent. */
return false;
+ case TYPE_ARGUMENT_PACK:
+ case NONTYPE_ARGUMENT_PACK:
+ {
+ tree p1 = ARGUMENT_PACK_ARGS (t1);
+ tree p2 = ARGUMENT_PACK_ARGS (t2);
+ int len = TREE_VEC_LENGTH (p1);
+ if (TREE_VEC_LENGTH (p2) != len)
+ return false;
+
+ for (int ix = 0; ix != len; ix++)
+ if (!template_args_equal (TREE_VEC_ELT (p1, ix),
+ TREE_VEC_ELT (p2, ix)))
+ return false;
+ return true;
+ }
+
default:
break;
}
return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
if (TREE_CODE (init) != CONSTRUCTOR)
- return initializer_zerop (init);
+ {
+ /* A class can only be initialized by a non-class type if it has
+ a ctor that converts from that type. Such classes are excluded
+ since their semantics are unknown. */
+ if (RECORD_OR_UNION_TYPE_P (type)
+ && !RECORD_OR_UNION_TYPE_P (TREE_TYPE (init)))
+ return false;
+ return initializer_zerop (init);
+ }
if (TREE_CODE (type) == ARRAY_TYPE)
{