From bffc62707f731f20ded6993e734a361945684955 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Thu, 12 Jul 2018 16:21:06 +0000 Subject: [PATCH] PR c/86453 - error: type variant differs by TYPE_PACKED in free_lang_data since r255469 gcc/ChangeLog: PR c/86453 * attribs.c (decl_attributes): Reject conflicting attributes before calling attribute handlers. gcc/testsuite/ChangeLog: PR c/86453 * c-c++-common/Wattributes.c: Adjust. * gcc.dg/Wattributes-10.c: New test. * g++.dg/Wattributes-3.C: Adjust. * gcc.dg/Wattributes-6.c: Adjust. * gcc.dg/pr18079.c: Adjust. * gcc.dg/torture/pr42363.c: Adjust. From-SVN: r262596 --- gcc/ChangeLog | 6 +++ gcc/attribs.c | 56 ++++++++++++------------ gcc/testsuite/ChangeLog | 10 +++++ gcc/testsuite/c-c++-common/Wattributes.c | 6 +-- gcc/testsuite/g++.dg/Wattributes-3.C | 3 ++ gcc/testsuite/gcc.dg/Wattributes-10.c | 26 +++++++++++ gcc/testsuite/gcc.dg/Wattributes-6.c | 6 +-- gcc/testsuite/gcc.dg/pr18079.c | 8 ++-- gcc/testsuite/gcc.dg/torture/pr42363.c | 6 ++- 9 files changed, 89 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/Wattributes-10.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec22e935611..7e24d18175a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-07-12 Martin Sebor + + PR c/86453 + * attribs.c (decl_attributes): Reject conflicting attributes before + calling attribute handlers. + 2018-07-12 Jan Hubicka * dumpfile.c (gcc::dump_manager::get_dump_file_name): Add PART diff --git a/gcc/attribs.c b/gcc/attribs.c index bfadf124dcb..efc879ba476 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -672,6 +672,35 @@ decl_attributes (tree *node, tree attributes, int flags, bool no_add_attrs = false; + /* Check for exclusions with other attributes on the current + declation as well as the last declaration of the same + symbol already processed (if one exists). Detect and + reject incompatible attributes. */ + bool built_in = flags & ATTR_FLAG_BUILT_IN; + if (spec->exclude + && (flag_checking || !built_in)) + { + /* Always check attributes on user-defined functions. + Check them on built-ins only when -fchecking is set. + Ignore __builtin_unreachable -- it's both const and + noreturn. */ + + if (!built_in + || !DECL_P (*anode) + || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE + && (DECL_FUNCTION_CODE (*anode) + != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE))) + { + bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec); + if (!no_add && anode != node) + no_add = diag_attr_exclusions (last_decl, *node, name, spec); + no_add_attrs |= no_add; + } + } + + if (no_add_attrs) + continue; + if (spec->handler != NULL) { int cxx11_flag = @@ -695,33 +724,6 @@ decl_attributes (tree *node, tree attributes, int flags, returned_attrs = chainon (ret, returned_attrs); } - /* If the attribute was successfully handled on its own and is - about to be added check for exclusions with other attributes - on the current declation as well as the last declaration of - the same symbol already processed (if one exists). */ - bool built_in = flags & ATTR_FLAG_BUILT_IN; - if (spec->exclude - && !no_add_attrs - && (flag_checking || !built_in)) - { - /* Always check attributes on user-defined functions. - Check them on built-ins only when -fchecking is set. - Ignore __builtin_unreachable -- it's both const and - noreturn. */ - - if (!built_in - || !DECL_P (*anode) - || (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE - && (DECL_FUNCTION_CODE (*anode) - != BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE))) - { - bool no_add = diag_attr_exclusions (last_decl, *anode, name, spec); - if (!no_add && anode != node) - no_add = diag_attr_exclusions (last_decl, *node, name, spec); - no_add_attrs |= no_add; - } - } - /* Layout the decl in case anything changed. */ if (spec->type_required && DECL_P (*node) && (VAR_P (*node) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d524e0d633d..7e8c380a691 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2018-07-12 Martin Sebor + + PR c/86453 + * c-c++-common/Wattributes.c: Adjust. + * gcc.dg/Wattributes-10.c: New test. + * g++.dg/Wattributes-3.C: Adjust. + * gcc.dg/Wattributes-6.c: Adjust. + * gcc.dg/pr18079.c: Adjust. + * gcc.dg/torture/pr42363.c: Adjust. + 2018-07-12 Julia Koval * gcc.target/i386/avx512vl-vpclmulqdq-2.c: Remove 128bit diff --git a/gcc/testsuite/c-c++-common/Wattributes.c b/gcc/testsuite/c-c++-common/Wattributes.c index 40a29856ec6..6925d4eaacd 100644 --- a/gcc/testsuite/c-c++-common/Wattributes.c +++ b/gcc/testsuite/c-c++-common/Wattributes.c @@ -39,13 +39,13 @@ PackedPacked { int i; }; aligned and packed on a function declaration. */ void ATTR ((aligned (8), packed)) -faligned8_1 (void); /* { dg-warning ".packed. attribute ignored" } */ +faligned8_1 (void); /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */ void ATTR ((aligned (8))) -faligned8_2 (void); /* { dg-message "previous declaration here" "" { xfail *-*-* } } */ +faligned8_2 (void); /* { dg-message "previous declaration here" } */ void ATTR ((packed)) -faligned8_2 (void); /* { dg-warning ".packed. attribute ignored" } */ +faligned8_2 (void); /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */ /* Exercise the handling of the mutually exclusive attributes always_inline and noinline (in that order). */ diff --git a/gcc/testsuite/g++.dg/Wattributes-3.C b/gcc/testsuite/g++.dg/Wattributes-3.C index a70176b14b6..208ec669655 100644 --- a/gcc/testsuite/g++.dg/Wattributes-3.C +++ b/gcc/testsuite/g++.dg/Wattributes-3.C @@ -26,6 +26,8 @@ B::operator char () const { return 0; } ATTR ((__noinline__)) B::operator int () const // { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } +// { dg-warning "function might not be inlinable" "" { target *-*-* } .-1 } + { return 0; } @@ -43,6 +45,7 @@ C::operator char () { return 0; } ATTR ((__noinline__)) C::operator short () // { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } +// { dg-warning "function might not be inlinable" "" { target *-*-* } .-1 } { return 0; } inline ATTR ((__noinline__)) diff --git a/gcc/testsuite/gcc.dg/Wattributes-10.c b/gcc/testsuite/gcc.dg/Wattributes-10.c new file mode 100644 index 00000000000..f88d7a2fb46 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wattributes-10.c @@ -0,0 +1,26 @@ +/* PR middle-end/86453 - error: type variant differs by TYPE_PACKED in + free_lang_data since r255469 + { dg-do compile } + { dg-options "-Wall -ftrack-macro-expansion=0" } */ + +#define A(expr) do { int a[1 - 2 * !(expr)]; (void)&a; } while (0) + +struct S +{ + int* __attribute__ ((aligned (16))) paligned; + int* __attribute__ ((packed)) ppacked; /* { dg-warning ".packed. attribute ignored for type .int \\\*." } */ + + int* __attribute__ ((aligned (16), packed)) qaligned; /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */ + int* __attribute__ ((packed, aligned (16))) qpacked; /* { dg-warning ".packed. attribute ignored for type .int \\\*." } */ +} s; + +void test (void) +{ + /* Verify that attributes reported ignored really are ignored + and not applied. */ + + A (__alignof__ (s.paligned) == 16); + A (__alignof__ (s.ppacked) < 16); + A (__alignof__ (s.qaligned) == 16); + A (__alignof__ (s.qpacked) == __alignof__ (s.paligned)); +} diff --git a/gcc/testsuite/gcc.dg/Wattributes-6.c b/gcc/testsuite/gcc.dg/Wattributes-6.c index a260d018dcf..b2ea7db1833 100644 --- a/gcc/testsuite/gcc.dg/Wattributes-6.c +++ b/gcc/testsuite/gcc.dg/Wattributes-6.c @@ -39,13 +39,13 @@ PackedPacked { int i; }; aligned and packed on a function declaration. */ void ATTR ((aligned (8), packed)) -faligned8_1 (void); /* { dg-warning ".packed. attribute ignored" } */ +faligned8_1 (void); /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */ void ATTR ((aligned (8))) -faligned8_2 (void); /* { dg-message "previous declaration here" "" { xfail *-*-* } } */ +faligned8_2 (void); /* { dg-message "previous declaration here" } */ void ATTR ((packed)) -faligned8_2 (void); /* { dg-warning ".packed. attribute ignored" } */ +faligned8_2 (void); /* { dg-warning "ignoring attribute .packed. because it conflicts with attribute .aligned." } */ /* Exercise the handling of the mutually exclusive attributes always_inline and noinline (in that order). */ diff --git a/gcc/testsuite/gcc.dg/pr18079.c b/gcc/testsuite/gcc.dg/pr18079.c index b84cdebde3f..a37dc1880b2 100644 --- a/gcc/testsuite/gcc.dg/pr18079.c +++ b/gcc/testsuite/gcc.dg/pr18079.c @@ -6,14 +6,14 @@ __attribute__ ((noinline)) __attribute__ ((always_inline)) int fn1 (int r) -{ /* { dg-warning "attribute ignored due to conflict" } */ +{ /* { dg-warning "ignoring attribute .always_inline. because it conflicts with attribute .noinline." } */ return r & 4; } __attribute__ ((noinline, always_inline)) int fn2 (int r) -{ /* { dg-warning "attribute ignored due to conflict" } */ +{ /* { dg-warning "ignoring attribute .always_inline. because it conflicts with attribute .noinline." } */ return r & 4; } @@ -21,13 +21,13 @@ __attribute__ ((always_inline)) __attribute__ ((noinline)) inline int fn3 (int r) -{ /* { dg-warning "attribute ignored due to conflict" } */ +{ /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */ return r & 8; } __attribute__ ((always_inline, noinline)) inline int fn4 (int r) -{ /* { dg-warning "attribute ignored due to conflict" } */ +{ /* { dg-warning "ignoring attribute .noinline. because it conflicts with attribute .always_inline." } */ return r & 8; } diff --git a/gcc/testsuite/gcc.dg/torture/pr42363.c b/gcc/testsuite/gcc.dg/torture/pr42363.c index ad0eac8ceed..e4c3861a46d 100644 --- a/gcc/testsuite/gcc.dg/torture/pr42363.c +++ b/gcc/testsuite/gcc.dg/torture/pr42363.c @@ -54,7 +54,11 @@ static int __attribute__ ((pure, const, noreturn)) barf (void) { /* { dg-warning "ignoring attribute .const." "const" { target *-*-* } .-1 } */ /* { dg-warning "ignoring attribute .noreturn." "noreturn" { target *-*-* } .-2 } */ -} /* { dg-warning "does return" } */ + + /* The noreturn attribute is ignored so verify there is no warning + for returning from the function: + { dg-bogus "does return" } */ +} static int __attribute__ ((pure, const)) bark (void) { /* { dg-warning "ignoring attribute .const." } */ -- 2.30.2