{ "always_inline", 0, 0, true, false, false,
handle_always_inline_attribute },
{ "flatten", 0, 0, true, false, false,
- handle_flatten_attribute },
+ handle_flatten_attribute },
{ "used", 0, 0, true, false, false,
handle_used_attribute },
{ "unused", 0, 0, false, false, false,
{
/* Let the back-end know about this variable. */
if (!anon_aggr_type_p (TREE_TYPE (decl)))
- emit_local_var (decl);
+ emit_local_var (decl);
else
- expand_anon_union_decl (decl, NULL_TREE,
- DECL_ANON_UNION_ELEMS (decl));
+ expand_anon_union_decl (decl, NULL_TREE,
+ DECL_ANON_UNION_ELEMS (decl));
}
else
return 0;
/* Print a warning about casts that might indicate violation
of strict aliasing rules if -Wstrict-aliasing is used and
- strict aliasing mode is in effect. otype is the original
- TREE_TYPE of expr, and type the type we're casting to. */
+ strict aliasing mode is in effect. OTYPE is the original
+ TREE_TYPE of EXPR, and TYPE the type we're casting to. */
void
-strict_aliasing_warning(tree otype, tree type, tree expr)
+strict_aliasing_warning (tree otype, tree type, tree expr)
{
if (flag_strict_aliasing && warn_strict_aliasing
&& POINTER_TYPE_P (type) && POINTER_TYPE_P (otype)
{
return targetm.vector_opaque_p (t1)
|| targetm.vector_opaque_p (t2)
- || (tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
- && (TREE_CODE (TREE_TYPE (t1)) != REAL_TYPE ||
+ || (tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
+ && (TREE_CODE (TREE_TYPE (t1)) != REAL_TYPE ||
TYPE_PRECISION (t1) == TYPE_PRECISION (t2))
&& INTEGRAL_TYPE_P (TREE_TYPE (t1))
== INTEGRAL_TYPE_P (TREE_TYPE (t2)));
/* Do not diagnose overflow in a constant expression merely
because a conversion overflowed. */
- TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (expr);
+ TREE_CONSTANT_OVERFLOW (t) = CONSTANT_CLASS_P (expr)
+ && TREE_CONSTANT_OVERFLOW (expr);
/* No warning for converting 0x80000000 to int. */
if (!(TYPE_UNSIGNED (type) < TYPE_UNSIGNED (TREE_TYPE (expr))
default:
/* For other expressions, simply recurse on their operands.
- Manual tail recursion for unary expressions.
+ Manual tail recursion for unary expressions.
Other non-expressions need not be processed. */
if (cl == tcc_unary)
{
{
tree inner = TREE_OPERAND (expr, 0);
if (DECL_P (inner)
- && (TREE_CODE (inner) == PARM_DECL || !DECL_WEAK (inner)))
+ && (TREE_CODE (inner) == PARM_DECL
+ || TREE_CODE (inner) == LABEL_DECL
+ || !DECL_WEAK (inner)))
{
/* Common Ada/Pascal programmer's mistake. We always warn
about this since it is so bad. */
- warning (OPT_Walways_true, "the address of %qD, will always evaluate as %<true%>",
+ warning (OPT_Walways_true, "the address of %qD will always evaluate as %<true%>",
inner);
return truthvalue_true_node;
}
But, the standard is wrong. In particular, this code is
legal C++:
- int *ip;
- int **ipp = &ip;
- const int* const* cipp = ipp;
+ int *ip;
+ int **ipp = &ip;
+ const int* const* cipp = ipp;
And, it doesn't make sense for that to be legal unless you
can dereference IPP and CIPP. So, we ignore cv-qualifiers on
NONANSI_P, ATTRS, IMPLICIT, COND) \
if (NAME && COND) \
def_builtin_1 (ENUM, NAME, CLASS, \
- builtin_types[(int) TYPE], \
- builtin_types[(int) LIBTYPE], \
- BOTH_P, FALLBACK_P, NONANSI_P, \
- built_in_attributes[(int) ATTRS], IMPLICIT);
+ builtin_types[(int) TYPE], \
+ builtin_types[(int) LIBTYPE], \
+ BOTH_P, FALLBACK_P, NONANSI_P, \
+ built_in_attributes[(int) ATTRS], IMPLICIT);
#include "builtins.def"
#undef DEF_BUILTIN
{
tree type = TREE_VALUE (t);
+ if (type == error_mark_node)
+ continue;
+
if (TREE_CHAIN (t) == 0 && type != void_type_node)
return 0;
if (low_value && high_value)
{
/* If the LOW_VALUE and HIGH_VALUE are the same, then this isn't
- really a case range, even though it was written that way.
- Remove the HIGH_VALUE to simplify later processing. */
+ really a case range, even though it was written that way.
+ Remove the HIGH_VALUE to simplify later processing. */
if (tree_int_cst_equal (low_value, high_value))
high_value = NULL_TREE;
else if (!tree_int_cst_lt (low_value, high_value))
(splay_tree_key) low_value);
high_bound = splay_tree_successor (cases,
(splay_tree_key) low_value);
-
+
/* It is smaller than the LOW_VALUE, so there is no need to check
- unless the LOW_BOUND is in fact itself a case range. */
+ unless the LOW_BOUND is in fact itself a case range. */
if (low_bound
&& CASE_HIGH ((tree) low_bound->value)
&& tree_int_cst_compare (CASE_HIGH ((tree) low_bound->value),
if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
*node = build_variant_type_copy (*node);
TYPE_PACKED (*node) = 1;
- if (TYPE_MAIN_VARIANT (*node) == *node)
- {
- /* If it is the main variant, then pack the other variants
- too. This happens in,
-
- struct Foo {
- struct Foo const *ptr; // creates a variant w/o packed flag
- } __ attribute__((packed)); // packs it now.
- */
- tree probe;
-
- for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
- TYPE_PACKED (probe) = 1;
- }
}
else if (TREE_CODE (*node) == FIELD_DECL)
{
static tree
handle_flatten_attribute (tree *node, tree name,
- tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
/* Do nothing else, just set the attribute. We'll get at
"%qE attribute have effect only on public objects", name);
*no_add_attrs = true;
}
- else if (TREE_CODE (node) == FUNCTION_DECL)
- {
- struct cgraph_node *n = cgraph_node (node);
- n->local.externally_visible = true;
- if (n->local.finalized)
- cgraph_mark_needed_node (n);
- }
- else if (TREE_CODE (node) == VAR_DECL)
- {
- struct cgraph_varpool_node *n = cgraph_varpool_node (node);
- n->externally_visible = true;
- if (n->finalized)
- cgraph_varpool_mark_needed_node (n);
- }
+ else if (TREE_CODE (node) == FUNCTION_DECL
+ || TREE_CODE (node) == VAR_DECL)
+ ;
else
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
return NULL_TREE;
}
- if (TREE_CODE (type) == POINTER_TYPE)
+ if (TREE_CODE (type) == POINTER_TYPE)
fn = build_pointer_type_for_mode;
else
fn = build_reference_type_for_mode;
typefm = fn (TREE_TYPE (type), mode, false);
}
else
- typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
+ typefm = lang_hooks.types.type_for_mode (mode, TYPE_UNSIGNED (type));
if (typefm == NULL_TREE)
{
{
tree attr = NULL_TREE;
+ /* We must ignore the attribute when it is associated with
+ local-scoped decls, since attribute alias is ignored and many
+ such symbols do not even have a DECL_WEAK field. */
+ if (decl_function_context (*node) || current_function_decl)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored", name);
+ *no_add_attrs = true;
+ return NULL_TREE;
+ }
+
/* The idea here is that `weakref("name")' mutates into `weakref,
alias("name")', and weakref without arguments, in turn,
implicitly adds weak. */
static tree
handle_visibility_attribute (tree *node, tree name, tree args,
int ARG_UNUSED (flags),
- bool *no_add_attrs)
+ bool *ARG_UNUSED (no_add_attrs))
{
tree decl = *node;
tree id = TREE_VALUE (args);
-
- *no_add_attrs = true;
+ enum symbol_visibility vis;
if (TYPE_P (*node))
{
- if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
- {
- warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
- name);
- return NULL_TREE;
- }
+ if (TREE_CODE (*node) == ENUMERAL_TYPE)
+ /* OK */;
+ else if (TREE_CODE (*node) != RECORD_TYPE && TREE_CODE (*node) != UNION_TYPE)
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored on non-class types",
+ name);
+ return NULL_TREE;
+ }
+ else if (TYPE_FIELDS (*node))
+ {
+ error ("%qE attribute ignored because %qT is already defined",
+ name, *node);
+ return NULL_TREE;
+ }
}
else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl))
{
{
decl = TYPE_NAME (decl);
if (!decl)
- return NULL_TREE;
+ return NULL_TREE;
if (TREE_CODE (decl) == IDENTIFIER_NODE)
{
warning (OPT_Wattributes, "%qE attribute ignored on types",
}
if (strcmp (TREE_STRING_POINTER (id), "default") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ vis = VISIBILITY_DEFAULT;
else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_INTERNAL;
+ vis = VISIBILITY_INTERNAL;
else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ vis = VISIBILITY_HIDDEN;
else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0)
- DECL_VISIBILITY (decl) = VISIBILITY_PROTECTED;
+ vis = VISIBILITY_PROTECTED;
else
- error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+ {
+ error ("visibility argument must be one of \"default\", \"hidden\", \"protected\" or \"internal\"");
+ vis = VISIBILITY_DEFAULT;
+ }
+
+ if (DECL_VISIBILITY_SPECIFIED (decl)
+ && vis != DECL_VISIBILITY (decl)
+ && lookup_attribute ("visibility", (TYPE_P (*node)
+ ? TYPE_ATTRIBUTES (*node)
+ : DECL_ATTRIBUTES (decl))))
+ error ("%qD redeclared with different visibility", decl);
+
+ DECL_VISIBILITY (decl) = vis;
DECL_VISIBILITY_SPECIFIED (decl) = 1;
- /* For decls only, go ahead and attach the attribute to the node as well.
- This is needed so we can determine whether we have VISIBILITY_DEFAULT
- because the visibility was not specified, or because it was explicitly
- overridden from the class visibility. */
- if (DECL_P (*node))
- *no_add_attrs = false;
+ /* Go ahead and attach the attribute to the node as well. This is needed
+ so we can determine whether we have VISIBILITY_DEFAULT because the
+ visibility was not specified, or because it was explicitly overridden
+ from the containing scope. */
return NULL_TREE;
}
return true;
}
+ /* Set default visibility to whatever the user supplied with
+ visibility_specified depending on #pragma GCC visibility. */
+ if (!DECL_VISIBILITY_SPECIFIED (decl))
+ {
+ DECL_VISIBILITY (decl) = default_visibility;
+ DECL_VISIBILITY_SPECIFIED (decl) = visibility_options.inpragma;
+ }
return false;
}
typelist = TREE_CHAIN (typelist);
params = TREE_CHAIN (params);
}
-
+
if (typelist || !params)
warning (OPT_Wformat,
"not enough variable arguments to fit a sentinel");
else
- {
+ {
tree sentinel, end;
unsigned pos = 0;
-
+
if (TREE_VALUE (attr))
{
tree p = TREE_VALUE (TREE_VALUE (attr));
as wide as a pointer, and we don't want to force
users to cast the NULL they have written there.
We warn with -Wstrict-null-sentinel, though. */
- && (warn_strict_null_sentinel
+ && (warn_strict_null_sentinel
|| null_node != TREE_VALUE (sentinel)))
warning (OPT_Wformat, "missing sentinel in function call");
}
params = TREE_CHAIN (params);
if (VOID_TYPE_P (TREE_VALUE (params)))
- {
+ {
warning (OPT_Wattributes,
"%qE attribute only applies to variadic functions", name);
*no_add_attrs = true;
}
}
-
+
if (args)
{
tree position = TREE_VALUE (args);
if (TREE_CODE (position) != INTEGER_CST)
- {
+ {
warning (0, "requested position is not an integer constant");
*no_add_attrs = true;
}
else
- {
+ {
if (tree_int_cst_lt (position, integer_zero_node))
{
warning (0, "requested position is less than zero");
}
}
}
-
+
return NULL_TREE;
}
\f
unsigned int val = TREE_INT_CST_LOW (value);
const char *const ell = (token == CPP_CHAR) ? "" : "L";
if (val <= UCHAR_MAX && ISGRAPH (val))
- message = catenate_messages (gmsgid, " before %s'%c'");
+ message = catenate_messages (gmsgid, " before %s'%c'");
else
- message = catenate_messages (gmsgid, " before %s'\\x%x'");
+ message = catenate_messages (gmsgid, " before %s'\\x%x'");
error (message, ell, val);
free (message);
error (message);
free (message);
}
-#undef catenate_messages
+#undef catenate_messages
}
/* Walk a gimplified function and warn for functions whose return value is
case ERROR_MARK:
return expr;
+ case VAR_DECL:
+ error ("cannot apply %<offsetof%> to static data member %qD", expr);
+ return error_mark_node;
+
case INDIRECT_REF:
return size_zero_node;
return 0;
}
-/* A helper function for resolve_overloaded_builtin. Adds casts to
+/* A helper function for resolve_overloaded_builtin. Adds casts to
PARAMS to make arguments match up with those of FUNCTION. Drops
the variadic arguments at the end. Returns false if some error
was encountered; true on success. */
return true;
}
-/* A helper function for resolve_overloaded_builtin. Adds a cast to
+/* A helper function for resolve_overloaded_builtin. Adds a cast to
RESULT to make it match the type of the first pointer argument in
PARAMS. */
break;
case BUILT_IN_MD:
if (targetm.resolve_overloaded_builtin)
- return targetm.resolve_overloaded_builtin (function, params);
+ return targetm.resolve_overloaded_builtin (function, params);
else
- return NULL_TREE;
+ return NULL_TREE;
default:
return NULL_TREE;
}
-
+
/* Handle BUILT_IN_NORMAL here. */
switch (orig_code)
{