if (error_operand_p (destination))
return NULL_TREE;
}
- /* We don't inline calls to functions with computed gotos.
- Those functions are typically up to some funny business,
- and may be depending on the labels being at particular
- addresses, or some such. */
- DECL_UNINLINABLE (current_function_decl) = 1;
}
check_goto (destination);
/* It actually has a value we need to deal with. First, force it
to be an rvalue so that we won't need to build up a copy
constructor call later when we try to assign it to something. */
- expr = force_rvalue (expr);
+ expr = force_rvalue (expr, tf_warning_or_error);
if (error_operand_p (expr))
return error_mark_node;
temporary object created by the final expression is destroyed at
the end of the full-expression containing the
statement-expression. */
- result = force_target_expr (type, result);
+ result = force_target_expr (type, result, tf_warning_or_error);
}
return result;
is not included in *ARGS even though it is considered to
be part of the list of arguments. Note that this is
related to CWG issues 515 and 1005. */
- || ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ || (((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
+ || BASELINK_P (fn))
&& current_class_ref
&& type_dependent_expression_p (current_class_ref)))
{
represent class temporaries with TARGET_EXPR so we elide copies. */
if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
&& TREE_CODE (type) == ARRAY_TYPE
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& initializer_constant_valid_p (compound_literal, type))
{
tree decl = create_temporary_var (type);
return decl;
}
else
- return get_target_expr (compound_literal);
+ return get_target_expr_sfinae (compound_literal, complain);
}
/* Return the declaration for the function-name variable indicated by
return type;
}
+/* Implement the __underlying_type keyword: Return the underlying
+ type of TYPE, suitable for use as a type-specifier. */
+
+tree
+finish_underlying_type (tree type)
+{
+ tree underlying_type;
+
+ if (processing_template_decl)
+ {
+ underlying_type = cxx_make_type (UNDERLYING_TYPE);
+ UNDERLYING_TYPE_TYPE (underlying_type) = type;
+ SET_TYPE_STRUCTURAL_EQUALITY (underlying_type);
+
+ return underlying_type;
+ }
+
+ complete_type (type);
+
+ if (TREE_CODE (type) != ENUMERAL_TYPE)
+ {
+ error ("%qE is not an enumeration type", type);
+ return error_mark_node;
+ }
+
+ underlying_type = ENUM_UNDERLYING_TYPE (type);
+
+ /* Fixup necessary in this case because ENUM_UNDERLYING_TYPE
+ includes TYPE_MIN_VALUE and TYPE_MAX_VALUE information.
+ See finish_enum_value_list for details. */
+ if (!ENUM_FIXED_UNDERLYING_TYPE_P (type))
+ underlying_type
+ = c_common_type_for_mode (TYPE_MODE (underlying_type),
+ TYPE_UNSIGNED (underlying_type));
+
+ return underlying_type;
+}
+
/* Perform C++-specific checks for __builtin_offsetof before calling
fold_offsetof. */
bool
literal_type_p (tree t)
{
- if (SCALAR_TYPE_P (t))
+ if (SCALAR_TYPE_P (t)
+ || TREE_CODE (t) == REFERENCE_TYPE)
return true;
if (CLASS_TYPE_P (t))
return CLASSTYPE_LITERAL_P (t);
return (constexpr_fundef *) htab_find (constexpr_fundef_table, &fundef);
}
-/* Return true if type expression T is a valid parameter type, or
- a valid return type, of a constexpr function. */
-
-static bool
-valid_type_in_constexpr_fundecl_p (tree t)
-{
- return (literal_type_p (t)
- /* FIXME we allow ref to non-literal; should change standard to
- match, or change back if not. */
- || TREE_CODE (t) == REFERENCE_TYPE);
-}
-
/* Check whether the parameter and return types of FUN are valid for a
constexpr function, and complain if COMPLAIN. */
tree parm = FUNCTION_FIRST_USER_PARM (fun);
bool ret = true;
for (; parm != NULL; parm = TREE_CHAIN (parm))
- if (!valid_type_in_constexpr_fundecl_p (TREE_TYPE (parm)))
+ if (!literal_type_p (TREE_TYPE (parm)))
{
ret = false;
if (complain)
if (!DECL_CONSTRUCTOR_P (fun))
{
tree rettype = TREE_TYPE (TREE_TYPE (fun));
- if (!valid_type_in_constexpr_fundecl_p (rettype))
+ if (!literal_type_p (rettype))
{
ret = false;
if (complain)
There's normally no way to express direct-initialization
from an element of a CONSTRUCTOR, so we build up a special
TARGET_EXPR to bypass the usual copy-initialization. */
- val = force_rvalue (val);
+ val = force_rvalue (val, tf_warning_or_error);
if (TREE_CODE (val) == TARGET_EXPR)
TARGET_EXPR_DIRECT_INIT_P (val) = true;
}