From d71488c017b4ebb932cf2b4a43656e1eda670b23 Mon Sep 17 00:00:00 2001 From: Jozef Lawrynowicz Date: Wed, 6 Jun 2018 11:49:20 +0000 Subject: [PATCH] MSP430: Allow interrupt handlers to be static * gcc/config/msp430/msp430.c (msp430_attr): Allow interrupt handlers to be static and remove check on interrupt attribute name. gcc/testsuite/gcc.target/msp430/ * function-attributes-4.c: New test. * static-interrupts.c: New test. From-SVN: r261229 --- gcc/ChangeLog | 9 ++ gcc/config/msp430/msp430.c | 17 ++- .../gcc.target/msp430/function-attributes-4.c | 111 ++++++++++++++++++ .../gcc.target/msp430/static-interrupts.c | 26 ++++ 4 files changed, 153 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/function-attributes-4.c create mode 100644 gcc/testsuite/gcc.target/msp430/static-interrupts.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e7be0083309..85515d98f98 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-06-06 Jozef Lawrynowicz + + * gcc/config/msp430/msp430.c (msp430_attr): Allow interrupt handlers + to be static and remove check on interrupt attribute name. + + gcc/testsuite/gcc.target/msp430/ + * function-attributes-4.c: New test. + * static-interrupts.c: New test. + 2018-06-05 Kelvin Nilsen * doc/extend.texi (PowerPC AltiVec Built-in Functions): Remove diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index 8c8e676b73e..90517615bba 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1878,11 +1878,9 @@ msp430_attr (tree * node, { gcc_assert (DECL_P (* node)); + /* Only the interrupt attribute takes an argument. */ if (args != NULL) { - /* Only the interrupt attribute takes an argument. */ - gcc_assert (TREE_NAME_EQ (name, ATTR_INTR)); - tree value = TREE_VALUE (args); switch (TREE_CODE (value)) @@ -1927,13 +1925,12 @@ msp430_attr (tree * node, if (TREE_CODE (TREE_TYPE (* node)) == FUNCTION_TYPE && ! VOID_TYPE_P (TREE_TYPE (TREE_TYPE (* node)))) message = "interrupt handlers must be void"; - - if (! TREE_PUBLIC (* node)) - message = "interrupt handlers cannot be static"; - - /* Ensure interrupt handlers never get optimised out. */ - TREE_USED (* node) = 1; - DECL_PRESERVE_P (* node) = 1; + else + { + /* Ensure interrupt handlers never get optimised out. */ + TREE_USED (* node) = 1; + DECL_PRESERVE_P (* node) = 1; + } } else if (TREE_NAME_EQ (name, ATTR_REENT)) { diff --git a/gcc/testsuite/gcc.target/msp430/function-attributes-4.c b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c new file mode 100644 index 00000000000..07d13c95ff1 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/function-attributes-4.c @@ -0,0 +1,111 @@ +/* { dg-do compile } */ +/* Check that the foo interrupt vectors aren't actually removed. */ +/* { dg-final { scan-assembler-times "__interrupt_vector_foo" 2 } } */ + +/* Check that warnings are emitted when attributes are used incorrectly and + that attributes are interpreted correctly whether leading and trailing + underscores are used or not. */ + +void __attribute__((__naked__,__reentrant__)) +fn1(void) +{ /* { dg-warning "naked functions cannot be reentrant" } */ +} + +void __attribute__((naked,reentrant)) +fn2(void) +{ /* { dg-warning "naked functions cannot be reentrant" } */ +} + +void __attribute__((__reentrant__,__naked__)) +fn3(void) +{ /* { dg-warning "reentrant functions cannot be naked" } */ +} + +void __attribute__((reentrant,naked)) +fn4(void) +{ /* { dg-warning "reentrant functions cannot be naked" } */ +} + +void __attribute__((__critical__,__reentrant__)) +fn5(void) +{ /* { dg-warning "critical functions cannot be reentrant" } */ +} + +void __attribute__((critical,reentrant)) +fn6(void) +{ /* { dg-warning "critical functions cannot be reentrant" } */ +} + +void __attribute__((__reentrant__,__critical__)) +fn7(void) +{ /* { dg-warning "reentrant functions cannot be critical" } */ +} + +void __attribute__((reentrant,critical)) +fn8(void) +{ /* { dg-warning "reentrant functions cannot be critical" } */ +} + +void __attribute__((__critical__,__naked__)) +fn9(void) +{ /* { dg-warning "critical functions cannot be naked" } */ +} + +void __attribute__((critical,naked)) +fn10(void) +{ /* { dg-warning "critical functions cannot be naked" } */ +} + +void __attribute__((__naked__,__critical__)) +fn11(void) +{ /* { dg-warning "naked functions cannot be critical" } */ +} + +void __attribute__((naked,critical)) +fn12(void) +{ /* { dg-warning "naked functions cannot be critical" } */ +} + +int __attribute__((interrupt)) +isr1 (void) +{ /* { dg-warning "interrupt handlers must be void" } */ +} + +int __attribute__((__interrupt__)) +isr2 (void) +{ /* { dg-warning "interrupt handlers must be void" } */ +} + +void __attribute__((interrupt("foo1"))) +isr3 (void) +{ /* { dg-warning "unrecognized interrupt vector argument" } */ +} + +void __attribute__((__interrupt__("foo2"))) +isr4 (void) +{ /* { dg-warning "unrecognized.*interrupt vector argument" } */ +} + +void __attribute__((interrupt(65))) +isr5 (void) +{ /* { dg-warning "numeric argument of 'interrupt' attribute must be in range 0..63" } */ +} + +void __attribute__((__interrupt__(100))) +isr6 (void) +{ /* { dg-warning "numeric argument of 'interrupt' attribute must be in range 0..63" } */ +} + +void __attribute__((interrupt(0.5))) +isr7 (void) +{ /* { dg-warning "argument of 'interrupt' attribute is not a string constant or number" } */ + volatile int __attribute__((__naked__)) + a; /* { dg-warning "'naked' attribute only applies to functions" } */ +} + +void __attribute__((__interrupt__(1.5))) +isr8 (void) +{ /* { dg-warning "argument of 'interrupt' attribute is not a string constant or number" } */ + volatile int __attribute__((naked)) + a; /* { dg-warning "'naked' attribute only applies to functions" } */ +} diff --git a/gcc/testsuite/gcc.target/msp430/static-interrupts.c b/gcc/testsuite/gcc.target/msp430/static-interrupts.c new file mode 100644 index 00000000000..06d9ea694af --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/static-interrupts.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ +/* { dg-final { scan-assembler-times "__interrupt_vector_" 4 } } */ + +/* Test that interrupts aren't optimised out and that "__interrupt__" and + "interrupt" can be used interchangeably. */ + +static void __attribute__((interrupt(1))) +isr_static (void) +{ +} + +static void __attribute__((__interrupt__(2))) +isr_static_alt (void) +{ +} + +void __attribute__((interrupt(3))) +isr_global (void) +{ +} + +void __attribute__((__interrupt__(4))) +isr_global_alt (void) +{ +} -- 2.30.2