aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c133
1 files changed, 107 insertions, 26 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c46100d..a79a70b 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -974,7 +974,11 @@ grokfield (const cp_declarator *declarator,
if ((TREE_CODE (value) == FUNCTION_DECL
|| TREE_CODE (value) == TEMPLATE_DECL)
&& DECL_CONTEXT (value) != current_class_type)
- return value;
+ {
+ if (attrlist)
+ cplus_decl_attributes (&value, attrlist, 0);
+ return value;
+ }
/* Need to set this before push_template_decl. */
if (VAR_P (value))
@@ -1117,7 +1121,7 @@ grokbitfield (const cp_declarator *declarator,
&& !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (width)))
error ("width of bit-field %qD has non-integral type %qT", value,
TREE_TYPE (width));
- else
+ else if (!check_for_bare_parameter_packs (width))
{
/* Temporarily stash the width in DECL_BIT_FIELD_REPRESENTATIVE.
check_bitfield_decl picks it from there later and sets DECL_SIZE
@@ -1278,9 +1282,9 @@ save_template_attributes (tree *attr_p, tree *decl_p, int flags)
tree old_attrs = *q;
- /* Merge the late attributes at the beginning with the attribute
+ /* Place the late attributes at the beginning of the attribute
list. */
- late_attrs = merge_attributes (late_attrs, *q);
+ late_attrs = chainon (late_attrs, *q);
if (*q != late_attrs
&& !DECL_P (*decl_p)
&& !(flags & ATTR_FLAG_TYPE_IN_PLACE))
@@ -1547,7 +1551,7 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
return;
/* Add implicit "omp declare target" attribute if requested. */
- if (scope_chain->omp_declare_target_attribute
+ if (vec_safe_length (scope_chain->omp_declare_target_attribute)
&& ((VAR_P (*decl)
&& (TREE_STATIC (*decl) || DECL_EXTERNAL (*decl)))
|| TREE_CODE (*decl) == FUNCTION_DECL))
@@ -1580,6 +1584,31 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
cp_check_const_attributes (attributes);
+ if ((flag_openmp || flag_openmp_simd) && attributes != error_mark_node)
+ {
+ bool diagnosed = false;
+ for (tree *pa = &attributes; *pa; )
+ {
+ if (get_attribute_namespace (*pa) == omp_identifier)
+ {
+ tree name = get_attribute_name (*pa);
+ if (is_attribute_p ("directive", name)
+ || is_attribute_p ("sequence", name))
+ {
+ if (!diagnosed)
+ {
+ error ("%<omp::%E%> not allowed to be specified in this "
+ "context", name);
+ diagnosed = true;
+ }
+ *pa = TREE_CHAIN (*pa);
+ continue;
+ }
+ }
+ pa = &TREE_CHAIN (*pa);
+ }
+ }
+
if (TREE_CODE (*decl) == TEMPLATE_DECL)
decl = &DECL_TEMPLATE_RESULT (*decl);
@@ -1606,6 +1635,17 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
if (*decl == pattern)
TREE_DEPRECATED (tmpl) = true;
}
+
+ /* Likewise, propagate unavailability out to the template. */
+ if (TREE_UNAVAILABLE (*decl))
+ if (tree ti = get_template_info (*decl))
+ {
+ tree tmpl = TI_TEMPLATE (ti);
+ tree pattern = (TYPE_P (*decl) ? TREE_TYPE (tmpl)
+ : DECL_TEMPLATE_RESULT (tmpl));
+ if (*decl == pattern)
+ TREE_UNAVAILABLE (tmpl) = true;
+ }
}
/* Walks through the namespace- or function-scope anonymous union
@@ -2937,14 +2977,15 @@ reset_type_linkage (tree type)
SET_DECL_ASSEMBLER_NAME (vt, name);
reset_decl_linkage (vt);
}
- if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
- {
- tree name = mangle_typeinfo_for_type (type);
- DECL_NAME (ti) = name;
- SET_DECL_ASSEMBLER_NAME (ti, name);
- TREE_TYPE (name) = type;
- reset_decl_linkage (ti);
- }
+ if (!ANON_AGGR_TYPE_P (type))
+ if (tree ti = CLASSTYPE_TYPEINFO_VAR (type))
+ {
+ tree name = mangle_typeinfo_for_type (type);
+ DECL_NAME (ti) = name;
+ SET_DECL_ASSEMBLER_NAME (ti, name);
+ TREE_TYPE (name) = type;
+ reset_decl_linkage (ti);
+ }
for (tree m = TYPE_FIELDS (type); m; m = DECL_CHAIN (m))
{
tree mem = STRIP_TEMPLATE (m);
@@ -3418,6 +3459,12 @@ set_guard (tree guard)
static bool
var_defined_without_dynamic_init (tree var)
{
+ /* constinit vars are guaranteed to not have dynamic initializer,
+ but still registering the destructor counts as dynamic initialization. */
+ if (DECL_DECLARED_CONSTINIT_P (var)
+ && COMPLETE_TYPE_P (TREE_TYPE (var))
+ && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (var)))
+ return true;
/* If it's defined in another TU, we can't tell. */
if (DECL_EXTERNAL (var))
return false;
@@ -4525,7 +4572,7 @@ no_linkage_error (tree decl)
|| (errorcount + sorrycount > 0
&& DECL_LANG_SPECIFIC (decl)
&& DECL_TEMPLATE_INFO (decl)
- && TREE_NO_WARNING (decl))))
+ && warning_suppressed_p (decl /* What warning? */))))
/* In C++11 it's ok if the decl is defined. */
return;
@@ -5200,7 +5247,7 @@ c_parse_final_cleanups (void)
&& warning_at (DECL_SOURCE_LOCATION (decl), 0,
"inline function %qD used but never defined", decl))
/* Avoid a duplicate warning from check_global_declaration. */
- TREE_NO_WARNING (decl) = 1;
+ suppress_warning (decl, OPT_Wunused);
}
/* So must decls that use a type with no linkage. */
@@ -5463,14 +5510,47 @@ maybe_instantiate_decl (tree decl)
}
}
-/* Maybe warn if DECL is deprecated, subject to COMPLAIN. Returns whether or
- not a warning was emitted. */
+/* Error if the DECL is unavailable (unless this is currently suppressed).
+ Maybe warn if DECL is deprecated, subject to COMPLAIN. Returns true if
+ an error or warning was emitted. */
bool
-cp_warn_deprecated_use (tree decl, tsubst_flags_t complain)
+cp_handle_deprecated_or_unavailable (tree decl, tsubst_flags_t complain)
{
- if (!(complain & tf_warning) || !decl
- || deprecated_state == DEPRECATED_SUPPRESS)
+ if (!decl)
+ return false;
+
+ if ((complain & tf_error)
+ && deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
+ {
+ if (TREE_UNAVAILABLE (decl))
+ {
+ error_unavailable_use (decl, NULL_TREE);
+ return true;
+ }
+ else
+ {
+ /* Perhaps this is an unavailable typedef. */
+ if (TYPE_P (decl)
+ && TYPE_NAME (decl)
+ && TREE_UNAVAILABLE (TYPE_NAME (decl)))
+ {
+ decl = TYPE_NAME (decl);
+ /* Don't error within members of a unavailable type. */
+ if (TYPE_P (decl)
+ && currently_open_class (decl))
+ return false;
+
+ error_unavailable_use (decl, NULL_TREE);
+ return true;
+ }
+ }
+ /* Carry on to consider deprecatedness. */
+ }
+
+ if (!(complain & tf_warning)
+ || deprecated_state == DEPRECATED_SUPPRESS
+ || deprecated_state == UNAVAILABLE_DEPRECATED_SUPPRESS)
return false;
if (!TREE_DEPRECATED (decl))
@@ -5495,10 +5575,10 @@ cp_warn_deprecated_use (tree decl, tsubst_flags_t complain)
&& DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
&& copy_fn_p (decl))
{
- if (warn_deprecated_copy
- /* Don't warn about system library classes (c++/86342). */
- && (!DECL_IN_SYSTEM_HEADER (decl)
- || global_dc->dc_warn_system_headers))
+ /* Don't warn if the flag was disabled around the class definition
+ (c++/94492). */
+ if (warning_enabled_at (DECL_SOURCE_LOCATION (decl),
+ OPT_Wdeprecated_copy))
{
auto_diagnostic_group d;
tree ctx = DECL_CONTEXT (decl);
@@ -5529,7 +5609,8 @@ cp_warn_deprecated_use_scopes (tree scope)
&& scope != error_mark_node
&& scope != global_namespace)
{
- if (cp_warn_deprecated_use (scope))
+ if ((TREE_CODE (scope) == NAMESPACE_DECL || OVERLOAD_TYPE_P (scope))
+ && cp_handle_deprecated_or_unavailable (scope))
return;
if (TYPE_P (scope))
scope = CP_TYPE_CONTEXT (scope);
@@ -5641,7 +5722,7 @@ mark_used (tree decl, tsubst_flags_t complain)
TREE_USED (decl) = true;
}
- cp_warn_deprecated_use (decl, complain);
+ cp_handle_deprecated_or_unavailable (decl, complain);
/* We can only check DECL_ODR_USED on variables or functions with
DECL_LANG_SPECIFIC set, and these are also the only decls that we