gcc/gcc/testsuite/gcc.dg/attr-unavailable-1.c

89 lines
2.8 KiB
C
Raw Normal View History

C-family: Add attribute 'unavailable'. If an interface is marked 'deprecated' then, presumably, at some point it will be withdrawn and no longer available. The 'unavailable' attribute makes it possible to mark up interfaces to indicate this status. It is used quite extensively in some codebases where a single set of headers can be used to permit code generation for multiple system versions. From a configuration perspective, it also allows a compile test to determine that an interface is missing - rather than requiring a link test. The implementation follows the pattern of attribute deprecated, but produces an error (where deprecation produces a warning). This attribute has been implemented in clang for some years. Signed-off-by: Iain Sandoe <iain@sandoe.co.uk> gcc/c-family/ChangeLog: * c-attribs.c (handle_unavailable_attribute): New. gcc/c/ChangeLog: * c-decl.c (enum deprecated_states): Add unavailable state. (merge_decls): Copy unavailability. (quals_from_declspecs): Handle unavailable case. (start_decl): Amend the logic handling suppression of nested deprecation states to include unavailability. (smallest_type_quals_location): Amend comment. (grokdeclarator): Handle the unavailable deprecation state. (declspecs_add_type): Set TREE_UNAVAILABLE from the decl specs. * c-tree.h (struct c_declspecs): Add unavailable_p. * c-typeck.c (build_component_ref): Handle unavailability. (build_external_ref): Likewise. gcc/cp/ChangeLog: * call.c (build_over_call): Handle unavailable state in addition to deprecation. * class.c (type_build_ctor_call): Likewise. (type_build_dtor_call): Likewise. * cp-tree.h: Rename cp_warn_deprecated_use to cp_handle_deprecated_or_unavailable. * decl.c (duplicate_decls): Merge unavailability. (grokdeclarator): Handle unavailability in addition to deprecation. (type_is_unavailable): New. (grokparms): Handle unavailability in addition to deprecation. * decl.h (enum deprecated_states): Add UNAVAILABLE_DEPRECATED_SUPPRESS. * decl2.c (cplus_decl_attributes): Propagate unavailability to templates. (cp_warn_deprecated_use): Rename to ... (cp_handle_deprecated_or_unavailable): ... this and amend to handle the unavailable case. It remains a warning in the case of deprecation but becomes an error in the case of unavailability. (cp_warn_deprecated_use_scopes): Handle unavailability. (mark_used): Likewise. * parser.c (cp_parser_template_name): Likewise. (cp_parser_template_argument): Likewise. (cp_parser_parameter_declaration_list): Likewise. * typeck.c (build_class_member_access_expr): Likewise. (finish_class_member_access_expr): Likewise. * typeck2.c (build_functional_cast_1): Likewise. gcc/ChangeLog: * doc/extend.texi: Document unavailable attribute. * print-tree.c (print_node): Handle unavailable attribute. * tree-core.h (struct tree_base): Add a bit to carry unavailability. * tree.c (error_unavailable_use): New. * tree.h (TREE_UNAVAILABLE): New. (error_unavailable_use): New. gcc/objc/ChangeLog: * objc-act.c (objc_add_property_declaration): Register unavailable attribute. (maybe_make_artificial_property_decl): Set available. (objc_maybe_build_component_ref): Generalise to the method prototype to count availability. (objc_build_class_component_ref): Likewise. (build_private_template): Likewise. (objc_decl_method_attributes): Handle unavailable attribute. (lookup_method_in_hash_lists): Amend comments. (objc_finish_message_expr): Handle unavailability in addition to deprecation. (start_class): Likewise. (finish_class): Likewise. (lookup_protocol): Likewise. (objc_declare_protocol): Likewise. (start_protocol): Register unavailable attribute. (really_start_method): Likewise. (objc_gimplify_property_ref): Emit error on encountering an unavailable entity (and a warning for a deprecated one). gcc/testsuite/ChangeLog: * g++.dg/ext/attr-unavailable-1.C: New test. * g++.dg/ext/attr-unavailable-2.C: New test. * g++.dg/ext/attr-unavailable-3.C: New test. * g++.dg/ext/attr-unavailable-4.C: New test. * g++.dg/ext/attr-unavailable-5.C: New test. * g++.dg/ext/attr-unavailable-6.C: New test. * g++.dg/ext/attr-unavailable-7.C: New test. * g++.dg/ext/attr-unavailable-8.C: New test. * g++.dg/ext/attr-unavailable-9.C: New test. * gcc.dg/attr-unavailable-1.c: New test. * gcc.dg/attr-unavailable-2.c: New test. * gcc.dg/attr-unavailable-3.c: New test. * gcc.dg/attr-unavailable-4.c: New test. * gcc.dg/attr-unavailable-5.c: New test. * gcc.dg/attr-unavailable-6.c: New test. * obj-c++.dg/attributes/method-unavailable-1.mm: New test. * obj-c++.dg/attributes/method-unavailable-2.mm: New test. * obj-c++.dg/attributes/method-unavailable-3.mm: New test. * obj-c++.dg/property/at-property-unavailable-1.mm: New test. * obj-c++.dg/property/at-property-unavailable-2.mm: New test. * obj-c++.dg/property/dotsyntax-unavailable-1.mm: New test. * objc.dg/attributes/method-unavailable-1.m: New test. * objc.dg/attributes/method-unavailable-2.m: New test. * objc.dg/attributes/method-unavailable-3.m: New test. * objc.dg/property/at-property-unavailable-1.m: New test. * objc.dg/property/at-property-unavailable-2.m: New test. * objc.dg/property/dotsyntax-unavailable-1.m: New test.
2020-11-08 10:04:07 +01:00
/* Test __attribute__ ((unavailable)) */
/* { dg-do compile } */
/* { dg-options "" } */
typedef int INT1 __attribute__((unavailable));
typedef INT1 INT2 __attribute__ ((__unavailable__));
typedef INT1 INT1a; /* { dg-error "'INT1' is unavailable" "" } */
typedef INT1 INT1b __attribute__ ((unavailable));
INT1 should_be_unavailable; /* { dg-error "'INT1' is unavailable" "" } */
INT1a should_not_be_unavailable;
INT1 f1(void) __attribute__ ((unavailable));
INT1 f2(void) { return 0; } /* { dg-error "'INT1' is unavailable" "" } */
INT2 f3(void) __attribute__ ((__unavailable__));
INT2 f4(void) { return 0; } /* { dg-error "'INT2' is unavailable" "" } */
int f5(INT2 x); /* { dg-error "'INT2' is unavailable" "" } */
int f6(INT2 x) __attribute__ ((__unavailable__)); /* { dg-error "'INT2' is unavailable" "" } */
typedef enum {red, green, blue} Color __attribute__((unavailable));
int g1;
int g2 __attribute__ ((unavailable));
int g3 __attribute__ ((__unavailable__));
Color k; /* { dg-error "'Color' is unavailable" "" } */
typedef struct {
int field1;
int field2 __attribute__ ((unavailable));
int field3;
int field4 __attribute__ ((__unavailable__));
union {
int field5;
int field6 __attribute__ ((unavailable));
} u1;
int field7:1;
int field8:1 __attribute__ ((unavailable));
union {
int field9;
int field10;
} u2 __attribute__ ((unavailable));
} S1;
int func1()
{
INT1 w; /* { dg-error "'INT1' is unavailable" "" } */
int x __attribute__ ((unavailable));
int y __attribute__ ((__unavailable__));
int z;
int (*pf)() = f1; /* { dg-error "'f1' is unavailable" "" } */
z = w + x + y + g1 + g2 + g3; /* { dg-error "'x' is unavailable" "" } */
/* { dg-error "'y' is unavailable" "y" { target *-*-* } .-1 } */
/* { dg-error "'g2' is unavailable" "g2" { target *-*-* } .-2 } */
/* { dg-error "'g3' is unavailable" "g3" { target *-*-* } .-3 } */
return f1(); /* { dg-error "'f1' is unavailable" "f1" } */
}
int func2(S1 *p)
{
S1 lp;
if (p->field1)
return p->field2; /* { dg-error "'field2' is unavailable" "" } */
else if (lp.field4) /* { dg-error "'field4' is unavailable" "" } */
return p->field3;
p->u1.field5 = g1 + p->field7;
p->u2.field9; /* { dg-error "'u2' is unavailable" "" } */
return p->u1.field6 + p->field8; /* { dg-error "'field6' is unavailable" "" } */
/* { dg-error "'field8' is unavailable" "field8" { target *-*-* } .-1 } */
}
struct SS1 {
int x;
INT1 y; /* { dg-error "'INT1' is unavailable" "" } */
} __attribute__ ((unavailable));
struct SS1 *p1; /* { dg-error "'SS1' is unavailable" "" } */
struct __attribute__ ((__unavailable__)) SS2 {
int x;
INT1 y; /* { dg-error "'INT1' is unavailable" "" } */
};
struct SS2 *p2; /* { dg-error "'SS2' is unavailable" "" } */