summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/cp/typeck.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/cp/typeck.c')
-rw-r--r--contrib/gcc/cp/typeck.c74
1 files changed, 53 insertions, 21 deletions
diff --git a/contrib/gcc/cp/typeck.c b/contrib/gcc/cp/typeck.c
index 0c9c6c4..b13fb85 100644
--- a/contrib/gcc/cp/typeck.c
+++ b/contrib/gcc/cp/typeck.c
@@ -95,6 +95,9 @@ require_complete_type (tree value)
else
type = TREE_TYPE (value);
+ if (type == error_mark_node)
+ return error_mark_node;
+
/* First, detect a valid value with a complete type. */
if (COMPLETE_TYPE_P (type))
return value;
@@ -265,10 +268,12 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
/* FIXME: Attributes. */
my_friendly_assert (ARITHMETIC_TYPE_P (t1)
|| TREE_CODE (t1) == COMPLEX_TYPE
+ || TREE_CODE (t1) == VECTOR_TYPE
|| TREE_CODE (t1) == ENUMERAL_TYPE,
19990725);
my_friendly_assert (ARITHMETIC_TYPE_P (t2)
|| TREE_CODE (t2) == COMPLEX_TYPE
+ || TREE_CODE (t2) == VECTOR_TYPE
|| TREE_CODE (t2) == ENUMERAL_TYPE,
19990725);
@@ -296,6 +301,16 @@ type_after_usual_arithmetic_conversions (tree t1, tree t2)
attributes);
}
+ if (code1 == VECTOR_TYPE)
+ {
+ /* When we get here we should have two vectors of the same size.
+ Just prefer the unsigned one if present. */
+ if (TREE_UNSIGNED (t1))
+ return build_type_attribute_variant (t1, attributes);
+ else
+ return build_type_attribute_variant (t2, attributes);
+ }
+
/* If only one is real, use it as the result. */
if (code1 == REAL_TYPE && code2 != REAL_TYPE)
return build_type_attribute_variant (t1, attributes);
@@ -745,9 +760,9 @@ common_type (tree t1, tree t2)
code2 = TREE_CODE (t2);
if ((ARITHMETIC_TYPE_P (t1) || code1 == ENUMERAL_TYPE
- || code1 == COMPLEX_TYPE)
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
&& (ARITHMETIC_TYPE_P (t2) || code2 == ENUMERAL_TYPE
- || code2 == COMPLEX_TYPE))
+ || code2 == COMPLEX_TYPE || code2 == VECTOR_TYPE))
return type_after_usual_arithmetic_conversions (t1, t2);
else if ((TYPE_PTR_P (t1) && TYPE_PTR_P (t2))
@@ -2878,9 +2893,9 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
- || code0 == COMPLEX_TYPE)
+ || code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
- || code1 == COMPLEX_TYPE))
+ || code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1))
warning ("division by zero in `%E / 0'", op0);
@@ -2907,7 +2922,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if ((code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE))
shorten = -1;
break;
@@ -3158,12 +3174,17 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
break;
}
- if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
- &&
- (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
+ if (((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE)
+ &&
+ (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE))
+ || (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE))
{
int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE);
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && !tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)))
+ error ("can't convert between vector values of different size");
+
if (shorten || common || short_compare)
result_type = common_type (type0, type1);
@@ -4776,7 +4797,7 @@ build_const_cast (tree type, tree expr)
{
tree intype;
- if (type == error_mark_node || expr == error_mark_node)
+ if (type == error_mark_node || error_operand_p (expr))
return error_mark_node;
if (processing_template_decl)
@@ -6066,6 +6087,15 @@ check_return_expr (tree retval)
/* Remember that this function did return a value. */
current_function_returns_value = 1;
+ /* Check for erroneous operands -- but after giving ourselves a
+ chance to provide an error about returning a value from a void
+ function. */
+ if (error_operand_p (retval))
+ {
+ current_function_return_value = error_mark_node;
+ return error_mark_node;
+ }
+
/* Only operator new(...) throw(), can return NULL [expr.new/13]. */
if ((DECL_OVERLOADED_OPERATOR_P (current_function_decl) == NEW_EXPR
|| DECL_OVERLOADED_OPERATOR_P (current_function_decl) == VEC_NEW_EXPR)
@@ -6122,8 +6152,8 @@ check_return_expr (tree retval)
/* We don't need to do any conversions when there's nothing being
returned. */
- if (!retval || retval == error_mark_node)
- return retval;
+ if (!retval)
+ return NULL_TREE;
/* Do any required conversions. */
if (retval == result || DECL_CONSTRUCTOR_P (current_function_decl))
@@ -6314,11 +6344,6 @@ casts_away_constness_r (tree *t1, tree *t2)
and pointers to members (conv.qual), the "member" aspect of a
pointer to member level is ignored when determining if a const
cv-qualifier has been cast away. */
- if (TYPE_PTRMEM_P (*t1))
- *t1 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t1));
- if (TYPE_PTRMEM_P (*t2))
- *t2 = build_pointer_type (TYPE_PTRMEM_POINTED_TO_TYPE (*t2));
-
/* [expr.const.cast]
For two pointer types:
@@ -6336,9 +6361,8 @@ casts_away_constness_r (tree *t1, tree *t2)
to
Tcv2,(M-K+1) * cv2,(M-K+2) * ... cv2,M *. */
-
- if (TREE_CODE (*t1) != POINTER_TYPE
- || TREE_CODE (*t2) != POINTER_TYPE)
+ if ((!TYPE_PTR_P (*t1) && !TYPE_PTRMEM_P (*t1))
+ || (!TYPE_PTR_P (*t2) && !TYPE_PTRMEM_P (*t2)))
{
*t1 = cp_build_qualified_type (void_type_node,
cp_type_quals (*t1));
@@ -6349,8 +6373,16 @@ casts_away_constness_r (tree *t1, tree *t2)
quals1 = cp_type_quals (*t1);
quals2 = cp_type_quals (*t2);
- *t1 = TREE_TYPE (*t1);
- *t2 = TREE_TYPE (*t2);
+
+ if (TYPE_PTRMEM_P (*t1))
+ *t1 = TYPE_PTRMEM_POINTED_TO_TYPE (*t1);
+ else
+ *t1 = TREE_TYPE (*t1);
+ if (TYPE_PTRMEM_P (*t2))
+ *t2 = TYPE_PTRMEM_POINTED_TO_TYPE (*t2);
+ else
+ *t2 = TREE_TYPE (*t2);
+
casts_away_constness_r (t1, t2);
*t1 = build_pointer_type (*t1);
*t2 = build_pointer_type (*t2);
OpenPOWER on IntegriCloud