tree pointed_to_1 = TREE_TYPE (t1);
tree pointed_to_2 = TREE_TYPE (t2);
tree target = composite_type (pointed_to_1, pointed_to_2);
- t1 = build_pointer_type (target);
+ t1 = build_pointer_type_for_mode (target, TYPE_MODE (t1), false);
t1 = build_type_attribute_variant (t1, attributes);
return qualify_type (t1, t2);
}
compatible integer type, then this sets *ENUM_AND_INT_P to true;
*ENUM_AND_INT_P is never set to false. If DIFFERENT_TYPES_P is not
NULL, and the types are compatible but different enough not to be
- permitted in C1X typedef redeclarations, then this sets
+ permitted in C11 typedef redeclarations, then this sets
*DIFFERENT_TYPES_P to true; *DIFFERENT_TYPES_P is never set to
false, but may or may not be set if the types are incompatible.
This differs from comptypes, in that we don't free the seen
if (TREE_CODE (exp) == INDIRECT_REF)
return convert (ptrtype, TREE_OPERAND (exp, 0));
+ /* In C++ array compound literals are temporary objects unless they are
+ const or appear in namespace scope, so they are destroyed too soon
+ to use them for much of anything (c++/53220). */
+ if (warn_cxx_compat && TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
+ {
+ tree decl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
+ if (!TREE_READONLY (decl) && !TREE_STATIC (decl))
+ warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+ "converting an array compound literal to a pointer "
+ "is ill-formed in C++");
+ }
+
adr = build_unary_op (loc, ADDR_EXPR, exp, 1);
return convert (ptrtype, adr);
}
"wrong type argument to unary exclamation mark");
return error_mark_node;
}
- arg = c_objc_common_truthvalue_conversion (location, arg);
+ if (int_operands)
+ {
+ arg = c_objc_common_truthvalue_conversion (location, xarg);
+ arg = remove_c_maybe_const_expr (arg);
+ }
+ else
+ arg = c_objc_common_truthvalue_conversion (location, arg);
ret = invert_truthvalue_loc (location, arg);
/* If the TRUTH_NOT_EXPR has been folded, reset the location. */
if (EXPR_P (ret) && EXPR_HAS_LOCATION (ret))
ret = fold_build3_loc (colon_loc, COND_EXPR, result_type, ifexp, op1, op2);
else
{
+ if (int_operands)
+ {
+ op1 = remove_c_maybe_const_expr (op1);
+ op2 = remove_c_maybe_const_expr (op2);
+ }
ret = build3 (COND_EXPR, result_type, ifexp, op1, op2);
if (int_operands)
ret = note_integer_operands (ret);
ret = build_c_cast (loc, type, expr);
if (type_expr)
{
+ bool inner_expr_const = true;
+ ret = c_fully_fold (ret, require_constant_value, &inner_expr_const);
ret = build2 (C_MAYBE_CONST_EXPR, TREE_TYPE (ret), type_expr, ret);
- C_MAYBE_CONST_EXPR_NON_CONST (ret) = !type_expr_const;
+ C_MAYBE_CONST_EXPR_NON_CONST (ret) = !(type_expr_const
+ && inner_expr_const);
SET_EXPR_LOCATION (ret, loc);
}
FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value)
{
- add_pending_init (index, value, NULL_TREE, false,
+ add_pending_init (index, value, NULL_TREE, true,
braced_init_obstack);
}
constructor_elements = 0;
}
value = build_int_cst_wide (type, val[1], val[0]);
- add_pending_init (purpose, value, NULL_TREE, false,
+ add_pending_init (purpose, value, NULL_TREE, true,
braced_init_obstack);
}
npc, NULL_TREE, NULL_TREE, 0);
tree res = DECL_RESULT (current_function_decl);
tree inner;
+ bool save;
current_function_returns_value = 1;
if (t == error_mark_node)
return NULL_TREE;
+ save = in_late_binary_op;
+ if (TREE_CODE (TREE_TYPE (res)) == BOOLEAN_TYPE
+ || TREE_CODE (TREE_TYPE (res)) == COMPLEX_TYPE)
+ in_late_binary_op = true;
inner = t = convert (TREE_TYPE (res), t);
+ in_late_binary_op = save;
/* Strip any conversions, additions, and subtractions, and see if
we are returning the address of a local variable. Warn if so. */
sc = convert (TREE_TYPE (type0), sc);
op1 = build_vector_from_val (type0, sc);
if (!maybe_const)
- op0 = c_wrap_maybe_const (op1, true);
+ op1 = c_wrap_maybe_const (op1, true);
orig_type1 = type1 = TREE_TYPE (op1);
code1 = TREE_CODE (type1);
converted = 1;
but that does not mean the operands should be
converted to ints! */
result_type = integer_type_node;
- op0 = c_common_truthvalue_conversion (location, op0);
- op1 = c_common_truthvalue_conversion (location, op1);
+ if (op0_int_operands)
+ {
+ op0 = c_objc_common_truthvalue_conversion (location, orig_op0);
+ op0 = remove_c_maybe_const_expr (op0);
+ }
+ else
+ op0 = c_objc_common_truthvalue_conversion (location, op0);
+ if (op1_int_operands)
+ {
+ op1 = c_objc_common_truthvalue_conversion (location, orig_op1);
+ op1 = remove_c_maybe_const_expr (op1);
+ }
+ else
+ op1 = c_objc_common_truthvalue_conversion (location, op1);
converted = 1;
boolean_op = true;
}
int_const = (TREE_CODE (expr) == INTEGER_CST && !TREE_OVERFLOW (expr));
int_operands = EXPR_INT_CONST_OPERANDS (expr);
- if (int_operands)
- expr = remove_c_maybe_const_expr (expr);
-
- /* ??? Should we also give an error for vectors rather than leaving
- those to give errors later? */
- expr = c_common_truthvalue_conversion (location, expr);
+ if (int_operands && TREE_CODE (expr) != INTEGER_CST)
+ {
+ expr = remove_c_maybe_const_expr (expr);
+ expr = build2 (NE_EXPR, integer_type_node, expr,
+ convert (TREE_TYPE (expr), integer_zero_node));
+ expr = note_integer_operands (expr);
+ }
+ else
+ /* ??? Should we also give an error for vectors rather than leaving
+ those to give errors later? */
+ expr = c_common_truthvalue_conversion (location, expr);
if (TREE_CODE (expr) == INTEGER_CST && int_operands && !int_const)
{