+2015-01-21 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/64313
+ * tree-core.h (builtin_info, builtin_info_type): Turn from
+ an object with two arrays into an array of an object with
+ decl and two flags, implicit_p and declared_p.
+ * tree.h (builtin_decl_explicit, builtin_decl_implicit,
+ set_builtin_decl, set_builtin_decl_implicit_p,
+ builtin_decl_explicit_p, builtin_decl_implicit_p): Adjust.
+ (set_builtin_decl_declared_p, builtin_decl_declared_p): New functions.
+ * builtins.c (builtin_info): Adjust.
+ * gimplify.c (gimplify_addr_expr): References to builtins
+ that have been declared by the user makes them eligible for
+ use by the compiler. Call set_builtin_decl_implicit_p on them.
+
2015-01-20 Jeff Law <law@redhat.com>
PR target/59946
};
#undef DEF_BUILTIN
-/* Setup an array of _DECL trees, make sure each element is
+/* Setup an array of builtin_info_type, make sure each element decl is
initialized to NULL_TREE. */
-builtin_info_type builtin_info;
+builtin_info_type builtin_info[(int)END_BUILTINS];
/* Non-zero if __builtin_constant_p should be folded right away. */
bool force_folding_builtin_constant_p;
+2015-01-21 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/64313
+ * c-decl.c (merge_decls): Call set_builtin_decl_declared_p
+ for builtins the user declared correctly.
+
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
set_builtin_decl_implicit_p (fncode, true);
break;
default:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_declared_p (fncode, true);
break;
}
}
+2015-01-21 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/64313
+ * decl.c (duplicate_decls): Call set_builtin_decl_declared_p
+ for builtins the user declared correctly.
+
2015-01-16 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58614
set_builtin_decl_implicit_p (fncode, true);
break;
default:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_declared_p (fncode, true);
break;
}
}
break;
default:
+ /* If we see a call to a declared builtin or see its address
+ being taken (we can unify those cases here) then we can mark
+ the builtin for implicit generation by GCC. */
+ if (TREE_CODE (op0) == FUNCTION_DECL
+ && DECL_BUILT_IN_CLASS (op0) == BUILT_IN_NORMAL
+ && builtin_decl_declared_p (DECL_FUNCTION_CODE (op0)))
+ set_builtin_decl_implicit_p (DECL_FUNCTION_CODE (op0), true);
+
/* We use fb_either here because the C frontend sometimes takes
the address of a call that returns a struct; see
gcc.dg/c99-array-lval-1.c. The gimplifier will correctly make
};
/* The builtin_info structure holds the FUNCTION_DECL of the standard builtin
- function, and a flag that says if the function is available implicitly, or
- whether the user has to code explicit calls to __builtin_<xxx>. */
+ function, and flags. */
struct GTY(()) builtin_info_type {
- tree decl[(int)END_BUILTINS];
- bool implicit_p[(int)END_BUILTINS];
+ tree decl;
+ /* Whether the user can use <xxx> instead of explicitly using calls
+ to __builtin_<xxx>. */
+ unsigned implicit_p : 1;
+ /* Whether the user has provided a declaration of <xxx>. */
+ unsigned declared_p : 1;
};
extern bool in_gimple_form;
/* Functional interface to the builtin functions. */
-extern GTY(()) builtin_info_type builtin_info;
+extern GTY(()) builtin_info_type builtin_info[(int)END_BUILTINS];
/* If nonzero, an upper limit on alignment of structure fields, in bits, */
extern unsigned int maximum_field_alignment;
{
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return builtin_info.decl[(size_t)fncode];
+ return builtin_info[(size_t)fncode].decl;
}
/* Return the tree node for an implicit builtin function or NULL. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- if (!builtin_info.implicit_p[uns_fncode])
+ if (!builtin_info[uns_fncode].implicit_p)
return NULL_TREE;
- return builtin_info.decl[uns_fncode];
+ return builtin_info[uns_fncode].decl;
}
/* Set explicit builtin function nodes and whether it is an implicit
gcc_checking_assert (BUILTIN_VALID_P (fncode)
&& (decl != NULL_TREE || !implicit_p));
- builtin_info.decl[ufncode] = decl;
- builtin_info.implicit_p[ufncode] = implicit_p;
+ builtin_info[ufncode].decl = decl;
+ builtin_info[ufncode].implicit_p = implicit_p;
+ builtin_info[ufncode].declared_p = false;
}
/* Set the implicit flag for a builtin function. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode)
- && builtin_info.decl[uns_fncode] != NULL_TREE);
+ && builtin_info[uns_fncode].decl != NULL_TREE);
- builtin_info.implicit_p[uns_fncode] = implicit_p;
+ builtin_info[uns_fncode].implicit_p = implicit_p;
+}
+
+/* Set the declared flag for a builtin function. */
+
+static inline void
+set_builtin_decl_declared_p (enum built_in_function fncode, bool declared_p)
+{
+ size_t uns_fncode = (size_t)fncode;
+
+ gcc_checking_assert (BUILTIN_VALID_P (fncode)
+ && builtin_info[uns_fncode].decl != NULL_TREE);
+
+ builtin_info[uns_fncode].declared_p = declared_p;
}
/* Return whether the standard builtin function can be used as an explicit
builtin_decl_explicit_p (enum built_in_function fncode)
{
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return (builtin_info.decl[(size_t)fncode] != NULL_TREE);
+ return (builtin_info[(size_t)fncode].decl != NULL_TREE);
}
/* Return whether the standard builtin function can be used implicitly. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return (builtin_info.decl[uns_fncode] != NULL_TREE
- && builtin_info.implicit_p[uns_fncode]);
+ return (builtin_info[uns_fncode].decl != NULL_TREE
+ && builtin_info[uns_fncode].implicit_p);
+}
+
+/* Return whether the standard builtin function was declared. */
+
+static inline bool
+builtin_decl_declared_p (enum built_in_function fncode)
+{
+ size_t uns_fncode = (size_t)fncode;
+
+ gcc_checking_assert (BUILTIN_VALID_P (fncode));
+ return (builtin_info[uns_fncode].decl != NULL_TREE
+ && builtin_info[uns_fncode].declared_p);
}
/* Return true if T (assumed to be a DECL) is a global variable.