if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);
+ /* Type `noreturn' has no storage, return `null' for the expression. */
+ if (DECL_P (exp) && TREE_CODE (exp) != FIELD_DECL
+ && TYPE_MAIN_VARIANT (TREE_TYPE (exp)) == noreturn_type_node)
+ return compound_expr (init, null_pointer_node);
+
/* Some expression lowering may request an address of a compile-time constant,
or other non-lvalue expression. Make sure it is assigned to a location we
can reference. */
/* Type `noreturn` is a terminator, as no other arguments can possibly
be evaluated after it. */
- if (TREE_TYPE (targ) == noreturn_type_node)
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (targ)) == noreturn_type_node)
noreturn_call = true;
vec_safe_push (args, targ);
unsigned int ix;
FOR_EACH_VEC_SAFE_ELT (args, ix, arg)
- saved_args = compound_expr (saved_args, arg);
+ {
+ saved_args = compound_expr (saved_args, arg);
+
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (arg)) == noreturn_type_node)
+ break;
+ }
/* Add a stub result type for the expression. */
tree result = build_zero_cst (TREE_TYPE (ctype));
/* Type `noreturn` is a terminator, as no other arguments can possibly
be evaluated after it. */
- if (TREE_TYPE (parm_decl) == noreturn_type_node)
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (parm_decl)) == noreturn_type_node)
break;
/* Chain them in the correct order. */
/* Type `noreturn` is a terminator, as no other arguments can possibly
be evaluated after it. */
- if (type == noreturn_type_node)
+ if (TYPE_MAIN_VARIANT (type) == noreturn_type_node)
break;
fnparams = chainon (fnparams, build_tree_list (0, type));
d_keep (t->ctype);
/* Qualify function types that have the type `noreturn` as volatile. */
- if (fntype == noreturn_type_node)
+ if (TYPE_MAIN_VARIANT (fntype) == noreturn_type_node)
t->ctype = build_qualified_type (t->ctype, TYPE_QUAL_VOLATILE);
/* Handle any special support for calling conventions. */