From: Marek Polacek Date: Wed, 11 May 2016 17:07:37 +0000 (+0000) Subject: re PR c++/71024 (Missing warning for contradictory attributes) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5c3a10fbc1d4e91287b635d6ff068c8f80dff8cd;p=gcc.git re PR c++/71024 (Missing warning for contradictory attributes) PR c++/71024 * c-common.c (diagnose_mismatched_attributes): New function. * c-common.h (diagnose_mismatched_attributes): Declare. * c-decl.c (diagnose_mismatched_decls): Factor out code to diagnose_mismatched_attributes and call it. * decl.c (duplicate_decls): Call diagnose_mismatched_decls. * c-c++-common/attributes-3.c: New test. From-SVN: r236129 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index e1ba43945c6..0b31517a118 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2016-05-11 Marek Polacek + + PR c++/71024 + * c-common.c (diagnose_mismatched_attributes): New function. + * c-common.h (diagnose_mismatched_attributes): Declare. + 2016-05-04 Marek Polacek * c.opt (Wdangling-else): New option. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 63a18c866eb..665448c2298 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -12824,4 +12824,58 @@ get_source_date_epoch () return (time_t) epoch; } +/* Check and possibly warn if two declarations have contradictory + attributes, such as always_inline vs. noinline. */ + +bool +diagnose_mismatched_attributes (tree olddecl, tree newdecl) +{ + bool warned = false; + + tree a1 = lookup_attribute ("optimize", DECL_ATTRIBUTES (olddecl)); + tree a2 = lookup_attribute ("optimize", DECL_ATTRIBUTES (newdecl)); + /* An optimization attribute applied on a declaration after the + definition is likely not what the user wanted. */ + if (a2 != NULL_TREE + && DECL_SAVED_TREE (olddecl) != NULL_TREE + && (a1 == NULL_TREE || !attribute_list_equal (a1, a2))) + warned |= warning (OPT_Wattributes, + "optimization attribute on %qD follows " + "definition but the attribute doesn%'t match", + newdecl); + + /* Diagnose inline __attribute__ ((noinline)) which is silly. */ + if (DECL_DECLARED_INLINE_P (newdecl) + && DECL_UNINLINABLE (olddecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, "inline declaration of %qD follows " + "declaration with attribute noinline", newdecl); + else if (DECL_DECLARED_INLINE_P (olddecl) + && DECL_UNINLINABLE (newdecl) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " + "noinline follows inline declaration ", newdecl); + else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "noinline", "always_inline"); + else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "always_inline", "noinline"); + else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "cold", "hot"); + else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl)) + && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl))) + warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute " + "%qs follows declaration with attribute %qs", + newdecl, "hot", "cold"); + return warned; +} + #include "gt-c-family-c-common.h" diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 4454d084724..0ee9f567123 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -850,6 +850,7 @@ extern bool keyword_is_type_qualifier (enum rid); extern bool keyword_is_decl_specifier (enum rid); extern bool cxx_fundamental_alignment_p (unsigned); extern bool pointer_to_zero_sized_aggr_p (tree); +extern bool diagnose_mismatched_attributes (tree, tree); #define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, false, 1) #define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, false, 1) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 9387c73b35e..70444002652 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2016-05-11 Marek Polacek + + PR c++/71024 + * c-decl.c (diagnose_mismatched_decls): Factor out code to + diagnose_mismatched_attributes and call it. + 2016-05-10 Marek Polacek PR c/70255 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 9c09536c18e..6ba0e0e52a5 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -2227,55 +2227,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, } if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - tree a1 = lookup_attribute ("optimize", DECL_ATTRIBUTES (olddecl)); - tree a2 = lookup_attribute ("optimize", DECL_ATTRIBUTES (newdecl)); - /* An optimization attribute applied on a declaration after the - definition is likely not what the user wanted. */ - if (a2 != NULL_TREE - && DECL_SAVED_TREE (olddecl) != NULL_TREE - && (a1 == NULL_TREE || !attribute_list_equal (a1, a2))) - warned |= warning (OPT_Wattributes, - "optimization attribute on %qD follows " - "definition but the attribute doesn%'t match", - newdecl); - - /* Diagnose inline __attribute__ ((noinline)) which is silly. */ - if (DECL_DECLARED_INLINE_P (newdecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - warned |= warning (OPT_Wattributes, - "inline declaration of %qD follows " - "declaration with attribute noinline", newdecl); - else if (DECL_DECLARED_INLINE_P (olddecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute " - "noinline follows inline declaration ", newdecl); - else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)) - && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl))) - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute " - "%qs follows declaration with attribute %qs", - newdecl, "noinline", "always_inline"); - else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl)) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute " - "%qs follows declaration with attribute %qs", - newdecl, "always_inline", "noinline"); - else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl)) - && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl))) - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute %qs follows " - "declaration with attribute %qs", newdecl, "cold", - "hot"); - else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl)) - && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl))) - warned |= warning (OPT_Wattributes, - "declaration of %q+D with attribute %qs follows " - "declaration with attribute %qs", newdecl, "hot", - "cold"); - } + warned |= diagnose_mismatched_attributes (olddecl, newdecl); else /* PARM_DECL, VAR_DECL */ { /* Redeclaration of a parameter is a constraint violation (this is diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9006b341a7a..fda48a700b9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2016-05-11 Marek Polacek + + PR c++/71024 + * decl.c (duplicate_decls): Call diagnose_mismatched_decls. + 2016-05-05 Jakub Jelinek * parser.c (cp_parser_selection_statement): For RID_SWITCH, diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8dbc730f3a6..126d8707e45 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1389,38 +1389,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) if (DECL_P (olddecl) && TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (olddecl) == FUNCTION_DECL - && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl))) - { - if (DECL_DECLARED_INLINE_P (newdecl) - && DECL_UNINLINABLE (newdecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) - /* Already warned elsewhere. */; - else if (DECL_DECLARED_INLINE_P (olddecl) - && DECL_UNINLINABLE (olddecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - /* Already warned. */; - else if (DECL_DECLARED_INLINE_P (newdecl) - && DECL_UNINLINABLE (olddecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl))) - { - if (warning_at (DECL_SOURCE_LOCATION (newdecl), - OPT_Wattributes, "function %qD redeclared as inline", - newdecl)) - inform (DECL_SOURCE_LOCATION (olddecl), - "previous declaration of %qD with attribute noinline", - olddecl); - } - else if (DECL_DECLARED_INLINE_P (olddecl) - && DECL_UNINLINABLE (newdecl) - && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))) - { - if (warning_at (DECL_SOURCE_LOCATION (newdecl), - OPT_Wattributes, "function %qD redeclared with " - "attribute noinline", newdecl)) - inform (DECL_SOURCE_LOCATION (olddecl), - "previous declaration of %qD was inline", - olddecl); - } + && diagnose_mismatched_attributes (olddecl, newdecl)) + { + if (DECL_INITIAL (olddecl)) + inform (DECL_SOURCE_LOCATION (olddecl), + "previous definition of %q+D was here", olddecl); + else + inform (DECL_SOURCE_LOCATION (olddecl), + "previous declaration of %qD was here", olddecl); } /* Check for redeclaration and other discrepancies. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 839d0a0fa6a..93c8706aca6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-11 Marek Polacek + + PR c++/71024 + * c-c++-common/attributes-3.c: New test. + 2016-05-11 Nathan Sidwell * gcc.dg/pr68671.c: Xfail on PTX -- assembler crash. diff --git a/gcc/testsuite/c-c++-common/attributes-3.c b/gcc/testsuite/c-c++-common/attributes-3.c new file mode 100644 index 00000000000..821278c680f --- /dev/null +++ b/gcc/testsuite/c-c++-common/attributes-3.c @@ -0,0 +1,27 @@ +/* PR c++/71024 */ +/* { dg-do compile } */ +/* { dg-prune-output "declared but never defined" } */ + +void +fn0 (void) /* { dg-message "previous definition" } */ +{ +} +extern void __attribute__((optimize ("O2"))) fn0 (void); /* { dg-warning "optimization attribute" } */ + +extern __attribute__((noinline)) int fn1 (void); /* { dg-message "previous declaration" } */ +extern inline int fn1 (void); /* { dg-warning "inline declaration of" } */ + +extern inline int fn2 (void); /* { dg-message "previous declaration" } */ +extern __attribute__((noinline)) int fn2 (void); /* { dg-warning "attribute noinline follows inline declaration" } */ + +extern __attribute__((always_inline)) int fn3 (void); /* { dg-message "previous declaration" } */ +extern __attribute__((noinline)) int fn3 (void); /* { dg-warning "attribute .noinline. follows declaration with attribute .always_inline." } */ + +extern __attribute__((noinline)) int fn4 (void); /* { dg-message "previous declaration" } */ +extern __attribute__((always_inline)) int fn4 (void); /* { dg-warning "attribute .always_inline. follows declaration with attribute .noinline." } */ + +extern __attribute__((hot)) int fn5 (void); /* { dg-message "previous declaration" } */ +extern __attribute__((cold)) int fn5 (void); /* { dg-warning "attribute .cold. follows declaration with attribute .hot." } */ + +extern __attribute__((cold)) int fn6 (void); /* { dg-message "previous declaration" } */ +extern __attribute__((hot)) int fn6 (void); /* { dg-warning "attribute .hot. follows declaration with attribute .cold." } */