static tree
original_type (tree t)
{
- while (TYPE_NAME (t) != NULL_TREE)
+ int quals = cp_type_quals (t);
+ while (t != error_mark_node
+ && TYPE_NAME (t) != NULL_TREE)
{
tree x = TYPE_NAME (t);
if (TREE_CODE (x) != TYPE_DECL)
break;
t = x;
}
- return t;
+ return cp_build_qualified_type (t, quals);
}
/* T1 and T2 are arithmetic or enumeration types. Return the type
default:;
}
- return cp_build_type_attribute_variant (t1, attributes);
+
+ if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
+ return t1;
+ else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
+ return t2;
+ else
+ return cp_build_type_attribute_variant (t1, attributes);
}
/* Return the common type of two types.
cxx_alignof_expr (tree e)
{
tree t;
-
+
if (e == error_mark_node)
return error_mark_node;
adr = build_unary_op (ADDR_EXPR, exp, 1);
return cp_convert (ptrtype, adr);
}
-
+
/* If a bitfield is used in a context where integral promotion
applies, then the caller is expected to have used
default_conversion. That function promotes bitfields correctly
{
/* Perform the integral promotions first so that bitfield
expressions (which may promote to "int", even if the bitfield is
- declared "unsigned") are promoted correctly. */
+ declared "unsigned") are promoted correctly. */
if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (exp)))
exp = perform_integral_promotions (exp);
/* Perform the other conversions. */
/* This warning is not very useful, as it complains about printf. */
if (warn)
- warning (OPT_Wwrite_strings, "deprecated conversion from string constant to %qT'", totype);
+ warning (OPT_Wwrite_strings,
+ "deprecated conversion from string constant to %qT",
+ totype);
return 1;
}
tree member_scope;
tree result = NULL_TREE;
- if (object == error_mark_node || member == error_mark_node)
+ if (error_operand_p (object) || error_operand_p (member))
return error_mark_node;
gcc_assert (DECL_P (member) || BASELINK_P (member));
template, the program is ill-formed.
DR 228 removed the restriction that the template be a member
- template.
-
+ template.
+
DR 96, if accepted would add the further restriction that explicit
template arguments must be provided if the template keyword is
used, but, as of 2005-10-16, that DR is still in "drafting". If
orig_object, orig_name,
NULL_TREE);
}
-
+
return expr;
}
switch (code)
{
- case PLUS_EXPR:
- /* Handle the pointer + int case. */
- if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return cp_pointer_int_sum (PLUS_EXPR, op0, op1);
- else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
- return cp_pointer_int_sum (PLUS_EXPR, op1, op0);
- else
- common = 1;
- break;
-
case MINUS_EXPR:
/* Subtraction of two similar pointers.
We must subtract them as integers, then divide by object size. */
&& same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
TREE_TYPE (type1)))
return pointer_diff (op0, op1, common_type (type0, type1));
- /* Handle pointer minus int. Just like pointer plus int. */
- else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return cp_pointer_int_sum (MINUS_EXPR, op0, op1);
- else
- common = 1;
+ /* In all other cases except pointer - int, the usual arithmetic
+ rules aply. */
+ else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
+ {
+ common = 1;
+ break;
+ }
+ /* The pointer - int case is just like pointer + int; fall
+ through. */
+ case PLUS_EXPR:
+ if ((code0 == POINTER_TYPE || code1 == POINTER_TYPE)
+ && (code0 == INTEGER_TYPE || code1 == INTEGER_TYPE))
+ {
+ tree ptr_operand;
+ tree int_operand;
+ ptr_operand = ((code0 == POINTER_TYPE) ? op0 : op1);
+ int_operand = ((code0 == INTEGER_TYPE) ? op0 : op1);
+ if (processing_template_decl)
+ {
+ result_type = TREE_TYPE (ptr_operand);
+ break;
+ }
+ return cp_pointer_int_sum (code,
+ ptr_operand,
+ int_operand);
+ }
+ common = 1;
break;
case MULT_EXPR:
case EQ_EXPR:
case NE_EXPR:
if (code0 == REAL_TYPE || code1 == REAL_TYPE)
- warning (OPT_Wfloat_equal,
- "comparing floating point with == or != is unsafe");
+ warning (OPT_Wfloat_equal,
+ "comparing floating point with == or != is unsafe");
if ((TREE_CODE (orig_op0) == STRING_CST && !integer_zerop (op1))
|| (TREE_CODE (orig_op1) == STRING_CST && !integer_zerop (op0)))
warning (OPT_Wstring_literal_comparison,
else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM,
arg, true)))
errstring = "wrong type argument to bit-complement";
- else if (!noconvert)
+ else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg)))
arg = perform_integral_promotions (arg);
break;
pedwarn ("ISO C++ forbids taking the address of a cast to a non-lvalue expression");
break;
+ case BASELINK:
+ arg = BASELINK_FUNCTIONS (arg);
+ /* Fall through. */
+
case OVERLOAD:
arg = OVL_CURRENT (arg);
break;
/* Allow array assignment in compiler-generated code. */
if (! DECL_ARTIFICIAL (current_function_decl))
- pedwarn ("ISO C++ forbids assignment of arrays");
+ {
+ /* This routine is used for both initialization and assignment.
+ Make sure the diagnostic message differentiates the context. */
+ if (modifycode == INIT_EXPR)
+ error ("array used as initializer");
+ else
+ error ("invalid array assignment");
+ return error_mark_node;
+ }
from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE
? 1 + (modifycode != INIT_EXPR): 0;
- return build_vec_init (lhs, NULL_TREE, newrhs,
+ return build_vec_init (lhs, NULL_TREE, newrhs,
/*explicit_default_init_p=*/false,
from_array);
}
"%s might be a candidate for a format attribute",
errtype);
}
-
+
return perform_implicit_conversion (strip_top_quals (type), rhs);
}
}
}
+ while (TREE_CODE (whats_returned) == COMPONENT_REF
+ || TREE_CODE (whats_returned) == ARRAY_REF)
+ whats_returned = TREE_OPERAND (whats_returned, 0);
+
if (DECL_P (whats_returned)
&& DECL_NAME (whats_returned)
&& DECL_FUNCTION_SCOPE_P (whats_returned)
return!). */
current_function_returns_null = 0;
/* And signal caller that TREE_NO_WARNING should be set on the
- RETURN_EXPR to avoid control reaches end of non-void function
- warnings in tree-cfg.c. */
+ RETURN_EXPR to avoid control reaches end of non-void function
+ warnings in tree-cfg.c. */
*no_warning = true;
}
/* Check for a return statement with a value in a function that
was an incomplete type. Just treat this as 'return;' */
if (VOID_TYPE_P (functype))
return error_mark_node;
-
+
/* First convert the value to the function's return type, then
to the type of return value's location to handle the
case that functype is smaller than the valtype. */