Skip to content

Commit 19dd768

Browse files
Merge pull request #58 from goblint/c11-noreturn
Support for C11 `_Noreturn`
2 parents c6be79a + c0868db commit 19dd768

File tree

9 files changed

+41
-10
lines changed

9 files changed

+41
-10
lines changed

src/frontc/cabs.ml

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ and spec_elem =
105105
| SpecAttr of attribute (* __attribute__ *)
106106
| SpecStorage of storage
107107
| SpecInline
108+
| SpecNoreturn
108109
| SpecType of typeSpecifier
109110
| SpecPattern of string (* specifier pattern variable *)
110111

src/frontc/cabs2cil.ml

+1
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of
23332333
match se with
23342334
A.SpecTypedef -> acc
23352335
| A.SpecInline -> isinline := true; acc
2336+
| A.SpecNoreturn -> attrs := ("noreturn", []) :: !attrs; acc
23362337
| A.SpecStorage st ->
23372338
if !storage <> NoStorage then
23382339
E.s (error "Multiple storage specifiers");

src/frontc/cabsvisit.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ and childrenTypeSpecifier vis ts =
217217

218218
and childrenSpecElem (vis: cabsVisitor) (se: spec_elem) : spec_elem =
219219
match se with
220-
SpecTypedef | SpecInline | SpecStorage _ | SpecPattern _ -> se
220+
SpecTypedef | SpecInline | SpecStorage _ | SpecPattern _ | SpecNoreturn -> se
221221
| SpecCV _ -> se (* cop out *)
222222
| SpecAttr a -> begin
223223
let al' = visitCabsAttribute vis a in

src/frontc/clexer.mll

+1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ let init_lexicon _ =
163163
("inline", fun loc -> INLINE loc);
164164
("__inline", fun loc -> INLINE loc);
165165
("_inline", fun loc -> IDENT ("_inline", loc));
166+
("_Noreturn", fun loc -> NORETURN loc);
166167
("__attribute__", fun loc -> ATTRIBUTE loc);
167168
("__attribute", fun loc -> ATTRIBUTE loc);
168169
(*

src/frontc/cparser.mly

+6-3
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ let transformOffsetOf (speclist, dtype) member =
252252
%token EOF
253253
%token<Cabs.cabsloc> CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32
254254
%token<Cabs.cabsloc> INT128 FLOAT128 COMPLEX /* C99 */
255-
%token<Cabs.cabsloc> GENERIC /* C11 */
255+
%token<Cabs.cabsloc> GENERIC NORETURN /* C11 */
256256
%token<Cabs.cabsloc> ENUM STRUCT TYPEDEF UNION
257257
%token<Cabs.cabsloc> SIGNED UNSIGNED LONG SHORT
258258
%token<Cabs.cabsloc> VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER
@@ -474,7 +474,7 @@ primary_expression: /*(* 6.5.1. *)*/
474474
;
475475

476476
/* (specifier, expression) list */
477-
generic_assoc_list:
477+
generic_assoc_list:
478478
| generic_association {[$1]}
479479
| generic_assoc_list COMMA generic_association {$3 :: $1}
480480

@@ -951,6 +951,7 @@ decl_spec_list: /* ISO 6.7 */
951951
| type_spec decl_spec_list_opt_no_named { SpecType (fst $1) :: $2, snd $1 }
952952
/* ISO 6.7.4 */
953953
| INLINE decl_spec_list_opt { SpecInline :: $2, $1 }
954+
| NORETURN decl_spec_list_opt { SpecNoreturn :: $2, $1 }
954955
| cvspec decl_spec_list_opt { (fst $1) :: $2, snd $1 }
955956
| attribute_nocv decl_spec_list_opt { SpecAttr (fst $1) :: $2, snd $1 }
956957
/* specifier pattern variable (must be last in spec list) */
@@ -1360,7 +1361,9 @@ pragma:
13601361
/* (* We want to allow certain strange things that occur in pragmas, so we
13611362
* cannot use directly the language of expressions *) */
13621363
primary_attr:
1363-
IDENT { VARIABLE (fst $1) }
1364+
IDENT { VARIABLE (fst $1) }
1365+
/* (* This is just so code such as __attribute(_NoReturn) is not rejected, which may arise when combining GCC noreturn attribute and including C11 stdnoreturn.h *) */
1366+
| NORETURN { VARIABLE ("__noreturn__") }
13641367
/*(* The NAMED_TYPE here creates conflicts with IDENT *)*/
13651368
| NAMED_TYPE { VARIABLE (fst $1) }
13661369
| LPAREN attr RPAREN { $2 }

src/frontc/cprint.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ let rec print_specifiers (specs: spec_elem list) =
135135
let print_spec_elem = function
136136
SpecTypedef -> print "typedef"
137137
| SpecInline -> printu "inline"
138+
| SpecNoreturn -> printu "_Noreturn"
138139
| SpecStorage sto ->
139140
printu (match sto with
140141
NO_STORAGE -> (comstring "/*no storage*/")
@@ -532,11 +533,11 @@ and print_expression_level (lvl: int) (exp : expression) =
532533
print ")"
533534
| GENERIC (exp, lst) ->
534535
let rec print_generic_list l =
535-
match l with
536+
match l with
536537
[] -> ()
537538
| (t, e) :: tl ->
538539
print ", ";
539-
print_onlytype t;
540+
print_onlytype t;
540541
print ": ";
541542
print_expression_level 0 e;
542543
print_generic_list tl

test/small1/c11-noreturn.c

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "testharness.h"
2+
#include <stdnoreturn.h>
3+
4+
_Noreturn int fun() {
5+
SUCCESS;
6+
}
7+
8+
noreturn int blub() {
9+
SUCCESS;
10+
}
11+
12+
int blabla() __attribute__((noreturn));
13+
14+
int blabla() {
15+
SUCCESS;
16+
}
17+
18+
int main() {
19+
fun();
20+
blub();
21+
blabla();
22+
23+
SUCCESS;
24+
}

test/small1/gcc-c11-generic-1.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// https://github.com/gcc-mirror/gcc/blob/16e2427f50c208dfe07d07f18009969502c25dc8/gcc/testsuite/gcc.dg/c11-generic-1.c
22
#include "testharness.h"
33

4-
// _Noreturn extern void abort (void);
4+
_Noreturn extern void abort (void);
55

66
int e = 0;
77

@@ -50,9 +50,8 @@ main (void)
5050
check (n);
5151

5252
/* _Noreturn is not part of the function type. */
53-
// TODO: add back when C11 _Noreturn supported
54-
/* check (_Generic (&abort, void (*) (void): 0, default: n++));
55-
check (n); */
53+
check (_Generic (&abort, void (*) (void): 0, default: n++));
54+
check (n);
5655

5756
/* Integer promotions do not occur. */
5857
short s;

test/testcil.pl

+1
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ sub addToGroup {
695695

696696
addTest("testrunc11/c11-generic");
697697
addTest("testrunc11/c11-caserange");
698+
addTest("testrunc11/c11-noreturn");
698699
addTest("testrunc11/gcc-c11-generic-1");
699700
# TODO: these messages are not even checked?
700701
addTestFail("testc11/gcc-c11-generic-2-1", "Multiple defaults in generic");

0 commit comments

Comments
 (0)