Index: gcc/function.c |
diff --git a/gcc/function.c b/gcc/function.c |
index d582fea6e6539ff774d7463cd546d2163410a75f..329e75aebbc944cfc007a7596ac81aa9a0d1d340 100644 |
--- a/gcc/function.c |
+++ b/gcc/function.c |
@@ -1826,6 +1826,27 @@ struct rtl_opt_pass pass_instantiate_virtual_regs = |
} |
}; |
+/* HACK: If |maybe_call| is a call expression, grab additional type attributes |
+ from the expression (e.g., from a function pointer type) which may not |
+ have been present in a function decl. This must NOT affect the original |
+ function type/decl, so make a copy if it really changed. We may be able |
+ to narrow this hack to just propagate the "pnaclcall" attribute. */ |
+static tree copy_attributes_if_call (const_tree maybe_call, const_tree fntype) { |
+ if (TREE_CODE (maybe_call) == CALL_EXPR) |
+ { |
+ tree new_attributes = merge_type_attributes(fntype, |
+ TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (maybe_call)))); |
+ if (!attribute_list_equal (TYPE_ATTRIBUTES (fntype), new_attributes)) |
+ { |
+ tree new_fntype = copy_node (fntype); |
+ TYPE_ATTRIBUTES (new_fntype) = new_attributes; |
+ return new_fntype; |
+ } |
+ return fntype; |
+ } |
+ return fntype; |
+} |
+ |
/* Return 1 if EXP is an aggregate type (or a value with aggregate type). |
This means a type for which function calls must pass an address to the |
@@ -1853,10 +1874,14 @@ aggregate_value_p (const_tree exp, const_tree fntype) |
fntype = (fndecl |
? TREE_TYPE (fndecl) |
: TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (fntype)))); |
+ /* HACK to grab attributes from the callexp type as well as the decl. */ |
+ fntype = copy_attributes_if_call (exp, fntype); |
break; |
case FUNCTION_DECL: |
fndecl = fntype; |
fntype = TREE_TYPE (fndecl); |
+ /* HACK to grab attributes from the callexp type as well as the decl. */ |
+ fntype = copy_attributes_if_call (exp, fntype); |
break; |
case FUNCTION_TYPE: |
case METHOD_TYPE: |